Change playback code to not buffer

This commit is contained in:
Ruben van de Ven 2019-11-13 11:19:21 +01:00
parent 76ad34be99
commit ab60d7a1cf
2 changed files with 79 additions and 57 deletions

View file

@ -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,6 +260,8 @@ class CommandHandler(object):
# self.showMyself() # queue message for connection request
def handle(self, cmd):
try:
print('handle', cmd)
# self.sendMessage({'reply':'test'})
if not 'action' in cmd:
@ -274,13 +278,16 @@ class CommandHandler(object):
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,14 +299,27 @@ 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))
# logger.debug(['play', file])
playCmd = ['play', '-']
for param, value in params.items():
if not value:
@ -323,14 +343,15 @@ class CommandHandler(object):
t.start()
self.playPopen = subprocess.Popen(
playCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environment_vars)
playCmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environment_vars)
self.sendMessage({
'event': 'playbackStart',
'msgId': msgId
})
out, err = self.playPopen.communicate()
out, err = self.playPopen.communicate(input=audioFile.getvalue())
playend = time.time()
returnCode = self.playPopen.returncode if self.playPopen else 0
logger.debug('finished')
logger.info('finished playing {} in {:.4f}s (duration: {}s)'.format(filepath, playend-fetchend, duration))
self.playPopen = None
if t is not None:

View file

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