ts2mkv.py

Sat, 25 Nov 2017 16:51:08 +0100

author
mdd
date
Sat, 25 Nov 2017 16:51:08 +0100
changeset 14
b398ae388328
parent 13
cf5c5cec1b2b
child 15
82361ad7b3fe
permissions
-rwxr-xr-x

added support for dvb_teletext subtitles

7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
1 #!/usr/bin/env python
10
mdd
parents: 9
diff changeset
2 """
mdd
parents: 9
diff changeset
3 DVB-TS to MKV kung-fu
mdd
parents: 9
diff changeset
4 2017 by mdd
mdd
parents: 9
diff changeset
5
mdd
parents: 9
diff changeset
6 Toolkit / executable to automagically convert DVB recordings to h264 mkv.
mdd
parents: 9
diff changeset
7 Automatic audio stream selection (deu/eng)
mdd
parents: 9
diff changeset
8 Automatic crop detection to remove cinematic bars
mdd
parents: 9
diff changeset
9 """
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
10
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
11 import subprocess
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
12 from eit import readeit, eitinfo
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
13 import os, shlex
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
14
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
15 def filter_lines(data, search):
10
mdd
parents: 9
diff changeset
16 """
mdd
parents: 9
diff changeset
17 input: data = \n separated string
mdd
parents: 9
diff changeset
18 output: tuple containing all lines where search is found
mdd
parents: 9
diff changeset
19 """
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
20 ret = []
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
21 for line in data.split("\n"):
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
22 if line.find(search) == -1:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
23 continue
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
24 ret.append(line)
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
25 return "\n".join(ret)
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
26
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
27 def run_command(command):
10
mdd
parents: 9
diff changeset
28 """
mdd
parents: 9
diff changeset
29 run command as blocking subprocess, returns exit code
mdd
parents: 9
diff changeset
30 """
mdd
parents: 9
diff changeset
31 process = subprocess.Popen(shlex.split(command), \
mdd
parents: 9
diff changeset
32 stdout=subprocess.PIPE)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
33 while True:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
34 output = process.stdout.readline()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
35 if output == '' and process.poll() is not None:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
36 break
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
37 if output:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
38 print output.strip()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
39 rc = process.poll()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
40 return rc
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
41
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
42 def ffmpeg_filename(filename):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
43 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
44 Escape filename path contents for ffmpeg shell command
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
45 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
46 fn = "\\'".join(p for p in filename.split("'"))
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
47 fn = fn.replace(" ", "\\ ")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
48 return fn
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
49
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
50 class ts2mkv(object):
10
mdd
parents: 9
diff changeset
51 """
mdd
parents: 9
diff changeset
52 Main worker class, contains all the magic & ffmpeg voodoo
mdd
parents: 9
diff changeset
53 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
54 def __init__(self, crf=19, tune='film', scaleto_720p=True, rename=False):
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
55 self.msg_prepare = ""
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
56 self.msg_eit = ""
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
57 self.msg_ffmpeg = ""
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
58 self.command = None
13
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
59 self.filename = None
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
60 self.outfilebase = None
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
61
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
62 self.scaleto_720p = scaleto_720p
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
63 self.rename = rename
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
64
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
65 self.video_options = [
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
66 "-c:v libx264",
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
67 "-preset faster", # slow
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
68 "-tune %s" % tune, # film / animation
10
mdd
parents: 9
diff changeset
69 "-crf %i" % crf, # 21, better 19
mdd
parents: 9
diff changeset
70 ]
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
71 self.audio_options = [
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
72 "-c:a copy",
10
mdd
parents: 9
diff changeset
73 ]
mdd
parents: 9
diff changeset
74
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
75
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
76 def get_stream_index(self, data):
10
mdd
parents: 9
diff changeset
77 """
mdd
parents: 9
diff changeset
78 input: ffmpeg stream info string
mdd
parents: 9
diff changeset
79 output: ffmpeg stream mapping part
mdd
parents: 9
diff changeset
80 """
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
81 idx = data.find("Stream #")
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
82 if idx == -1:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
83 return ""
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
84 idx += 8
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
85 self.msg_prepare += "Selecting: %s\n" % data
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
86 return data[idx:idx+3]
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
87
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
88 def get_movie_description(self):
10
mdd
parents: 9
diff changeset
89 """
mdd
parents: 9
diff changeset
90 looks for eit file with same basename of current filename
mdd
parents: 9
diff changeset
91 parse the eit file for txt infofile and optional build new
mdd
parents: 9
diff changeset
92 output filename base with movie name and genre
mdd
parents: 9
diff changeset
93
mdd
parents: 9
diff changeset
94 output: nothing, manipulates internal variables
mdd
parents: 9
diff changeset
95 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
96 if not self.filename:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
97 return
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
98 # read the EIT file
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
99 filename = os.path.splitext(self.filename)[0] + ".eit"
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
100 self.msg_eit = readeit(filename)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
101 if not self.rename or not self.msg_eit:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
102 return
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
103 info = eitinfo(filename)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
104 name = info.eit.get("name")
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
105 if name == "":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
106 # cancel rename, no movie title found!
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
107 return
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
108 genre = info.eit.get("genre")
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
109 if genre != "":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
110 name = "%s (%s)" % (name, genre)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
111 # build new filename
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
112 name = name.replace(' : ', ' - ')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
113 name = name.replace(': ', ' - ')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
114 name = name.replace(':', '-')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
115 name = name.replace('/', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
116 name = name.replace('\\', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
117 name = name.replace('?', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
118 name = name.replace('*', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
119 name = name.replace('\"', '\'')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
120
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
121 self.outfilebase = os.path.join(
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
122 os.path.dirname(filename),
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
123 name
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
124 )
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
125
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
126
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
127 def get_crop_option(self):
10
mdd
parents: 9
diff changeset
128 """
mdd
parents: 9
diff changeset
129 parse the ffmpeg analyze output cropdetect lines
mdd
parents: 9
diff changeset
130 returns None or valid crop string for ffmpeg video filter
mdd
parents: 9
diff changeset
131 """
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
132 lines = filter_lines(self.msg_ffmpeg, "[Parsed_cropdetect").split("\n")
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
133 option = None
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
134 for line in lines:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
135 tmp = line[line.find(" crop="):].strip()
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
136 #print "DEBUG: " + tmp
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
137 if not option:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
138 option = tmp
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
139 else:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
140 if option != tmp:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
141 self.msg_prepare += "WARNING: cropdetect inconsistent over scan time, disabling autocrop\n"
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
142 return None
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
143 self.msg_prepare += "Crop detected: %s\n" % option
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
144 return option
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
145
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
146 def __get_audiomap(self, info):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
147 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
148 Select the wanted german and english audio streams from ffmpeg info
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
149 output: mapping list
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
150 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
151 audiomap = []
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
152 audioall = filter_lines(info, "Audio:")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
153 audio = filter_lines(audioall, "(deu):")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
154 aidx = self.get_stream_index(
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
155 filter_lines(audio, "ac3"))
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
156 if aidx == "":
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
157 print audioall
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
158 print "No AC3 german audio stream found"
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
159 # try to find the first german audio stream
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
160 aidx = self.get_stream_index(audio.split("\n")[0])
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
161 if aidx == "":
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
162 print "No other german audio streams, trying english..."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
163 else:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
164 print "Selecting first german stream."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
165 audiomap.append(aidx)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
166 else:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
167 audiomap.append(aidx)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
168
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
169 audio = filter_lines(audioall, "(eng):")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
170 aidx = self.get_stream_index(
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
171 filter_lines(audio, "ac3"))
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
172 if aidx != "":
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
173 # append english audio too!
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
174 print "Selecting english ac3 stream."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
175 audiomap.append(aidx)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
176 return audiomap
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
177
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
178 def get_ffmpeg_command(self):
10
mdd
parents: 9
diff changeset
179 """
mdd
parents: 9
diff changeset
180 Too complex to describe, this does all the magic
mdd
parents: 9
diff changeset
181 output: produces internal ffmpeg command list (empty command list on error)
mdd
parents: 9
diff changeset
182 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
183 if not self.filename:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
184 return None
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
185
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
186
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
187 commands = []
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
188 fn = ffmpeg_filename(self.filename)
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
189 outfn = self.outfilebase + ".mkv"
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
190 # double-check: pull the kill switch and exit if outfile exists already!
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
191 # we do not want to overwrite files in accident (caused by automatic file naming)
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
192 if len(glob.glob(outfn)) > 0:
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
193 print "Output file exists: %s" % outfn
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
194 print "NOT overwriting it!"
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
195 return None
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
196 outfn = ffmpeg_filename(outfn)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
197
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
198 cmd = [
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
199 "ffmpeg", "-hide_banner",
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
200 "-ss 00:05:00", "-t 1", # search to 5 minutes, analyze 1 second
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
201 "-i %s" % fn,
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
202 "-vf \"cropdetect=24:2:0\"", # detect black bar crop on top and bottom
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
203 "-f null", "-" # no output file
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
204 ]
10
mdd
parents: 9
diff changeset
205 p = subprocess.Popen(shlex.split(" ".join(cmd)), \
mdd
parents: 9
diff changeset
206 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
207 out, err = p.communicate()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
208 self.msg_ffmpeg = out + "\n" + err
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
209 self.msg_ffmpeg = self.msg_ffmpeg[self.msg_ffmpeg.find("Input #0"):]
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
210
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
211 # find "Stream #0:" lines
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
212 info = filter_lines(self.msg_ffmpeg, "Stream #0:")
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
213
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
214 v = self.get_stream_index(
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
215 filter_lines(info, "Video:"))
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
216 if v == "":
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
217 print "No video stream found"
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
218 return None
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
219
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
220
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
221 # TODO: copy ALL subtitle streams if present!
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
222 # Stream #0:0[0x20](deu): Subtitle: dvb_teletext ([6][0][0][0] / 0x0006), 492x250
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
223 submap = []
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
224 for tmp in filter_lines(info, "Subtitle: dvb_teletext").split("\n"):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
225 if self.get_stream_index(tmp):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
226 submap.append(self.get_stream_index(tmp))
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
227
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
228 # select audio streams
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
229 audiomap = self.__get_audiomap(info)
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
230 if len(audiomap) == 0:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
231 print "No suitable audio stream found, aborting."
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
232 return None
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
233
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
234 # Old dreambox images did a file split: .ts .ts.001 .ts.002 etc.
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
235 # Find all these files and join them!
12
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
236 inputs = [fn]
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
237 if os.path.splitext(fn)[1].lower() == '.ts':
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
238 for fpart in glob.glob(self.filename + '.' + ('[0-9]' * 3)):
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
239 fn = "\\'".join(p for p in fpart.split("'"))
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
240 fn = fn.replace(" ", "\\ ")
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
241 inputs.append(fn)
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
242
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
243 if len(inputs) > 1:
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
244 # use ffmpeg input concat function
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
245 # attention, ffmpeg doesnt like escape sequences
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
246 fn = "\"concat:" + \
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
247 "|".join(inputs)\
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
248 .replace('\ ', ' ')\
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
249 .replace("\'", "'")\
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
250 + "\""
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
251
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
252 idx = 0
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
253 for tmp in inputs:
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
254 self.msg_prepare += "Input file #%i: %s\n" % (
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
255 idx, os.path.basename(tmp))
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
256 idx += 1
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
257
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
258 cmd = [
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
259 "ffmpeg", "-hide_banner",
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
260 "-i %s" % fn,
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
261 ]
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
262
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
263 for tmp in submap:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
264 self.msg_prepare += "Subtitle Stream selected: Stream #%s\n" % tmp
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
265 cmd.append("-map %s" % tmp)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
266
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
267 cmd.append("-map %s" % v)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
268 self.msg_prepare += "Video Stream selected: Stream #%s\n" % v
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
269
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
270 flt = []
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
271 crop = self.get_crop_option()
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
272 if crop:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
273 flt.append(crop)
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
274 if self.scaleto_720p:
10
mdd
parents: 9
diff changeset
275 # -2 ensures division by two for codec
mdd
parents: 9
diff changeset
276 flt.append("scale='min(1280,iw)':-2'")
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
277 self.msg_prepare += "Scaling output stream to 720p if width >1280\n"
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
278 if len(flt) > 0:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
279 # append video filters
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
280 cmd.append('-filter:v "%s"' % ",".join(flt))
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
281 for tmp in audiomap:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
282 self.msg_prepare += "Audio Stream selected: Stream #%s\n" % tmp
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
283 cmd.append("-map %s" % tmp)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
284 if len(submap) > 0:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
285 cmd.append("-c:s dvdsub")
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
286 cmd.extend(self.video_options)
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
287 cmd.extend(self.audio_options)
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
288 cmd.append(outfn)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
289
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
290 commands.append(" ".join(cmd))
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
291 return commands
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
292
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
293 def load(self, filename):
10
mdd
parents: 9
diff changeset
294 """
mdd
parents: 9
diff changeset
295 First step: setup, analyze & prepare for conversion
mdd
parents: 9
diff changeset
296 """
13
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
297 self.msg_prepare = ""
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
298 self.msg_eit = ""
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
299 self.msg_ffmpeg = ""
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
300
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
301 self.filename = filename
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
302 self.outfilebase = os.path.splitext(filename)[0]
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
303 self.get_movie_description()
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
304 self.command = self.get_ffmpeg_command()
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
305
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
306 def convert(self):
10
mdd
parents: 9
diff changeset
307 """
mdd
parents: 9
diff changeset
308 Second step: write info text file and start ffmpeg conversion
mdd
parents: 9
diff changeset
309 requires successful load as first step
mdd
parents: 9
diff changeset
310 returns ffmpeg conversion exit status
mdd
parents: 9
diff changeset
311 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
312 if not self.command:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
313 return None
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
314 fd = open(self.outfilebase + ".txt", "wb")
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
315 fd.write(self.msg_eit)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
316 fd.write("\n\n# ---DEBUG---\n\n")
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
317 fd.write(self.msg_prepare)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
318 fd.write(self.msg_ffmpeg)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
319 fd.close()
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
320 #print self.msg_ffmpeg
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
321
10
mdd
parents: 9
diff changeset
322 for cmd in self.command:
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
323 print "Executing ffmpeg:\n%s\n" % cmd
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
324 return run_command(cmd)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
325
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
326
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
327
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
328 if __name__ == "__main__":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
329 # parse command line options
10
mdd
parents: 9
diff changeset
330 import argparse, glob
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
331
10
mdd
parents: 9
diff changeset
332 parser = argparse.ArgumentParser(description='DVB-TS to MKV kung-fu')
mdd
parents: 9
diff changeset
333 parser.add_argument('--crf', type=int, default=19, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
334 help='h264 crf (default 19)')
10
mdd
parents: 9
diff changeset
335 parser.add_argument('--tune', default='film', \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
336 help='ffmpeg tune preset [film, animation] (default is film)')
10
mdd
parents: 9
diff changeset
337 parser.add_argument('--ns', action='store_true', default=False, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
338 help='no rescaling (default is scale to 720p)')
10
mdd
parents: 9
diff changeset
339 parser.add_argument('--rename', action='store_true', default=False, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
340 help='rename file basename to name and genre from EIT file if present')
10
mdd
parents: 9
diff changeset
341 parser.add_argument('input', metavar='input', nargs='+', \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
342 help='one or more files, glob style syntax')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
343
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
344 args = parser.parse_args()
10
mdd
parents: 9
diff changeset
345 processor = ts2mkv(crf=args.crf, tune=args.tune, scaleto_720p=(not args.ns), \
mdd
parents: 9
diff changeset
346 rename=args.rename)
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
347
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
348 for srcstr in args.input:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
349 src = glob.glob(srcstr)
10
mdd
parents: 9
diff changeset
350 for srcfile in src:
mdd
parents: 9
diff changeset
351 print "Processing: %s" % srcfile
mdd
parents: 9
diff changeset
352 processor.load(srcfile)
mdd
parents: 9
diff changeset
353 processor.convert()
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
354
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
355

mercurial