added ts2mkv converter

Fri, 24 Nov 2017 02:12:25 +0100

author
mdd
date
Fri, 24 Nov 2017 02:12:25 +0100
changeset 7
0d021d47eca5
parent 6
1420abafd049
child 8
92409c985e0d

added ts2mkv converter

ts2mkv.py file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ts2mkv.py	Fri Nov 24 02:12:25 2017 +0100
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+
+import subprocess
+from eit import readeit
+import os, shlex
+
+def filter_lines(data, search):
+    ret = []
+    for line in data.split("\n"):
+        if line.find(search) == -1:
+            continue
+        ret.append(line)
+    return "\n".join(ret)
+
+def run_command(command):
+    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
+    while True:
+        output = process.stdout.readline()
+        if output == '' and process.poll() is not None:
+            break
+        if output:
+            print output.strip()
+    rc = process.poll()
+    return rc
+
+class ts2mkv(object):
+    def __init__(self):
+        self.msg_prepare = ""
+        self.msg_eit = ""
+        self.msg_ffmpeg = ""
+        self.command = None
+
+        self.video_options = [
+            "-c:v libx264",
+            "-preset slow",
+            "-crf 21"
+        ]
+        self.audio_options = [
+            "-c:a copy",
+        ]
+
+
+    def get_stream_index(self, data):
+        idx = data.find("Stream #")
+        if idx == -1:
+            return ""
+        idx += 8
+        self.msg_prepare += "Selecting: %s\n" % data
+        return data[idx:idx+3]
+
+    def get_movie_description(self, filename):
+        # 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")
+
+    def get_ffmpeg_command(self, filename):
+        commands = []
+        fn = "\\'".join(p for p in filename.split("'"))
+
+        p = subprocess.Popen(["ffmpeg", "-i", fn],
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        out, err = p.communicate()
+        self.msg_ffmpeg = out + "\n" + err
+        self.msg_ffmpeg = self.msg_ffmpeg[self.msg_ffmpeg.find("Input #0"):]
+        # 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?!
+        #s = filter_lines(info, "Subtitle:")
+        #s = filter_lines(s, "(deu):")
+        #if s != "":
+        #    s = self.get_stream_index(s.split("\n")[0])
+        #    commands.append([
+        #        "ffmpeg",
+        #        "-txt_format text",
+        #        "-i %s" % fn,
+        #        "-map %s" % s,
+        #        "%s.srt" % os.path.splitext(fn)[0]
+        #        ])
+
+        v = self.get_stream_index(
+            filter_lines(info, "Video:"))
+        if v == "":
+            print "No video stream found"
+            return None
+
+        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
+
+        audio = filter_lines(audioall, "(eng):")
+        a = self.get_stream_index(
+            filter_lines(audio, "ac3"))
+        if a != "":
+            # append english audio too!
+            audiomap.append(a)
+
+
+        self.msg_prepare += "Video Stream selected: Stream #%s\n" % v
+        cmd = [
+            "ffmpeg",
+            "-i %s" % fn,
+            "-map %s" % v,
+            ]
+        for a in audiomap:
+            self.msg_prepare += "Audio Stream selected: Stream #%s\n" % a
+            cmd.append("-map %s" % a)
+        cmd.extend(self.video_options)
+        cmd.extend(self.audio_options)
+        cmd.append(os.path.splitext(fn)[0] + ".mkv")
+
+        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"
+
+    mkv = ts2mkv()
+    mkv.load(filename)
+    if mkv.command:
+        fd = open(os.path.splitext(filename)[0] + ".txt", "wb")
+        fd.write(mkv.msg_eit)
+        fd.write("\n\n# ---DEBUG---\n\n")
+        fd.write(mkv.msg_prepare)
+        fd.write(mkv.msg_ffmpeg)
+        fd.close()
+        print mkv.msg_ffmpeg
+
+        for cmd in mkv.command:
+            print "Executing ffmpeg:\n%s\n" % " ".join(cmd)
+            run_command(cmd)

mercurial