Further player hardening
This commit is contained in:
parent
eafb4dd461
commit
2bf4ff4715
1 changed files with 105 additions and 51 deletions
156
player.py
156
player.py
|
@ -14,8 +14,11 @@ os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
||||||
class Player():
|
class Player():
|
||||||
state = None
|
state = None
|
||||||
running = False
|
running = False
|
||||||
|
out_q = None
|
||||||
|
last_msg = None
|
||||||
|
|
||||||
__default_state = {
|
__default_state = {
|
||||||
|
"initialised": False,
|
||||||
"filename": "",
|
"filename": "",
|
||||||
"channel": -1,
|
"channel": -1,
|
||||||
"playing": False,
|
"playing": False,
|
||||||
|
@ -49,14 +52,30 @@ class Player():
|
||||||
if self.isPlaying:
|
if self.isPlaying:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Because Pygame/SDL is annoying
|
||||||
|
# We're not playing now, so we can quickly test run
|
||||||
|
# If that works, we're loaded.
|
||||||
try:
|
try:
|
||||||
current_pos = mixer.music.get_pos()
|
position = self.state.state["pos"]
|
||||||
mixer.music.set_pos(current_pos)
|
mixer.music.set_volume(0)
|
||||||
|
mixer.music.play(0)
|
||||||
except:
|
except:
|
||||||
# TODO: Trigger specially off the SDLError (couldn't find it)
|
try:
|
||||||
|
mixer.music.set_volume(1)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
return False
|
return False
|
||||||
|
if position > 0:
|
||||||
|
mixer.music.pause()
|
||||||
|
else:
|
||||||
|
mixer.music.stop()
|
||||||
|
mixer.music.set_volume(1)
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
@property
|
||||||
|
def status(self):
|
||||||
|
res = json.dumps(self.state.state)
|
||||||
|
return res
|
||||||
|
|
||||||
def play(self):
|
def play(self):
|
||||||
if not self.isPlaying:
|
if not self.isPlaying:
|
||||||
|
@ -144,33 +163,47 @@ class Player():
|
||||||
|
|
||||||
def output(self, name=None):
|
def output(self, name=None):
|
||||||
self.quit()
|
self.quit()
|
||||||
|
self.state.update("output", name)
|
||||||
|
self.state.update("filename", "")
|
||||||
try:
|
try:
|
||||||
if name:
|
if name:
|
||||||
mixer.init(44100, -16, 1, 1024, devicename=name)
|
mixer.init(44100, -16, 1, 1024, devicename=name)
|
||||||
else:
|
else:
|
||||||
mixer.init(44100, -16, 1, 1024)
|
mixer.init(44100, -16, 1, 1024)
|
||||||
except:
|
except:
|
||||||
return "FAIL:Failed to init mixer, check sound devices."
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _updateState(self, pos=None):
|
||||||
|
self.state.update("initialised", self.isInit)
|
||||||
|
if self.isInit:
|
||||||
|
self.state.update("playing", self.isPlaying)
|
||||||
|
self.state.update("loaded", self.isLoaded)
|
||||||
|
if (pos):
|
||||||
|
self.state.update("pos", max(0, pos))
|
||||||
|
else:
|
||||||
|
self.state.update("pos", max(0, mixer.music.get_pos()/1000))
|
||||||
|
self.state.update("remaining", self.state.state["length"] - self.state.state["pos"])
|
||||||
|
|
||||||
|
def _retMsg(self, msg, okay_str=False):
|
||||||
|
response = self.last_msg + ":"
|
||||||
|
if msg == True:
|
||||||
|
response += "OKAY"
|
||||||
|
elif isinstance(msg, str):
|
||||||
|
if okay_str:
|
||||||
|
response += "OKAY:" + msg
|
||||||
|
else:
|
||||||
|
response += "FAIL:" + msg
|
||||||
else:
|
else:
|
||||||
self.state.update("output", name)
|
response += "FAIL"
|
||||||
|
if self.out_q:
|
||||||
return "OK"
|
self.out_q.put(response)
|
||||||
|
|
||||||
def updateState(self, pos=None):
|
|
||||||
self.state.update("playing", self.isPlaying)
|
|
||||||
self.state.update("loaded", self.isLoaded)
|
|
||||||
if (pos):
|
|
||||||
self.state.update("pos", max(0, pos))
|
|
||||||
else:
|
|
||||||
self.state.update("pos", max(0, mixer.music.get_pos()/1000))
|
|
||||||
self.state.update("remaining", self.state.state["length"] - self.state.state["pos"])
|
|
||||||
|
|
||||||
def getDetails(self):
|
|
||||||
res = "RESP:DETAILS: " + json.dumps(self.state.state)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def __init__(self, channel, in_q, out_q):
|
def __init__(self, channel, in_q, out_q):
|
||||||
self.running = True
|
self.running = True
|
||||||
|
self.out_q = out_q
|
||||||
|
|
||||||
setproctitle.setproctitle("BAPSicle - Player " + str(channel))
|
setproctitle.setproctitle("BAPSicle - Player " + str(channel))
|
||||||
|
|
||||||
self.state = StateManager("channel" + str(channel), self.__default_state)
|
self.state = StateManager("channel" + str(channel), self.__default_state)
|
||||||
|
@ -201,47 +234,67 @@ class Player():
|
||||||
print("No file was previously loaded.")
|
print("No file was previously loaded.")
|
||||||
|
|
||||||
while self.running:
|
while self.running:
|
||||||
time.sleep(0.01)
|
time.sleep(0.1)
|
||||||
|
self._updateState()
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
incoming_msg = in_q.get_nowait()
|
self.last_msg = in_q.get_nowait()
|
||||||
except Empty:
|
except Empty:
|
||||||
# The incomming message queue was empty,
|
# The incomming message queue was empty,
|
||||||
# skip message processing
|
# skip message processing
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# We got a message.
|
# We got a message.
|
||||||
if self.isInit:
|
|
||||||
|
|
||||||
self.updateState()
|
# Output re-inits the mixer, so we can do this any time.
|
||||||
|
if (self.last_msg.startswith("OUTPUT")):
|
||||||
|
split = self.last_msg.split(":")
|
||||||
|
self._retMsg(self.output(split[1]))
|
||||||
|
|
||||||
if (incoming_msg == 'LOADED?'):
|
elif self.isInit:
|
||||||
out_q.put(self.isLoaded)
|
|
||||||
|
if (self.last_msg == 'LOADED?'):
|
||||||
|
self._retMsg(self.isLoaded)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (incoming_msg == 'PLAY'):
|
elif (self.last_msg == 'PLAY'):
|
||||||
self.play()
|
self._retMsg(self.play())
|
||||||
if (incoming_msg == 'PAUSE'):
|
|
||||||
self.pause()
|
|
||||||
if (incoming_msg == 'UNPAUSE'):
|
|
||||||
self.unpause()
|
|
||||||
if (incoming_msg == 'STOP'):
|
|
||||||
self.stop()
|
|
||||||
if (incoming_msg == 'QUIT'):
|
|
||||||
self.quit()
|
|
||||||
self.running = False
|
|
||||||
if (incoming_msg.startswith("SEEK")):
|
|
||||||
split = incoming_msg.split(":")
|
|
||||||
self.seek(float(split[1]))
|
|
||||||
if (incoming_msg.startswith("LOAD")):
|
|
||||||
split = incoming_msg.split(":")
|
|
||||||
self.load(split[1])
|
|
||||||
if (incoming_msg == 'DETAILS'):
|
|
||||||
out_q.put(self.getDetails())
|
|
||||||
|
|
||||||
if (incoming_msg.startswith("OUTPUT")):
|
elif (self.last_msg == 'PAUSE'):
|
||||||
split = incoming_msg.split(":")
|
self._retMsg(self.pause())
|
||||||
out_q.put(self.output(split[1]))
|
|
||||||
|
elif (self.last_msg == 'UNPAUSE'):
|
||||||
|
self._retMsg(self.unpause())
|
||||||
|
|
||||||
|
elif (self.last_msg == 'STOP'):
|
||||||
|
self._retMsg(self.stop())
|
||||||
|
|
||||||
|
elif (self.last_msg == 'QUIT'):
|
||||||
|
self.running = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif (self.last_msg.startswith("SEEK")):
|
||||||
|
split = self.last_msg.split(":")
|
||||||
|
self._retMsg(self.seek(float(split[1])))
|
||||||
|
|
||||||
|
elif (self.last_msg.startswith("LOAD")):
|
||||||
|
split = self.last_msg.split(":")
|
||||||
|
self._retMsg(self.load(split[1]))
|
||||||
|
|
||||||
|
elif (self.last_msg == 'UNLOAD'):
|
||||||
|
self._retMsg(self.unload())
|
||||||
|
|
||||||
|
elif (self.last_msg == 'STATUS'):
|
||||||
|
self._retMsg(self.status, True)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self._retMsg("Unknown Command")
|
||||||
|
else:
|
||||||
|
if (self.last_msg == 'STATUS'):
|
||||||
|
self._retMsg(self.status)
|
||||||
|
else:
|
||||||
|
self._retMsg(False)
|
||||||
|
|
||||||
# Catch the player being killed externally.
|
# Catch the player being killed externally.
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -253,14 +306,15 @@ class Player():
|
||||||
|
|
||||||
print("Quiting player ", channel)
|
print("Quiting player ", channel)
|
||||||
self.quit()
|
self.quit()
|
||||||
|
self._retMsg("EXIT")
|
||||||
|
|
||||||
|
|
||||||
def showOutput(in_q, out_q):
|
def showOutput(in_q, out_q):
|
||||||
print("Starting showOutput().")
|
print("Starting showOutput().")
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
incoming_msg = out_q.get()
|
self.last_msg = out_q.get()
|
||||||
print(incoming_msg)
|
print(self.last_msg)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue