Fix some queuing issues for playback position timers.
This commit is contained in:
parent
ce137be780
commit
12d7f6fdd2
4 changed files with 54 additions and 20 deletions
|
@ -4,3 +4,4 @@ VERSION: float = 1.0
|
||||||
# API Settings
|
# API Settings
|
||||||
API_KEY: str = ""
|
API_KEY: str = ""
|
||||||
MYRADIO_BASE_URL: str = "https://ury.org.uk/myradio"
|
MYRADIO_BASE_URL: str = "https://ury.org.uk/myradio"
|
||||||
|
MYRADIO_API_URL: str = "https://ury.org.uk/api"
|
||||||
|
|
45
player.py
45
player.py
|
@ -52,6 +52,8 @@ class Player():
|
||||||
last_time_update = None
|
last_time_update = None
|
||||||
logger = None
|
logger = None
|
||||||
api = None
|
api = None
|
||||||
|
already_stopped = False
|
||||||
|
starting = False
|
||||||
|
|
||||||
__default_state = {
|
__default_state = {
|
||||||
"initialised": False,
|
"initialised": False,
|
||||||
|
@ -140,6 +142,9 @@ class Player():
|
||||||
# Audio Playout Related Methods
|
# Audio Playout Related Methods
|
||||||
|
|
||||||
def play(self, pos: float = 0):
|
def play(self, pos: float = 0):
|
||||||
|
global starting
|
||||||
|
global already_stopped
|
||||||
|
starting = True
|
||||||
try:
|
try:
|
||||||
mixer.music.play(0, pos)
|
mixer.music.play(0, pos)
|
||||||
mixer.music.set_endevent(PLAYBACK_END)
|
mixer.music.set_endevent(PLAYBACK_END)
|
||||||
|
@ -148,6 +153,8 @@ class Player():
|
||||||
self.logger.log.exception("Failed to play at pos: " + str(pos))
|
self.logger.log.exception("Failed to play at pos: " + str(pos))
|
||||||
return False
|
return False
|
||||||
self.state.update("paused", False)
|
self.state.update("paused", False)
|
||||||
|
|
||||||
|
already_stopped = False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
|
@ -183,6 +190,9 @@ class Player():
|
||||||
self.state.update("pos_true", 0)
|
self.state.update("pos_true", 0)
|
||||||
self.state.update("paused", False)
|
self.state.update("paused", False)
|
||||||
|
|
||||||
|
global already_stopped
|
||||||
|
already_stopped = True
|
||||||
|
|
||||||
return True
|
return True
|
||||||
# return False
|
# return False
|
||||||
|
|
||||||
|
@ -316,6 +326,10 @@ class Player():
|
||||||
except:
|
except:
|
||||||
self.logger.log.exception("Failed to update the length of item.")
|
self.logger.log.exception("Failed to update the length of item.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if self.state.state["play_on_load"]:
|
||||||
|
self.play()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def unload(self):
|
def unload(self):
|
||||||
|
@ -363,11 +377,29 @@ class Player():
|
||||||
loaded_item = self.state.state["loaded_item"]
|
loaded_item = self.state.state["loaded_item"]
|
||||||
# check the existing state (not self.isPlaying)
|
# check the existing state (not self.isPlaying)
|
||||||
# Since this is called multiple times when pygame isn't playing.
|
# Since this is called multiple times when pygame isn't playing.
|
||||||
if loaded_item == None or not self.isPlaying:
|
|
||||||
|
global starting
|
||||||
|
|
||||||
|
if starting:
|
||||||
|
print("Starting")
|
||||||
|
starting = False
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.out_q:
|
|
||||||
self.out_q.put("STOPPED") # Tell clients that we've stopped playing.
|
|
||||||
|
global already_stopped
|
||||||
|
|
||||||
|
print(already_stopped, self.state.state["remaining"], self.isPlaying)
|
||||||
|
|
||||||
|
if loaded_item == None or already_stopped or (self.state.state["remaining"] > 1):
|
||||||
|
return
|
||||||
|
|
||||||
|
mixer.music.set_endevent(NOEVENT)
|
||||||
|
|
||||||
|
already_stopped = True
|
||||||
|
|
||||||
|
|
||||||
|
stopping = True
|
||||||
|
|
||||||
# Track has ended
|
# Track has ended
|
||||||
print("Finished", loaded_item.name)
|
print("Finished", loaded_item.name)
|
||||||
|
@ -375,6 +407,7 @@ class Player():
|
||||||
# Repeat 1
|
# Repeat 1
|
||||||
if self.state.state["repeat"] == "ONE":
|
if self.state.state["repeat"] == "ONE":
|
||||||
self.play()
|
self.play()
|
||||||
|
stopping = False
|
||||||
|
|
||||||
# Auto Advance
|
# Auto Advance
|
||||||
elif self.state.state["auto_advance"]:
|
elif self.state.state["auto_advance"]:
|
||||||
|
@ -391,6 +424,12 @@ class Player():
|
||||||
# Play on Load
|
# Play on Load
|
||||||
if self.state.state["play_on_load"]:
|
if self.state.state["play_on_load"]:
|
||||||
self.play()
|
self.play()
|
||||||
|
stopping = False
|
||||||
|
|
||||||
|
if stopping:
|
||||||
|
self.stop()
|
||||||
|
if self.out_q:
|
||||||
|
self.out_q.put("STOPPED") # Tell clients that we've stopped playing.
|
||||||
|
|
||||||
def _updateState(self, pos: Optional[float] = None):
|
def _updateState(self, pos: Optional[float] = None):
|
||||||
|
|
||||||
|
|
20
server.py
20
server.py
|
@ -79,20 +79,12 @@ class PlayerHandler():
|
||||||
for channel in range(len(channel_from_q)):
|
for channel in range(len(channel_from_q)):
|
||||||
try:
|
try:
|
||||||
message = channel_from_q[channel].get_nowait()
|
message = channel_from_q[channel].get_nowait()
|
||||||
|
websocket_to_q[channel].put(message)
|
||||||
print("Player Handler saw:", message.split(":")[0])
|
print("Player Handler saw:", message.split(":")[0])
|
||||||
try:
|
ui_to_q[channel].put(message)
|
||||||
websocket_to_q[channel].put_nowait(message)
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
ui_to_q[channel].put_nowait(message)
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
pass
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
time.sleep(0.01)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__, static_url_path='')
|
app = Flask(__name__, static_url_path='')
|
||||||
|
@ -409,7 +401,7 @@ async def startServer():
|
||||||
channel_to_q.append(multiprocessing.Queue())
|
channel_to_q.append(multiprocessing.Queue())
|
||||||
channel_from_q.append(multiprocessing.Queue())
|
channel_from_q.append(multiprocessing.Queue())
|
||||||
ui_to_q.append(multiprocessing.Queue())
|
ui_to_q.append(multiprocessing.Queue())
|
||||||
websocket_to_q.append(multiprocessing.Queue())
|
websocket_to_q.append(multiprocessing.Manager().Queue())
|
||||||
channel_p.append(
|
channel_p.append(
|
||||||
multiprocessing.Process(
|
multiprocessing.Process(
|
||||||
target=player.Player,
|
target=player.Player,
|
||||||
|
@ -422,10 +414,10 @@ async def startServer():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
player_handler = multiprocessing.Process(target=PlayerHandler, args=[channel_from_q, websocket_to_q, ui_to_q])
|
player_handler = multiprocessing.Process(target=PlayerHandler, args=(channel_from_q, websocket_to_q, ui_to_q))
|
||||||
player_handler.start()
|
player_handler.start()
|
||||||
|
|
||||||
websockets_server = multiprocessing.Process(target=WebsocketServer, args=[channel_to_q, channel_from_q, state])
|
websockets_server = multiprocessing.Process(target=WebsocketServer, args=(channel_to_q, channel_from_q, state))
|
||||||
websockets_server.start()
|
websockets_server.start()
|
||||||
|
|
||||||
if not isMacOS():
|
if not isMacOS():
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import queue
|
import queue
|
||||||
from typing import List
|
from typing import Dict, List, Optional
|
||||||
import websockets
|
import websockets
|
||||||
import json
|
import json
|
||||||
|
|
||||||
baps_clients = set()
|
baps_clients = set()
|
||||||
channel_to_q = None
|
channel_to_q: List[multiprocessing.Queue]
|
||||||
webstudio_to_q: List[multiprocessing.Queue]
|
webstudio_to_q: List[multiprocessing.Queue]
|
||||||
server_name = None
|
server_name: str
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,6 +97,8 @@ async def websocket_handler(websocket, path):
|
||||||
await asyncio.wait([conn.send(data) for conn in baps_clients])
|
await asyncio.wait([conn.send(data) for conn in baps_clients])
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
pass
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
await asyncio.sleep(0.01)
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
from_webstudio = asyncio.create_task(handle_from_webstudio())
|
from_webstudio = asyncio.create_task(handle_from_webstudio())
|
||||||
|
|
Loading…
Reference in a new issue