103 lines
3 KiB
Python
Executable file
103 lines
3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import subprocess
|
|
import pyinotify
|
|
import logging
|
|
import io
|
|
import time
|
|
import os
|
|
import shutil
|
|
import multiprocessing
|
|
import logging.handlers
|
|
|
|
indir = "upload/convert/"
|
|
outdir = "upload/"
|
|
faildir = "upload/fail/"
|
|
|
|
logf = "[%(name)s] %(levelname)s: %(message)s"
|
|
logging.basicConfig(format=logf)
|
|
|
|
class Worker(multiprocessing.Process):
|
|
def __init__(self, path):
|
|
super(Worker, self).__init__()
|
|
|
|
self.path = path
|
|
self.basename = path.rpartition("/")[-1].rpartition(".")[0]
|
|
self.ext = path.rpartition(".")[-1]
|
|
self.time = int(time.time())
|
|
|
|
self.string = io.StringIO()
|
|
self.logger = logging.getLogger("mp4conv")
|
|
self.handler = logging.StreamHandler(self.string)
|
|
self.logger.addHandler(self.handler)
|
|
self.logger.setLevel(logging.DEBUG)
|
|
|
|
def subprocess_logger(self, output):
|
|
for line in io.TextIOWrapper(output, encoding="utf-8"):
|
|
self.logger.debug("(ffmpeg - %s) %r" % (self.basename, line))
|
|
|
|
def build_command(self):
|
|
return ["ffmpeg", "-i", self.path, "-vcodec", "h264", "-acodec", "aac",
|
|
"-strict", "-2", "%s/%s_%i.tmp.mp4" % (outdir, self.basename,
|
|
self.time), "-nostats", "-hide_banner"]
|
|
|
|
def process(self):
|
|
self.logger.info("Discovered file %s." % self.path)
|
|
|
|
time.sleep(5)
|
|
if not os.path.exists(self.path):
|
|
self.logger.info("File %s disappeared." % self.path)
|
|
return self.string
|
|
|
|
self.logger.info("Starting to process %s." % self.path)
|
|
|
|
try:
|
|
sub = subprocess.Popen(self.build_command(), stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT)
|
|
|
|
with sub.stdout as output:
|
|
self.subprocess_logger(output)
|
|
|
|
assert not sub.wait()
|
|
|
|
os.rename("%s/%s_%i.tmp.mp4" % (outdir, self.basename, self.time),
|
|
"%s/%s_%i.mp4" % (outdir, self.basename, self.time))
|
|
|
|
if os.path.exists(self.path):
|
|
os.unlink(self.path)
|
|
|
|
except Exception as e:
|
|
self.logger.exception("Something went wrong. See the log file.")
|
|
|
|
with open("%s/%s_%i.log" % (faildir, self.basename,
|
|
self.time), "w+") as logfile:
|
|
self.string.seek(0)
|
|
shutil.copyfileobj(self.string, logfile)
|
|
|
|
os.rename(self.path, "%s/%s_%i.%s" % (faildir, self.basename,
|
|
self.time, self.ext))
|
|
|
|
finally:
|
|
return self.string
|
|
|
|
def run(self):
|
|
self.process()
|
|
|
|
class Handler(pyinotify.ProcessEvent):
|
|
def process_IN_CLOSE_WRITE(self, event):
|
|
Worker(event.pathname).start()
|
|
|
|
def process_IN_MOVED_TO(self, event):
|
|
self.process_IN_CLOSE_WRITE(event)
|
|
|
|
|
|
def runner():
|
|
watch = pyinotify.WatchManager()
|
|
event = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_MOVED_TO
|
|
|
|
notifier = pyinotify.ThreadedNotifier(watch, Handler())
|
|
watch.add_watch(indir, event, rec=True)
|
|
notifier.start()
|
|
|
|
if __name__ == "__main__":
|
|
runner()
|