make slightly less awful

This commit is contained in:
dave 2020-02-06 18:47:34 -08:00
parent 20e4a5e0b6
commit bbb67ab425
4 changed files with 119 additions and 116 deletions

7
app.py
View File

@ -15,8 +15,9 @@ from libs import database
from libs import recordTick from libs import recordTick
from datetime import datetime from datetime import datetime
if __name__ == '__main__' or 'uwsgi' in __name__: if __name__ == '__main__' or 'uwsgi' in __name__:
appdir = "/home/streamrecord/app" appdir = os.path.abspath(os.path.normpath(os.path.dirname(__file__)))
appconf = { appconf = {
'/': { '/': {
#'tools.proxy.on':True, #'tools.proxy.on':True,
@ -27,7 +28,7 @@ if __name__ == '__main__' or 'uwsgi' in __name__:
'tools.sessions.timeout':525600, 'tools.sessions.timeout':525600,
'request.show_tracebacks': True 'request.show_tracebacks': True
}, },
'/media': { '/static': {
'tools.staticdir.on': True, 'tools.staticdir.on': True,
'tools.staticdir.dir': appdir+"/static/" 'tools.staticdir.dir': appdir+"/static/"
} }
@ -44,7 +45,7 @@ if __name__ == '__main__' or 'uwsgi' in __name__:
cherrypy.server.socket_timeout = 5 cherrypy.server.socket_timeout = 5
# env - jinja2 template renderer # env - jinja2 template renderer
env = Environment(loader=FileSystemLoader("/home/streamrecord/app/templates")) env = Environment(loader=FileSystemLoader(os.path.join(appdir, "templates")))
# db - slightly custom sqlite3 object. rows = db.execute(query, args) # db - slightly custom sqlite3 object. rows = db.execute(query, args)
db = database() db = database()
# REC - recorder thread - see recordTick.py # REC - recorder thread - see recordTick.py

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sqlite3 import sqlite3
import os.path import os.path
from contextlib import closing
class database: class database:
def __init__(self): def __init__(self):
@ -35,13 +37,13 @@ class database:
def execute(self, sql, params=None): def execute(self, sql, params=None):
db = self.db db = self.db
cursor = db.cursor() with closing(db.cursor()) as cursor:
if params: if params:
cursor.execute(sql, params) cursor.execute(sql, params)
else: else:
cursor.execute(sql) cursor.execute(sql)
data = cursor.fetchall() data = cursor.fetchall()
if not cursor.lastrowid==None: if sql.lower().startswith("insert "):
return cursor.lastrowid return cursor.lastrowid
cursor.close() cursor.close()
return data return data

View File

@ -93,6 +93,7 @@ class recordThread(Thread):
print("%s starting downloader for %s" % (datetime.datetime.now(), self.url)) print("%s starting downloader for %s" % (datetime.datetime.now(), self.url))
# Download the stream to temp file(s) # Download the stream to temp file(s)
self.status = 2 self.status = 2
self.clearTempDir()
self.downloadStream() self.downloadStream()
# Combine files into 1 audio file # Combine files into 1 audio file
self.status = 3 self.status = 3
@ -106,32 +107,29 @@ class recordThread(Thread):
print("%s finished downloader for %s" % (datetime.datetime.now(), self.url)) print("%s finished downloader for %s" % (datetime.datetime.now(), self.url))
self.status = 0 self.status = 0
def clearTempDir(self):
# Delete temp files
files = os.listdir("files/temp/%s"%self.directory)
for f in files:
os.unlink("files/temp/%s/%s"%(self.directory,f))
def downloadStream(self): def downloadStream(self):
self.startdate = datetime.datetime.now() self.startdate = datetime.datetime.now()
recdate = str(int(time.time()))
# As long as we're supposed to keep retrying # As long as we're supposed to keep retrying
while self.running: while self.running:
# Create the temp dir for this stream # Create the temp dir for this stream
if not os.path.exists("files/temp/"+self.directory): os.makedirs("files/temp/"+self.directory, exist_ok=True)
os.mkdir("files/temp/"+self.directory)
# If there are already files, we're resuming. take the next available number # If there are already files, we're resuming. take the next available number
recNum = 0 recNum = 0
while os.path.exists("files/temp/%s/recdate%s.mp3" % (self.directory, ".%s"%recNum)): while os.path.exists("files/temp/%s/%s_%s.mp3" % (self.directory, recdate, recNum)):
recNum = recNum + 1 recNum = recNum + 1
# Filename is something like files/temp/stream-name/rec-y-m-d_h-m-s.0.mp3 # Filename is something like files/temp/stream-name/rec-y-m-d_h-m-s.0.mp3
fileName = "files/temp/%s/recdate%s.mp3" % (self.directory, "" if recNum == None else ".%s"%recNum) fileName = "files/temp/%s/%s_%s.mp3" % (self.directory, recdate, recNum)
# Args if we download with curl (bad)
args_curl = [
'/usr/bin/curl',
#'-s',
'-A',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36',
'--output', fileName, self.url]
# args if we download/transcode with avconv (HERO!)
args_libav = [ args_libav = [
'/usr/bin/avconv', os.environ.get("CONVERT_PROGRAM") or "/usr/bin/ffmpeg",
'-loglevel', '-loglevel',
'error', 'error',
'-i', '-i',
@ -140,12 +138,12 @@ class recordThread(Thread):
'128k', '128k',
fileName fileName
] ]
self.proc = subprocess.Popen(args_libav, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.proc = subprocess.Popen(args_libav, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = self.proc.communicate() output = self.proc.communicate()
print("LibAV output for %s:\n%s" % (self.url, output)) print("LibAV output for %s:\n%s" % (self.url, output))
self.proc = None self.proc = None
def mergeStream(self): def mergeStream(self):
# Get an ordered list of the piece files # Get an ordered list of the piece files
files = os.listdir("files/temp/%s"%self.directory) files = os.listdir("files/temp/%s"%self.directory)
@ -154,6 +152,7 @@ class recordThread(Thread):
command = ['/usr/bin/mkvmerge', '-o', "files/temp/%s/temp.mka"%self.directory, "files/temp/%s/%s"%(self.directory,files.pop(0))] command = ['/usr/bin/mkvmerge', '-o', "files/temp/%s/temp.mka"%self.directory, "files/temp/%s/%s"%(self.directory,files.pop(0))]
for fname in files: for fname in files:
command.append("+files/temp/%s/%s"%(self.directory,fname)) command.append("+files/temp/%s/%s"%(self.directory,fname))
self.mergeproc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.mergeproc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Wait for the merge to finish # Wait for the merge to finish
output = self.mergeproc.communicate() output = self.mergeproc.communicate()
@ -164,7 +163,13 @@ class recordThread(Thread):
os.unlink("files/temp/%s/out.mp3"%self.directory) os.unlink("files/temp/%s/out.mp3"%self.directory)
# Convert the matroska file to mp3 # Convert the matroska file to mp3
command = ['/usr/bin/avconv', '-i', "files/temp/%s/temp.mka"%self.directory, '-q:a', '0', '-ab', '128k', "files/temp/%s/out.mp3"%self.directory] command = [
os.environ.get("CONVERT_PROGRAM") or '/usr/bin/ffmpeg',
'-i', "files/temp/%s/temp.mka"%self.directory,
'-q:a', '0',
'-ab', '128k',
"files/temp/%s/out.mp3"%self.directory
]
self.transcodeproc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.transcodeproc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for the trancode to finish # wait for the trancode to finish
output = self.transcodeproc.communicate() output = self.transcodeproc.communicate()
@ -174,16 +179,12 @@ class recordThread(Thread):
newname = self.startdate.strftime("%Y-%m-%d_%H-%M-%S")+".mp3" newname = self.startdate.strftime("%Y-%m-%d_%H-%M-%S")+".mp3"
# make it's finished storage location # make it's finished storage location
if not os.path.exists("files/output/"+self.directory): os.makedirs("files/output/"+self.directory, exist_ok=True)
os.mkdir("files/output/"+self.directory)
# copy final recording to output dir # copy final recording to output dir
os.rename("files/temp/%s/out.mp3"%(self.directory), "files/output/%s/%s"%(self.directory,newname)) os.rename("files/temp/%s/out.mp3"%(self.directory), "files/output/%s/%s"%(self.directory,newname))
# Delete temp files self.clearTempDir()
files = os.listdir("files/temp/%s"%self.directory)
for f in files:
os.unlink("files/temp/%s/%s"%(self.directory,f))
def cancel(self): def cancel(self):
print("Closing %s" % self.url) print("Closing %s" % self.url)
@ -206,4 +207,3 @@ class recordThread(Thread):
if not self.proc == None: if not self.proc == None:
# Kill it # Kill it
self.proc.kill() self.proc.kill()

View File

@ -135,7 +135,7 @@ var validators = {
if(endHour<0 || endHour>=24 || isNaN(endHour)) { if(endHour<0 || endHour>=24 || isNaN(endHour)) {
messages.push("End hour must be 0-23") messages.push("End hour must be 0-23")
} }
if(endMin<0 || endMin>50 || isNaN(endMin)) { if(endMin<0 || endMin>59 || isNaN(endMin)) {
messages.push("End minute must be 0-59") messages.push("End minute must be 0-59")
} }