Fix some queuing issues for playback position timers.

This commit is contained in:
Matthew Stratford 2021-02-14 13:23:51 +00:00
parent ce137be780
commit 12d7f6fdd2
4 changed files with 54 additions and 20 deletions

View file

@ -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"

View file

@ -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):

View file

@ -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():

View file

@ -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())