commit 812b5fc3b83b6653c67b567166cfcc6a5aca75ed Author: Klaus-Uwe Mitterer Date: Sat Aug 18 11:58:07 2018 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25f5b6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/__pycache__ +**/*.pyc +upload/ diff --git a/mp4conv.py b/mp4conv.py new file mode 100755 index 0000000..38a33f2 --- /dev/null +++ b/mp4conv.py @@ -0,0 +1,114 @@ +#!/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) + +globq = multiprocessing.Queue() + +class Worker(multiprocessing.Process): + def __init__(self, path, q): + 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.queue = logging.handlers.QueueHandler(q) + self.logger.addHandler(self.handler) + self.logger.addHandler(self.queue) + 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 my_init(self, q): + self.logq = q + + def process_IN_CLOSE_WRITE(self, event): + Worker(event.pathname, self.logq).start() + + def process_IN_MOVED_TO(self, event): + self.process_IN_CLOSE_WRITE(event) + + +def runner(q = globq): + watch = pyinotify.WatchManager() + event = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_MOVED_TO + + #handler = logging.StreamHandler() + #listener = logging.handlers.QueueListener(q, handler) + #listener.start() + + notifier = pyinotify.ThreadedNotifier(watch, Handler(q=q)) + watch.add_watch(indir, event, rec=True) + notifier.start() + +if __name__ == "__main__": + runner()