added option parser and automatic file rename feature

Fri, 24 Nov 2017 23:11:58 +0100

author
mdd
date
Fri, 24 Nov 2017 23:11:58 +0100
changeset 9
1bf778001041
parent 8
92409c985e0d
child 10
f436a7f94c6a

added option parser and automatic file rename feature

eit.py file | annotate | diff | comparison | revisions
ts2mkv.py file | annotate | diff | comparison | revisions
--- a/eit.py	Fri Nov 24 16:16:50 2017 +0100
+++ b/eit.py	Fri Nov 24 23:11:58 2017 +0100
@@ -360,6 +360,8 @@
     Read Eit File and show the information.
     """
     eitlist = eitinfo(eitfile)
+    if len(eitlist.eit) == 0:
+        return None
     out = "Movie name: %s" % eitlist.get_name()
     out += "\nGenre: %s" % eitlist.get_genre()
     out += "\nComponents: %s" % eitlist.get_components()
--- a/ts2mkv.py	Fri Nov 24 16:16:50 2017 +0100
+++ b/ts2mkv.py	Fri Nov 24 23:11:58 2017 +0100
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 import subprocess
-from eit import readeit
+from eit import readeit, eitinfo
 import os, shlex
 
 def filter_lines(data, search):
@@ -24,19 +24,20 @@
     return rc
 
 class ts2mkv(object):
-    def __init__(self):
+    def __init__(self, crf=19, tune='film', scaleto_720p=True, rename=False):
         self.msg_prepare = ""
         self.msg_eit = ""
         self.msg_ffmpeg = ""
         self.command = None
 
-        self.scaleto_720p = True
+        self.scaleto_720p = scaleto_720p
+        self.rename = rename
 
         self.video_options = [
             "-c:v libx264",
             "-preset faster", # slow
-            "-tune film", # film / animation
-            "-crf 19" # 21, better 19
+            "-tune %s" % tune, # film / animation
+            "-crf %i" % crf # 21, better 19
         ]
         self.audio_options = [
             "-c:a copy",
@@ -50,12 +51,40 @@
         self.msg_prepare += "Selecting: %s\n" % data
         return data[idx:idx+3]
 
-    def get_movie_description(self, filename):
+    def get_movie_description(self):
+        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
-        self.msg_eit = readeit(os.path.splitext(filename)[0] + ".eit")
+        filename = os.path.splitext(self.filename)[0] + ".eit"
+        self.msg_eit = readeit(filename)
+        if not self.rename or not self.msg_eit:
+            return
+        info = eitinfo(filename)
+        name = info.eit.get("name")
+        if name == "":
+            # cancel rename, no movie title found!
+            return
+        genre = info.eit.get("genre")
+        if genre != "":
+            name = "%s (%s)" % (name, genre)
+        # build new filename
+        name = name.replace(' : ', ' - ')
+        name = name.replace(': ', ' - ')
+        name = name.replace(':', '-')
+        name = name.replace('/', '')
+        name = name.replace('\\', '')
+        name = name.replace('?', '')
+        name = name.replace('*', '')
+        name = name.replace('\"', '\'')
+
+        self.outfilebase = os.path.join(
+            os.path.dirname(filename),
+            name
+            )
+
 
     def get_crop_option(self):
         lines = filter_lines(self.msg_ffmpeg, "[Parsed_cropdetect").split("\n")
@@ -72,9 +101,16 @@
         self.msg_prepare += "Crop detected: %s\n" % option
         return option
 
-    def get_ffmpeg_command(self, filename):
+    def get_ffmpeg_command(self):
+        if not self.filename:
+            return None
+
         commands = []
-        fn = "\\'".join(p for p in filename.split("'"))
+        fn = "\\'".join(p for p in self.filename.split("'"))
+        fn = fn.replace(" ", "\\ ")
+        outfn = self.outfilebase + ".mkv"
+        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 -
 
@@ -94,7 +130,6 @@
         # find "Stream #0:" lines
         info = filter_lines(self.msg_ffmpeg, "Stream #0:")
 
-        fn = fn.replace(" ", "\\ ")
 
         # CRAP! ffmpeg cannot decode dvb_teletext streams to srt :(
         # are there any subtitle streams?!
@@ -116,23 +151,36 @@
             print "No video stream found"
             return None
 
+        audiomap = []
         audioall = filter_lines(info, "Audio:")
         audio = filter_lines(audioall, "(deu):")
         a = self.get_stream_index(
             filter_lines(audio, "ac3"))
         # TODO: wenn kein ac3 stream dann dts oder mpeg fallback
-        audiomap = [a]
         if a == "":
-            print "No suitable german audio stream found"
-            return None
+            print audioall
+            print "No AC3 german audio stream found"
+            # try to find the first german audio stream
+            a = self.get_stream_index(audio.split("\n")[0])
+            if a == "":
+                print "No other german audio streams, trying english ac3..."
+            else:
+                print "Selecting first german stream."
+                audiomap.append(a)
+        else:
+            audiomap.append(a)
 
         audio = filter_lines(audioall, "(eng):")
         a = self.get_stream_index(
             filter_lines(audio, "ac3"))
         if a != "":
             # append english audio too!
+            print "Selecting english ac3 stream."
             audiomap.append(a)
 
+        if len(audiomap) == 0:
+            print "No suitable audio stream found, aborting."
+            return None
 
 
         self.msg_prepare += "Video Stream selected: Stream #%s\n" % v
@@ -156,35 +204,65 @@
             cmd.append("-map %s" % a)
         cmd.extend(self.video_options)
         cmd.extend(self.audio_options)
-        cmd.append(os.path.splitext(fn)[0] + ".mkv")
+        cmd.append(outfn)
 
         commands.append(" ".join(cmd))
         return commands
 
     def load(self, filename):
         self.filename = filename
-        self.get_movie_description(filename)
-        self.command = self.get_ffmpeg_command(filename)
-
-if __name__ == "__main__":
-    import sys
-    os.system('cls' if os.name == 'nt' else 'clear')
-
-    # TODO: get file from commandline
-    #filename = "testfiles/chappie.ts"
-    filename = "/srv/storage0/DREAMBOX/Science Fiction/THE_ISLAND.ts"
+        self.outfilebase = os.path.splitext(filename)[0]
+        self.get_movie_description()
+        self.command = self.get_ffmpeg_command()
 
-    mkv = ts2mkv()
-    mkv.load(filename)
-    if mkv.command:
-        fd = open(os.path.splitext(filename)[0] + ".txt", "wb")
-        fd.write(mkv.msg_eit)
+    def convert(self):
+        if not self.command:
+            return None
+        fd = open(self.outfilebase + ".txt", "wb")
+        fd.write(self.msg_eit)
         fd.write("\n\n# ---DEBUG---\n\n")
-        fd.write(mkv.msg_prepare)
-        fd.write(mkv.msg_ffmpeg)
+        fd.write(self.msg_prepare)
+        fd.write(self.msg_ffmpeg)
         fd.close()
-        print mkv.msg_ffmpeg
+        #print self.msg_ffmpeg
 
         for cmd in mkv.command:
             print "Executing ffmpeg:\n%s\n" % cmd
-            run_command(cmd)
+            return run_command(cmd)
+
+
+
+if __name__ == "__main__":
+    # parse command line options
+    import argparse, sys, glob
+
+    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',
+        help='ffmpeg tune preset [film, animation] (default is film)')
+    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,
+        help='rename file basename to name and genre from EIT file if present')
+    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')
+
+    for srcstr in args.input:
+        src = glob.glob(srcstr)
+        for filename in src:
+            print filename
+            mkv.load(filename)
+            mkv.convert()
+
+

mercurial