From 2708f22b80e7d52fb042bf27a5eb4ecd5d4da6a0 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Wed, 24 Apr 2019 11:31:20 +0200 Subject: [PATCH] Add a duration check to prevent hanging playback --- hugvey/client.py | 22 ++++++++++++++++++++++ hugvey/story.py | 15 ++++++++++++++- install_server.sh | 5 +++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/hugvey/client.py b/hugvey/client.py index 6d928e9..b5dc419 100644 --- a/hugvey/client.py +++ b/hugvey/client.py @@ -279,6 +279,8 @@ class CommandHandler(object): file = cmd['file'] if 'file' in cmd else None text = cmd['msg'] if 'msg' in cmd else None params = cmd['params'] if 'params' in cmd else {} + # use duration for timing the popen duration (and redo it if needed) + duration = cmd['duration'] if 'duration' in cmd else None self.playingMsgId = msgId if file is None and text is None: @@ -302,6 +304,12 @@ class CommandHandler(object): if self.play_audiodev is not None: environment_vars['AUDIODEV'] = self.play_audiodev logger.debug(playCmd) + + t = None + if duration is not None: + t = threading.Timer(duration+3, self.checkPopen, (msgId,)) + t.start() + self.playPopen = subprocess.Popen( playCmd, stdout=subprocess.PIPE, env=environment_vars) self.sendMessage({ @@ -312,6 +320,10 @@ class CommandHandler(object): returnCode = self.playPopen.returncode logger.debug('finished') self.playPopen = None + + if t is not None: + t.cancel() + else: logger.info("Speak: {}".format(text)) playCmd = ['espeak', '-p', '{0}'.format(pitch), text] @@ -332,6 +344,16 @@ class CommandHandler(object): 'event': 'playbackFinish', 'msgId': msgId }) + + def checkPopen(self, msgId): + if self.playingMsgId != msgId: + return + + if self.playPopen is None: + return + + # prevent a lock of the story, no repeat or anything for now + self.playPopen.terminate() def cmdStop(self, msgId): if self.playPopen and self.playingMsgId == msgId: diff --git a/hugvey/story.py b/hugvey/story.py index 34395fb..09d66f1 100644 --- a/hugvey/story.py +++ b/hugvey/story.py @@ -12,6 +12,7 @@ import threading import faulthandler from zmq.asyncio import Context import zmq +import wave mainLogger = logging.getLogger("hugvey") logger = mainLogger.getChild("narrative") @@ -503,6 +504,10 @@ class Diversion(object): """ Participant asks if message can be repeated. """ + + + # TODO: how to handle this now we sometimes use different timings. + # Perhaps set isFinished when matching condition. if story.currentReply is None or story.currentReply.isSpeaking(): return @@ -937,12 +942,20 @@ class Story(object): # TODO: prep events & timer etc. fn = await message.getAudioFilePath() + + # get duration of audio file, so the client can detect a hang of 'play' + with wave.open(fn,'r') as fp: + frames = fp.getnframes() + rate = fp.getframerate() + duration = frames/float(rate) + # self.hugvey.google.pause() # pause STT to avoid text events while decision is made self.hugvey.sendCommand({ 'action': 'play', 'file': fn, 'id': message.id, - 'params': message.getParams() + 'params': message.getParams(), + 'duration': duration }) # 2019-02-22 temporary disable listening while playing audio: diff --git a/install_server.sh b/install_server.sh index 65c4cb6..fb049dc 100755 --- a/install_server.sh +++ b/install_server.sh @@ -1,10 +1,11 @@ apt-get update -apt-get install -y munin-node +apt-get install -y munin-node bc cp installation/rpi-internal-temp /usr/share/munin/plugins ln -sf /usr/share/munin/plugins/rpi-internal-temp /etc/munin/plugins/rpi-internal-temp +rm /etc/munin/plugins/irqstats chmod a+x /usr/share/munin/plugins/rpi-internal-temp -echo "allow ^192\\.168\\.0\\.155\$" >> /etc/munin/munin-node.conf +echo "allow ^\\S*\$" >> /etc/munin/munin-node.conf service munin-node restart apt-get install -y supervisor