ts2mkv.py

changeset 7
0d021d47eca5
child 8
92409c985e0d
equal deleted inserted replaced
6:1420abafd049 7:0d021d47eca5
1 #!/usr/bin/env python
2
3 import subprocess
4 from eit import readeit
5 import os, shlex
6
7 def filter_lines(data, search):
8 ret = []
9 for line in data.split("\n"):
10 if line.find(search) == -1:
11 continue
12 ret.append(line)
13 return "\n".join(ret)
14
15 def run_command(command):
16 process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
17 while True:
18 output = process.stdout.readline()
19 if output == '' and process.poll() is not None:
20 break
21 if output:
22 print output.strip()
23 rc = process.poll()
24 return rc
25
26 class ts2mkv(object):
27 def __init__(self):
28 self.msg_prepare = ""
29 self.msg_eit = ""
30 self.msg_ffmpeg = ""
31 self.command = None
32
33 self.video_options = [
34 "-c:v libx264",
35 "-preset slow",
36 "-crf 21"
37 ]
38 self.audio_options = [
39 "-c:a copy",
40 ]
41
42
43 def get_stream_index(self, data):
44 idx = data.find("Stream #")
45 if idx == -1:
46 return ""
47 idx += 8
48 self.msg_prepare += "Selecting: %s\n" % data
49 return data[idx:idx+3]
50
51 def get_movie_description(self, filename):
52 # read the EIT file
53 # TODO: fallback to meta file if no EIT
54 # TODO: is there a way to get the imdb for the movie automagically?
55 # http://www.omdbapi.com/apikey.aspx
56 self.msg_eit = readeit(os.path.splitext(filename)[0] + ".eit")
57
58 def get_ffmpeg_command(self, filename):
59 commands = []
60 fn = "\\'".join(p for p in filename.split("'"))
61
62 p = subprocess.Popen(["ffmpeg", "-i", fn],
63 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
64 out, err = p.communicate()
65 self.msg_ffmpeg = out + "\n" + err
66 self.msg_ffmpeg = self.msg_ffmpeg[self.msg_ffmpeg.find("Input #0"):]
67 # find "Stream #0:" lines
68 info = filter_lines(self.msg_ffmpeg, "Stream #0:")
69
70 fn = fn.replace(" ", "\\ ")
71
72 # CRAP! ffmpeg cannot decode dvb_teletext streams to srt :(
73 # are there any subtitle streams?!
74 #s = filter_lines(info, "Subtitle:")
75 #s = filter_lines(s, "(deu):")
76 #if s != "":
77 # s = self.get_stream_index(s.split("\n")[0])
78 # commands.append([
79 # "ffmpeg",
80 # "-txt_format text",
81 # "-i %s" % fn,
82 # "-map %s" % s,
83 # "%s.srt" % os.path.splitext(fn)[0]
84 # ])
85
86 v = self.get_stream_index(
87 filter_lines(info, "Video:"))
88 if v == "":
89 print "No video stream found"
90 return None
91
92 audioall = filter_lines(info, "Audio:")
93 audio = filter_lines(audioall, "(deu):")
94 a = self.get_stream_index(
95 filter_lines(audio, "ac3"))
96 # TODO: wenn kein ac3 stream dann dts oder mpeg fallback
97 audiomap = [a]
98 if a == "":
99 print "No suitable german audio stream found"
100 return None
101
102 audio = filter_lines(audioall, "(eng):")
103 a = self.get_stream_index(
104 filter_lines(audio, "ac3"))
105 if a != "":
106 # append english audio too!
107 audiomap.append(a)
108
109
110 self.msg_prepare += "Video Stream selected: Stream #%s\n" % v
111 cmd = [
112 "ffmpeg",
113 "-i %s" % fn,
114 "-map %s" % v,
115 ]
116 for a in audiomap:
117 self.msg_prepare += "Audio Stream selected: Stream #%s\n" % a
118 cmd.append("-map %s" % a)
119 cmd.extend(self.video_options)
120 cmd.extend(self.audio_options)
121 cmd.append(os.path.splitext(fn)[0] + ".mkv")
122
123 commands.append(" ".join(cmd))
124 return commands
125
126 def load(self, filename):
127 self.filename = filename
128 self.get_movie_description(filename)
129 self.command = self.get_ffmpeg_command(filename)
130
131 if __name__ == "__main__":
132 import sys
133 os.system('cls' if os.name == 'nt' else 'clear')
134
135 # TODO: get file from commandline
136 filename = "testfiles/chappie.ts"
137
138 mkv = ts2mkv()
139 mkv.load(filename)
140 if mkv.command:
141 fd = open(os.path.splitext(filename)[0] + ".txt", "wb")
142 fd.write(mkv.msg_eit)
143 fd.write("\n\n# ---DEBUG---\n\n")
144 fd.write(mkv.msg_prepare)
145 fd.write(mkv.msg_ffmpeg)
146 fd.close()
147 print mkv.msg_ffmpeg
148
149 for cmd in mkv.command:
150 print "Executing ffmpeg:\n%s\n" % " ".join(cmd)
151 run_command(cmd)

mercurial