pylint

Fri, 24 Nov 2017 23:42:30 +0100

author
mdd
date
Fri, 24 Nov 2017 23:42:30 +0100
changeset 10
f436a7f94c6a
parent 9
1bf778001041
child 11
821c02fa7070

pylint

ts2mkv.py file | annotate | diff | comparison | revisions
--- a/ts2mkv.py	Fri Nov 24 23:11:58 2017 +0100
+++ b/ts2mkv.py	Fri Nov 24 23:42:30 2017 +0100
@@ -1,10 +1,22 @@
 #!/usr/bin/env python
+"""
+DVB-TS to MKV kung-fu
+2017 by mdd
+
+Toolkit / executable to automagically convert DVB recordings to h264 mkv.
+Automatic audio stream selection (deu/eng)
+Automatic crop detection to remove cinematic bars
+"""
 
 import subprocess
 from eit import readeit, eitinfo
 import os, shlex
 
 def filter_lines(data, search):
+    """
+    input: data = \n separated string
+    output: tuple containing all lines where search is found
+    """
     ret = []
     for line in data.split("\n"):
         if line.find(search) == -1:
@@ -13,7 +25,11 @@
     return "\n".join(ret)
 
 def run_command(command):
-    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
+    """
+    run command as blocking subprocess, returns exit code
+    """
+    process = subprocess.Popen(shlex.split(command), \
+        stdout=subprocess.PIPE)
     while True:
         output = process.stdout.readline()
         if output == '' and process.poll() is not None:
@@ -24,6 +40,9 @@
     return rc
 
 class ts2mkv(object):
+    """
+    Main worker class, contains all the magic & ffmpeg voodoo
+    """
     def __init__(self, crf=19, tune='film', scaleto_720p=True, rename=False):
         self.msg_prepare = ""
         self.msg_eit = ""
@@ -37,13 +56,20 @@
             "-c:v libx264",
             "-preset faster", # slow
             "-tune %s" % tune, # film / animation
-            "-crf %i" % crf # 21, better 19
-        ]
+            "-crf %i" % crf, # 21, better 19
+            ]
         self.audio_options = [
             "-c:a copy",
-        ]
+            ]
+
+        self.filename = None
+        self.outfilebase = None
 
     def get_stream_index(self, data):
+        """
+        input: ffmpeg stream info string
+        output: ffmpeg stream mapping part
+        """
         idx = data.find("Stream #")
         if idx == -1:
             return ""
@@ -52,12 +78,16 @@
         return data[idx:idx+3]
 
     def get_movie_description(self):
+        """
+        looks for eit file with same basename of current filename
+        parse the eit file for txt infofile and optional build new
+        output filename base with movie name and genre
+
+        output: nothing, manipulates internal variables
+        """
         if not self.filename:
             return
         # read the EIT file
-        # TODO: fallback to meta file if no EIT
-        # TODO: is there a way to get the imdb for the movie automagically?
-        # http://www.omdbapi.com/apikey.aspx
         filename = os.path.splitext(self.filename)[0] + ".eit"
         self.msg_eit = readeit(filename)
         if not self.rename or not self.msg_eit:
@@ -87,6 +117,10 @@
 
 
     def get_crop_option(self):
+        """
+        parse the ffmpeg analyze output cropdetect lines
+        returns None or valid crop string for ffmpeg video filter
+        """
         lines = filter_lines(self.msg_ffmpeg, "[Parsed_cropdetect").split("\n")
         option = None
         for line in lines:
@@ -102,6 +136,10 @@
         return option
 
     def get_ffmpeg_command(self):
+        """
+        Too complex to describe, this does all the magic
+        output: produces internal ffmpeg command list (empty command list on error)
+        """
         if not self.filename:
             return None
 
@@ -112,8 +150,6 @@
         outfn = "\\'".join(p for p in outfn.split("'"))
         outfn = outfn.replace(" ", "\\ ")
 
