From 28e28414afc6751e85c150cd930121141e40bf7c Mon Sep 17 00:00:00 2001 From: William McBrine Date: Thu, 9 May 2013 02:10:58 -0400 Subject: [PATCH] Chunked transfers for the music plugin. I _think_ everything is legit HTTP 1.1 now... This should also do away with the stray ffmpeg processes left when skipping forward, although I'm still getting an extra traceback each time. --- plugins/music/music.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/plugins/music/music.py b/plugins/music/music.py index b8aa668..9726e1f 100644 --- a/plugins/music/music.py +++ b/plugins/music/music.py @@ -36,6 +36,8 @@ TAGNAMES = {'artist': ['\xa9ART', 'Author'], 'date': ['\xa9day', u'WM/Year'], 'genre': ['\xa9gen', u'WM/Genre']} +BLOCKSIZE = 64 * 1024 + # Search strings for different playlist types asxfile = re.compile('ref +href *= *"([^"]*)"', re.IGNORECASE).search wplfile = re.compile('media +src *= *"([^"]*)"', re.IGNORECASE).search @@ -100,12 +102,14 @@ class Music(Plugin): ext = os.path.splitext(fname)[1].lower() needs_transcode = ext in TRANSCODE or seek or duration or always - handler.send_response(200) - handler.send_header('Content-Type', 'audio/mpeg') if not needs_transcode: fsize = os.path.getsize(fname) + handler.send_response(200) handler.send_header('Content-Length', fsize) - handler.send_header('Connection', 'close') + else: + handler.send_response(206) + handler.send_header('Transfer-Encoding', 'chunked') + handler.send_header('Content-Type', 'audio/mpeg') handler.end_headers() if needs_transcode: @@ -123,12 +127,23 @@ class Music(Plugin): if duration: cmd[-1:] = ['-t', '%.3f' % (duration / 1000.0), '-'] - ffmpeg = subprocess.Popen(cmd, bufsize=(64 * 1024), + ffmpeg = subprocess.Popen(cmd, bufsize=BLOCKSIZE, stdout=subprocess.PIPE) - try: - shutil.copyfileobj(ffmpeg.stdout, handler.wfile) - except: - kill(ffmpeg) + while True: + try: + block = ffmpeg.stdout.read(BLOCKSIZE) + handler.wfile.write('%x\r\n' % len(block)) + handler.wfile.write(block) + handler.wfile.write('\r\n') + if not block: + handler.wfile.flush() + except Exception, msg: + handler.server.logger.info(msg) + kill(ffmpeg) + break + + if not block: + break else: f = open(fname, 'rb') try: -- 2.11.4.GIT