make slightly less awful
This commit is contained in:
parent
20e4a5e0b6
commit
bbb67ab425
7
app.py
7
app.py
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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()
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue