better subprocess handling

This commit is contained in:
dave 2017-08-16 21:36:15 -07:00
parent efcef1f5df
commit 3fff05bc28
2 changed files with 38 additions and 16 deletions

View File

@ -4,6 +4,8 @@ import cherrypy
import subprocess import subprocess
from time import time from time import time
from random import shuffle from random import shuffle
from threading import Thread
from time import sleep
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from pysonic.library import LETTER_GROUPS from pysonic.library import LETTER_GROUPS
from pysonic.types import MUSIC_TYPES from pysonic.types import MUSIC_TYPES
@ -220,20 +222,40 @@ class PysonicApi(object):
break break
yield data yield data
else: else:
def content(): transcode_args = ["ffmpeg", "-i", fpath, "-map", "0:0", "-b:a",
transcode_args = ["ffmpeg", "-i", fpath, "-map", "0:0", "-b:a", "{}k".format(min(maxBitRate, self.options.max_bitrate)),
"{}k".format(min(maxBitRate, self.options.max_bitrate)), "-v", "0", "-f", "mp3", "-"]
"-v", "0", "-f", "mp3", "-"] logging.info(' '.join(transcode_args))
logging.info(' '.join(transcode_args)) proc = subprocess.Popen(transcode_args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def content(proc):
start = time() start = time()
proc = subprocess.Popen(transcode_args, stdout=subprocess.PIPE) try:
while True: while True:
data = proc.stdout.read(16 * 1024) data = proc.stdout.read(16 * 1024)
if not data: if not data:
break break
yield data yield data
logging.warning("transcoded {} in {}s".format(id, int(time() - start))) finally:
return content() proc.poll()
if proc.returncode is None:
logging.warning("transcoded {} in {}s".format(id, int(time() - start)))
else:
logging.error("transcode of {} exited with code {} after {}s".format(id, proc.returncode,
int(time() - start)))
def stopit(proc):
try:
proc.wait(timeout=90)
except subprocess.TimeoutExpired:
logging.warning("killing timed-out transcoder")
proc.kill()
proc.wait()
Thread(target=stopit, args=(proc, )).start()
return content(proc)
stream_view._cp_config = {'response.stream': True} stream_view._cp_config = {'response.stream': True}
@cherrypy.expose @cherrypy.expose
@ -356,5 +378,5 @@ class PysonicApi(object):
continue continue
item_meta = item['metadata'] item_meta = item['metadata']
itemtype = "song" if item["type"] in MUSIC_TYPES else "album" itemtype = "song" if item["type"] in MUSIC_TYPES else "album"
tag.append(self.render_node(doc, item, item_meta, {}, {}, tagname=itemtype)) tag.append(self.render_node(doc, item, item_meta, {}, self.db.getnode(item["parent"])["metadata"], tagname=itemtype))
yield doc.prettify() yield doc.prettify()

View File

@ -75,11 +75,11 @@ class PysonicDatabase(object):
version = 1 version = 1
if version < 2: if version < 2:
logging.warning("migrating database to v2 from %s", version) logging.warning("migrating database to v2 from %s", version)
users_table = """CREATE TABLE 'stars' ( stars_table = """CREATE TABLE 'stars' (
'userid' INTEGER, 'userid' INTEGER,
'nodeid' INTEGER, 'nodeid' INTEGER,
primary key ('userid', 'nodeid'))""" primary key ('userid', 'nodeid'))"""
cursor.execute(users_table) cursor.execute(stars_table)
version = 2 version = 2
cursor.execute("""UPDATE meta SET value=? WHERE key="db_version";""", (str(version), )) cursor.execute("""UPDATE meta SET value=? WHERE key="db_version";""", (str(version), ))