Change playback code to not buffer
This commit is contained in:
parent
76ad34be99
commit
ab60d7a1cf
2 changed files with 79 additions and 57 deletions
135
hugvey/client.py
135
hugvey/client.py
|
@ -14,6 +14,8 @@ from hugvey.communication import LOG_BS
|
|||
import os
|
||||
import collections
|
||||
import math
|
||||
import urllib.request
|
||||
import io
|
||||
|
||||
try:
|
||||
import alsaaudio
|
||||
|
@ -258,29 +260,34 @@ class CommandHandler(object):
|
|||
# self.showMyself() # queue message for connection request
|
||||
|
||||
def handle(self, cmd):
|
||||
print('handle', cmd)
|
||||
# self.sendMessage({'reply':'test'})
|
||||
if not 'action' in cmd:
|
||||
logger.critical("Invalid command: {}".format(cmd))
|
||||
return
|
||||
|
||||
logger.info("Received {}".format(cmd))
|
||||
|
||||
if cmd['action'] == 'show_yourself':
|
||||
self.showMyself()
|
||||
if cmd['action'] == 'prepare':
|
||||
self.muteMic = True
|
||||
if cmd['action'] == 'play':
|
||||
self.cmdPlay(cmd)
|
||||
if cmd['action'] == 'stop':
|
||||
self.cmdStop(cmd['id'])
|
||||
try:
|
||||
|
||||
print('handle', cmd)
|
||||
# self.sendMessage({'reply':'test'})
|
||||
if not 'action' in cmd:
|
||||
logger.critical("Invalid command: {}".format(cmd))
|
||||
return
|
||||
|
||||
logger.info("Received {}".format(cmd))
|
||||
|
||||
if cmd['action'] == 'show_yourself':
|
||||
self.showMyself()
|
||||
if cmd['action'] == 'prepare':
|
||||
self.muteMic = True
|
||||
if cmd['action'] == 'play':
|
||||
self.cmdPlay(cmd)
|
||||
if cmd['action'] == 'stop':
|
||||
self.cmdStop(cmd['id'])
|
||||
except Exception as e:
|
||||
logger.critical("Exception during handling command: {}".format(cmd))
|
||||
logger.exception(e)
|
||||
|
||||
def cmdPlay(self, cmd):
|
||||
self.muteMic = True
|
||||
|
||||
msgId = cmd['id']
|
||||
pitch = cmd['pitch'] if 'pitch' in cmd else 50
|
||||
file = cmd['file'] if 'file' in cmd else None
|
||||
filepath = 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)
|
||||
|
@ -292,49 +299,63 @@ class CommandHandler(object):
|
|||
self.playPopen.kill()
|
||||
|
||||
err = None
|
||||
if file is None and text is None:
|
||||
if filepath is None and text is None:
|
||||
logger.critical("No file nor text given: {}".format(cmd))
|
||||
else:
|
||||
if file is not None:
|
||||
logger.info("Play: {}".format(file))
|
||||
file = self.file_address + "/" + file
|
||||
# logger.debug(['play', file])
|
||||
playCmd = ['play', file]
|
||||
if filepath is not None:
|
||||
file = self.file_address + "/" + filepath
|
||||
logger.debug("Fetch to play: {}".format(filepath))
|
||||
start = time.time()
|
||||
#: var response: http.client.HTTPResponse
|
||||
response = urllib.request.urlopen(file, timeout=4)
|
||||
fetchend = time.time()
|
||||
logger.info("Fetched {} in {}s".format(file, fetchend-start))
|
||||
if fetchend-start > 1:
|
||||
logger.warning("Super slow fetching of {} in {}s".format(file, fetchend-start))
|
||||
if response.getcode() != 200:
|
||||
logger.critical("Error fetching: {} - {}".format(file, response))
|
||||
else:
|
||||
audioFile = io.BytesIO(response.read())
|
||||
logger.info("Play: {}".format(filepath))
|
||||
|
||||
for param, value in params.items():
|
||||
if not value:
|
||||
continue
|
||||
playCmd.append(param)
|
||||
print(param, value)
|
||||
if value is True:
|
||||
continue
|
||||
playCmd.append(str(value))
|
||||
environment_vars = dict(os.environ)
|
||||
if self.play_audiodriver is not None:
|
||||
environment_vars['AUDIODRIVER'] = self.play_audiodriver
|
||||
elif 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,duration+3))
|
||||
t.start()
|
||||
|
||||
self.playPopen = subprocess.Popen(
|
||||
playCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environment_vars)
|
||||
self.sendMessage({
|
||||
'event': 'playbackStart',
|
||||
'msgId': msgId
|
||||
})
|
||||
out, err = self.playPopen.communicate()
|
||||
returnCode = self.playPopen.returncode if self.playPopen else 0
|
||||
logger.debug('finished')
|
||||
self.playPopen = None
|
||||
|
||||
if t is not None:
|
||||
t.cancel()
|
||||
# logger.debug(['play', file])
|
||||
playCmd = ['play', '-']
|
||||
|
||||
for param, value in params.items():
|
||||
if not value:
|
||||
continue
|
||||
playCmd.append(param)
|
||||
print(param, value)
|
||||
if value is True:
|
||||
continue
|
||||
playCmd.append(str(value))
|
||||
environment_vars = dict(os.environ)
|
||||
if self.play_audiodriver is not None:
|
||||
environment_vars['AUDIODRIVER'] = self.play_audiodriver
|
||||
elif 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,duration+3))
|
||||
t.start()
|
||||
|
||||
self.playPopen = subprocess.Popen(
|
||||
playCmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environment_vars)
|
||||
self.sendMessage({
|
||||
'event': 'playbackStart',
|
||||
'msgId': msgId
|
||||
})
|
||||
out, err = self.playPopen.communicate(input=audioFile.getvalue())
|
||||
playend = time.time()
|
||||
returnCode = self.playPopen.returncode if self.playPopen else 0
|
||||
logger.info('finished playing {} in {:.4f}s (duration: {}s)'.format(filepath, playend-fetchend, duration))
|
||||
self.playPopen = None
|
||||
|
||||
if t is not None:
|
||||
t.cancel()
|
||||
|
||||
else:
|
||||
logger.info("Speak: {}".format(text))
|
||||
|
|
|
@ -48,6 +48,7 @@ if __name__ == '__main__':
|
|||
host = urlparse(hv.config['events']['cmd_address']).hostname
|
||||
logger.info("Connect to logger on {}".format(host))
|
||||
socket_handler = logging.handlers.SocketHandler(host, 19996) # default listening address
|
||||
# socket_handler.setLevel(logging.DEBUG) # always debug
|
||||
logger.addHandler(socket_handler);
|
||||
|
||||
hv.start()
|
||||
|
|
Loading…
Reference in a new issue