-        #  ffmpeg -ss 00:05:00 -t 2 -i testfiles/chappie.ts -vf "cropdetect=24:16:0" -f null -
-
         cmd = ["ffmpeg",
                 "-ss 00:05:00", "-t 1", # search to 5 minutes, analyze 1 second
                 "-i %s" % fn,
@@ -121,7 +157,8 @@
                 "-f null", "-" # no output file
                 ]
         print " ".join(cmd)
-        p = subprocess.Popen(shlex.split(" ".join(cmd)), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        p = subprocess.Popen(shlex.split(" ".join(cmd)), \
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         out, err = p.communicate()
         print "Command return code: ", p.poll()
         self.msg_ffmpeg = out + "\n" + err
@@ -194,7 +231,8 @@
         if crop:
             flt.append(crop)
         if self.scaleto_720p:
-            flt.append("scale='min(1280,iw)':-2'") # -2 ensures division by two for codec
+            # -2 ensures division by two for codec
+            flt.append("scale='min(1280,iw)':-2'")
             self.msg_prepare += "Scaling cropped output stream to 720p\n"
         if len(flt) > 0:
             # append video filters
@@ -210,12 +248,20 @@
         return commands
 
     def load(self, filename):
+        """
+        First step: setup, analyze & prepare for conversion
+        """
         self.filename = filename
         self.outfilebase = os.path.splitext(filename)[0]
         self.get_movie_description()
         self.command = self.get_ffmpeg_command()
 
     def convert(self):
+        """
+        Second step: write info text file and start ffmpeg conversion
+        requires successful load as first step
+        returns ffmpeg conversion exit status
+        """
         if not self.command:
             return None
         fd = open(self.outfilebase + ".txt", "wb")
@@ -226,7 +272,7 @@
         fd.close()
         #print self.msg_ffmpeg
 
-        for cmd in mkv.command:
+        for cmd in self.command:
             print "Executing ffmpeg:\n%s\n" % cmd
             return run_command(cmd)
 
@@ -234,35 +280,29 @@
 
 if __name__ == "__main__":
     # parse command line options
-    import argparse, sys, glob
+    import argparse, glob
 
-    parser = argparse.ArgumentParser(description = 'DVB-TS to MKV kung-fu')
-    parser.add_argument('--crf', type=int, default=19,
+    parser = argparse.ArgumentParser(description='DVB-TS to MKV kung-fu')
+    parser.add_argument('--crf', type=int, default=19, \
         help='h264 crf (default 19)')
-    parser.add_argument('--tune', default='film',
+    parser.add_argument('--tune', default='film', \
         help='ffmpeg tune preset [film, animation] (default is film)')
-    parser.add_argument('--ns', action='store_true', default=False,
+    parser.add_argument('--ns', action='store_true', default=False, \
         help='no rescaling (default is scale to 720p)')
-    parser.add_argument('--rename', action='store_true', default=False,
+    parser.add_argument('--rename', action='store_true', default=False, \
         help='rename file basename to name and genre from EIT file if present')
-    parser.add_argument('input', metavar='input', nargs='+',
+    parser.add_argument('input', metavar='input', nargs='+', \
         help='one or more files, glob style syntax')
 
     args = parser.parse_args()
-    mkv = ts2mkv(
-        crf = args.crf,
-        tune = args.tune,
-        scaleto_720p = (not args.ns),
-        rename = args.rename
-        )
-
-    #os.system('cls' if os.name == 'nt' else 'clear')
+    processor = ts2mkv(crf=args.crf, tune=args.tune, scaleto_720p=(not args.ns), \
+        rename=args.rename)
 
     for srcstr in args.input:
         src = glob.glob(srcstr)
-        for filename in src:
-            print filename
-            mkv.load(filename)
-            mkv.convert()
+        for srcfile in src:
+            print "Processing: %s" % srcfile
+            processor.load(srcfile)
+            processor.convert()
 
 

mercurial