ts2mkv.py

Wed, 29 Nov 2017 23:34:51 +0100

author
mdd
date
Wed, 29 Nov 2017 23:34:51 +0100
changeset 22
c18abd9198c0
parent 20
5b433bdd2023
child 24
a1bc75496992
permissions
-rwxr-xr-x

implemented Levenshtein algorithm for incredible speedup

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.
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
7 Automatic audio stream selection
842120f00078 code cleanup
mdd
parents: 16
diff changeset
8 deu: ac3, otherwise fallback to first german stream
842120f00078 code cleanup
mdd
parents: 16
diff changeset
9 eng: ac3, no fallback
10
mdd
parents: 9
diff changeset
10 Automatic crop detection to remove cinematic bars
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
11 percentage + ETA for ffmpeg conversion subprocess
10
mdd
parents: 9
diff changeset
12 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
13 #pylint: disable=line-too-long
842120f00078 code cleanup
mdd
parents: 16
diff changeset
14 #pylint: disable=invalid-name
842120f00078 code cleanup
mdd
parents: 16
diff changeset
15
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
16
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
17 import subprocess
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
18 import pexpect
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
19 from eit import eitinfo
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
20 import os, shlex, sys, time
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
21
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
22 def filter_lines(data, search):
10
mdd
parents: 9
diff changeset
23 """
mdd
parents: 9
diff changeset
24 input: data = \n separated string
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
25 output: all lines where search is found
10
mdd
parents: 9
diff changeset
26 """
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
27 ret = []
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
28 for line in data.split("\n"):
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
29 if line.find(search) == -1:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
30 continue
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
31 ret.append(line)
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
32 return "\n".join(ret)
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
33
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
34 def run_command(command):
10
mdd
parents: 9
diff changeset
35 """
mdd
parents: 9
diff changeset
36 run command as blocking subprocess, returns exit code
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
37 if total_frames > 0 parse ffmpeg status line and insert ETA at line start before output
10
mdd
parents: 9
diff changeset
38 """
mdd
parents: 9
diff changeset
39 process = subprocess.Popen(shlex.split(command), \
mdd
parents: 9
diff changeset
40 stdout=subprocess.PIPE)
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
41 while True:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
42 output = process.stdout.readline()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
43 if output == '' and process.poll() is not None:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
44 break
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
45 if output:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
46 print output.strip()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
47 rc = process.poll()
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
48 return rc
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
49
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
50 def run_ffmpeg_watch(command, frames_total=0):
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
51 """
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
52 run command as blocking subprocess, returns exit code
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
53 if total_frames > 0 parse ffmpeg status line and insert ETA at line start before output
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
54 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
55 #pylint: disable=maybe-no-member
842120f00078 code cleanup
mdd
parents: 16
diff changeset
56
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
57 thread = pexpect.spawn(command)
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
58 cpl = thread.compile_pattern_list([
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
59 pexpect.EOF,
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
60 "frame= *(\d+)",
16
ace8005f02cf finished ffmpeg status output
mdd
parents: 15
diff changeset
61 "(.+)\n",
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
62 '(.+)'
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
63 ])
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
64 percent = 0
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
65 eta = 0
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
66 time_start = time.time() - 0.1 # start in the past
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
67 while True:
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
68 i = thread.expect_list(cpl, timeout=None)
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
69 if i == 0: # EOF
16
ace8005f02cf finished ffmpeg status output
mdd
parents: 15
diff changeset
70 print "\nffmpeg subprocess finished!"
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
71 break
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
72 elif i == 1:
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
73 try:
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
74 frame_number = int(thread.match.group(1))
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
75 if frames_total > 0:
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
76 percent = frame_number * 100.00 / frames_total
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
77 eta = frame_number / (time.time() - time_start)
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
78 # eta is frames per second so far
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
79 eta = (frames_total - frame_number) / eta / 60
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
80 sys.stdout.write("\rFrame %i of %i, %.1f%% done, ETA %.0f minutes, " % (
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
81 frame_number, frames_total, percent, eta
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
82 ))
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
83 except ValueError:
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
84 sys.stdout.write(thread.match.group(0))
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
85 sys.stdout.flush()
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
86 thread.close
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
87 #elif i == 2:
16
ace8005f02cf finished ffmpeg status output
mdd
parents: 15
diff changeset
88 # normal newline line, just ignore them...
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
89 # pass
16
ace8005f02cf finished ffmpeg status output
mdd
parents: 15
diff changeset
90 elif i == 3:
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
91 unknown_line = thread.match.group(0)
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
92 sys.stdout.write(unknown_line)
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
93 sys.stdout.flush()
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
94
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
95 def ffmpeg_filename(filename):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
96 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
97 Escape filename path contents for ffmpeg shell command
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
98 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
99 fn = filename.replace("'", r"\'")
842120f00078 code cleanup
mdd
parents: 16
diff changeset
100 fn = fn.replace(" ", r"\ ")
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
101 return fn
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
102
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
103 class ts2mkv(object):
10
mdd
parents: 9
diff changeset
104 """
mdd
parents: 9
diff changeset
105 Main worker class, contains all the magic & ffmpeg voodoo
mdd
parents: 9
diff changeset
106 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
107 def __init__(self, crf=19, tune='film'):
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
108 self.command = None
13
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
109 self.filename = None
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
110 self.outfilebase = None
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
111 self.info = {}
842120f00078 code cleanup
mdd
parents: 16
diff changeset
112 self.__reset()
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
113
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
114 self.config = {
842120f00078 code cleanup
mdd
parents: 16
diff changeset
115 "overwrite": False,
842120f00078 code cleanup
mdd
parents: 16
diff changeset
116 "scaledown": True,
842120f00078 code cleanup
mdd
parents: 16
diff changeset
117 "rename": True,
842120f00078 code cleanup
mdd
parents: 16
diff changeset
118 "video": [
842120f00078 code cleanup
mdd
parents: 16
diff changeset
119 "-c:v libx264",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
120 "-preset faster", # slow
842120f00078 code cleanup
mdd
parents: 16
diff changeset
121 "-tune %s" % tune, # film / animation
842120f00078 code cleanup
mdd
parents: 16
diff changeset
122 "-crf %i" % crf, # 21, better 19
842120f00078 code cleanup
mdd
parents: 16
diff changeset
123 ],
842120f00078 code cleanup
mdd
parents: 16
diff changeset
124 "audio": [
842120f00078 code cleanup
mdd
parents: 16
diff changeset
125 "-c:a copy",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
126 ]
842120f00078 code cleanup
mdd
parents: 16
diff changeset
127 }
10
mdd
parents: 9
diff changeset
128
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
129 def __reset(self):
842120f00078 code cleanup
mdd
parents: 16
diff changeset
130 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
131 Reset internal stuff before loading new task
842120f00078 code cleanup
mdd
parents: 16
diff changeset
132 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
133 self.info = {
842120f00078 code cleanup
mdd
parents: 16
diff changeset
134 "msg_prepare": "",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
135 "msg_eit": "",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
136 "msg_ffmpeg": "",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
137 "fps": 0,
842120f00078 code cleanup
mdd
parents: 16
diff changeset
138 "frames_total": 0
842120f00078 code cleanup
mdd
parents: 16
diff changeset
139 }
842120f00078 code cleanup
mdd
parents: 16
diff changeset
140 self.command = None
842120f00078 code cleanup
mdd
parents: 16
diff changeset
141 self.filename = None
842120f00078 code cleanup
mdd
parents: 16
diff changeset
142 self.outfilebase = None
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
143
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
144 def get_stream_index(self, data):
10
mdd
parents: 9
diff changeset
145 """
mdd
parents: 9
diff changeset
146 input: ffmpeg stream info string
mdd
parents: 9
diff changeset
147 output: ffmpeg stream mapping part
mdd
parents: 9
diff changeset
148 """
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
149 idx = data.find("Stream #")
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
150 if idx == -1:
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
151 return ""
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
152 idx += 8
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
153 self.info["msg_prepare"] += "Selecting: %s\n" % data
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
154 return data[idx:idx+3]
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
155
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
156 def __get_movie_description(self):
10
mdd
parents: 9
diff changeset
157 """
mdd
parents: 9
diff changeset
158 looks for eit file with same basename of current filename
mdd
parents: 9
diff changeset
159 parse the eit file for txt infofile and optional build new
mdd
parents: 9
diff changeset
160 output filename base with movie name and genre
mdd
parents: 9
diff changeset
161
mdd
parents: 9
diff changeset
162 output: nothing, manipulates internal variables
mdd
parents: 9
diff changeset
163 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
164 if not self.filename:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
165 return
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
166 # read the EIT file
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
167 filename = os.path.splitext(self.filename)[0] + ".eit"
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
168 info = eitinfo(filename)
842120f00078 code cleanup
mdd
parents: 16
diff changeset
169 self.info["msg_eit"] = info.dump()
842120f00078 code cleanup
mdd
parents: 16
diff changeset
170 if not self.config["rename"] or not self.info["msg_eit"]:
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
171 return
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
172 name = info.eit.get("name")
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
173 if name == "":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
174 # cancel rename, no movie title found!
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
175 return
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
176 genre = info.eit.get("genre")
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
177 if genre != "":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
178 name = "%s (%s)" % (name, genre)
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
179 # build new filename
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
180 name = name.replace(' : ', ' - ')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
181 name = name.replace(': ', ' - ')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
182 name = name.replace(':', '-')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
183 name = name.replace('/', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
184 name = name.replace('\\', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
185 name = name.replace('?', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
186 name = name.replace('*', '')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
187 name = name.replace('\"', '\'')
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
188
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
189 self.outfilebase = os.path.join(
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
190 os.path.dirname(filename),
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
191 name
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
192 )
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
193
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
194
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
195 def get_crop_option(self):
10
mdd
parents: 9
diff changeset
196 """
mdd
parents: 9
diff changeset
197 parse the ffmpeg analyze output cropdetect lines
mdd
parents: 9
diff changeset
198 returns None or valid crop string for ffmpeg video filter
mdd
parents: 9
diff changeset
199 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
200 lines = filter_lines(self.info["msg_ffmpeg"], "[Parsed_cropdetect").split("\n")
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
201 option = None
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
202 failcount = 0
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
203 for line in lines:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
204 tmp = line[line.find(" crop="):].strip()
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
205 #print "DEBUG: " + tmp
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
206 if not option:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
207 option = tmp
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
208 else:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
209 if option != tmp:
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
210 failcount += 1
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
211 if failcount > 12:
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
212 print "!!! Crop detect is inconsistent"
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
213 self.info["msg_prepare"] += "WARNING: cropdetect >50% inconsistent over scan time, disabling autocrop\n"
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
214 return None
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
215 self.info["msg_prepare"] += "Crop detected: %s\n" % option
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
216 return option
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
217
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
218 def __get_audiomap(self, info):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
219 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
220 Select the wanted german and english audio streams from ffmpeg info
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
221 output: mapping list
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
222 """
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
223 audiomap = []
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
224 audioall = filter_lines(info, "Audio:")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
225 audio = filter_lines(audioall, "(deu):")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
226 aidx = self.get_stream_index(
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
227 filter_lines(audio, "ac3"))
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
228 if aidx == "":
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
229 print audioall
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
230 print "No AC3 german audio stream found"
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
231 # try to find the first german audio stream
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
232 aidx = self.get_stream_index(audio.split("\n")[0])
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
233 if aidx == "":
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
234 print "No other german audio streams, trying english..."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
235 else:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
236 print "Selecting first german stream."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
237 audiomap.append(aidx)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
238 else:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
239 audiomap.append(aidx)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
240
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
241 audio = filter_lines(audioall, "(eng):")
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
242 aidx = self.get_stream_index(
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
243 filter_lines(audio, "ac3"))
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
244 if aidx != "" and filter_lines(audio, "ac3").find(" 0 channels ") < 1:
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
245 # append english audio too!
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
246 print "Selecting english ac3 stream."
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
247 audiomap.append(aidx)
20
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
248 if len(audiomap) == 0 and self.config["firstaudio"]:
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
249 # append first audio stream as forced fallback
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
250 aidx = self.get_stream_index(audioall)
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
251 if aidx != "":
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
252 print "Forcing first found audio stream: %s" % aidx
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
253 audiomap.append(aidx)
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
254 return audiomap
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
255
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
256 def __parse_info(self):
842120f00078 code cleanup
mdd
parents: 16
diff changeset
257 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
258 get total duration and fps from input stream
842120f00078 code cleanup
mdd
parents: 16
diff changeset
259 output: sets local variables
842120f00078 code cleanup
mdd
parents: 16
diff changeset
260 # Duration: 01:39:59.88, start: 93674.825111, bitrate: 9365 kb/s
842120f00078 code cleanup
mdd
parents: 16
diff changeset
261 # Stream #0:1[0x1ff]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn, 50 tbc
842120f00078 code cleanup
mdd
parents: 16
diff changeset
262 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
263 tmp = filter_lines(self.info["msg_ffmpeg"], "Duration:").strip()[10:]
842120f00078 code cleanup
mdd
parents: 16
diff changeset
264 tmp = tmp[0:tmp.find(",")].strip()
842120f00078 code cleanup
mdd
parents: 16
diff changeset
265 print "Input duration: %s" % tmp
842120f00078 code cleanup
mdd
parents: 16
diff changeset
266 try:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
267 self.info["frames_total"] = int(tmp[0:2]) * 3600 + \
842120f00078 code cleanup
mdd
parents: 16
diff changeset
268 int(tmp[3:5]) * 60 + int(tmp[6:8])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
269 except ValueError:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
270 self.info["frames_total"] = 0
842120f00078 code cleanup
mdd
parents: 16
diff changeset
271
842120f00078 code cleanup
mdd
parents: 16
diff changeset
272 tmp = filter_lines(self.info["msg_ffmpeg"], "Stream #0:")
842120f00078 code cleanup
mdd
parents: 16
diff changeset
273 tmp = filter_lines(tmp, "Video:").split(",")
842120f00078 code cleanup
mdd
parents: 16
diff changeset
274 for fps in tmp:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
275 if fps.strip().endswith('fps'):
842120f00078 code cleanup
mdd
parents: 16
diff changeset
276 try:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
277 self.info["fps"] = float(fps.strip().split(' ')[0])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
278 except ValueError:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
279 self.info["fps"] = 0
842120f00078 code cleanup
mdd
parents: 16
diff changeset
280 break
842120f00078 code cleanup
mdd
parents: 16
diff changeset
281 self.info["frames_total"] = round(self.info["frames_total"] * self.info["fps"], 0)
842120f00078 code cleanup
mdd
parents: 16
diff changeset
282 print "Input framerate: %f fps" % self.info["fps"]
842120f00078 code cleanup
mdd
parents: 16
diff changeset
283 print "Total frames of input file: %i" % (self.info["frames_total"])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
284
842120f00078 code cleanup
mdd
parents: 16
diff changeset
285
842120f00078 code cleanup
mdd
parents: 16
diff changeset
286 def __get_ffmpeg_input_info(self, filename):
842120f00078 code cleanup
mdd
parents: 16
diff changeset
287 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
288 Run ffmpeg for cropdetect and general input information
842120f00078 code cleanup
mdd
parents: 16
diff changeset
289 """
842120f00078 code cleanup
mdd
parents: 16
diff changeset
290 cmd = [
842120f00078 code cleanup
mdd
parents: 16
diff changeset
291 "ffmpeg", "-hide_banner",
842120f00078 code cleanup
mdd
parents: 16
diff changeset
292 "-ss 00:05:00", "-t 2", # search to 5 minutes, analyze 2 seconds
842120f00078 code cleanup
mdd
parents: 16
diff changeset
293 "-i %s" % filename,
842120f00078 code cleanup
mdd
parents: 16
diff changeset
294 "-vf \"cropdetect=24:2:0\"", # detect black bar crop on top and bottom
842120f00078 code cleanup
mdd
parents: 16
diff changeset
295 "-f null", "-" # no output file
842120f00078 code cleanup
mdd
parents: 16
diff changeset
296 ]
842120f00078 code cleanup
mdd
parents: 16
diff changeset
297 p = subprocess.Popen(shlex.split(" ".join(cmd)), \
842120f00078 code cleanup
mdd
parents: 16
diff changeset
298 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
842120f00078 code cleanup
mdd
parents: 16
diff changeset
299 out, err = p.communicate()
18
91cf8d348c74 brainfuck
mdd
parents: 17
diff changeset
300 self.info["msg_ffmpeg"] = out + "\n" + err
91cf8d348c74 brainfuck
mdd
parents: 17
diff changeset
301 self.info["msg_ffmpeg"] = self.info["msg_ffmpeg"][self.info["msg_ffmpeg"].find("Input #0"):]
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
302
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
303 def get_ffmpeg_command(self):
10
mdd
parents: 9
diff changeset
304 """
mdd
parents: 9
diff changeset
305 Too complex to describe, this does all the magic
mdd
parents: 9
diff changeset
306 output: produces internal ffmpeg command list (empty command list on error)
mdd
parents: 9
diff changeset
307 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
308 if not self.filename:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
309 return None
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
310
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
311 fn = {
842120f00078 code cleanup
mdd
parents: 16
diff changeset
312 "in": ffmpeg_filename(self.filename),
842120f00078 code cleanup
mdd
parents: 16
diff changeset
313 "out": self.outfilebase + ".mkv"
842120f00078 code cleanup
mdd
parents: 16
diff changeset
314 }
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
315
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
316 # 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
317 # we do not want to overwrite files in accident (caused by automatic file naming)
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
318 if not self.config["overwrite"] and len(glob.glob(fn["out"])) > 0:
842120f00078 code cleanup
mdd
parents: 16
diff changeset
319 print "Output file exists: %s" % fn["out"]
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
320 print "NOT overwriting it!"
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
321 return None
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
322
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
323 # load input file to get informations about
842120f00078 code cleanup
mdd
parents: 16
diff changeset
324 self.__get_ffmpeg_input_info(fn["in"])
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
325
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
326 # find "Stream #0:" lines
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
327 info = filter_lines(self.info["msg_ffmpeg"], "Stream #0:")
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
328
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
329 v = self.get_stream_index(
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
330 filter_lines(info, "Video:"))
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
331 if v == "":
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
332 print "No video stream found"
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
333 return None
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
334
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
335 self.__parse_info()
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
336
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
337 # copy ALL subtitle streams if present!
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
338 # 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
339 submap = []
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
340 for tmp in filter_lines(info, "Subtitle: dvb_teletext").split("\n"):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
341 if self.get_stream_index(tmp):
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
342 submap.append(self.get_stream_index(tmp))
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
343 # Subtitles disabled, that doesnt work as expected, dreambox crashes on copied subtitle stream
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
344 submap = []
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
345
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
346 # select audio streams
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
347 audiomap = self.__get_audiomap(info)
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
348 if len(audiomap) == 0:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
349 print "No suitable audio stream found, aborting."
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
350 return None
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
351
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
352 # 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
353 # Find all these files and join them!
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
354 inputs = [fn["in"]]
842120f00078 code cleanup
mdd
parents: 16
diff changeset
355 if os.path.splitext(self.filename)[1].lower() == '.ts':
842120f00078 code cleanup
mdd
parents: 16
diff changeset
356 for tmp in glob.glob(self.filename + '.' + ('[0-9]' * 3)):
842120f00078 code cleanup
mdd
parents: 16
diff changeset
357 inputs.append(ffmpeg_filename(tmp))
12
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
358
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
359 if len(inputs) > 1:
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
360 # use ffmpeg input concat function
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
361 # attention, ffmpeg concat protocol doesnt like escape sequences
19
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
362 for tmp in range(len(inputs)):
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
363 inputs[tmp] = inputs[tmp].replace(r"\ ", " ").replace(r"\'", "'")\
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
364
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
365 fn["in"] = "\"concat:" + "|".join(inputs) + "\""
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
366 # no ETA calculation possible since we have only the length of first file
19
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
367 # we could estimate by multiplying with factor generated by input file sizes
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
368 totalbytes = 0.0
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
369 for tmp in inputs:
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
370 totalbytes += os.path.getsize(tmp)
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
371 print "estimating total frames for ETA based on file sizes (we have multiple inputs here)"
3a9fd72717df estimate eta on concat protocol
mdd
parents: 18
diff changeset
372 self.info["frames_total"] *= totalbytes / os.path.getsize(inputs[0])
12
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
373
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
374 idx = 0
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
375 for tmp in inputs:
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
376 self.info["msg_prepare"] += "Input file #%i: %s\n" % (
12
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
377 idx, os.path.basename(tmp))
f0c7db3b239d ffmpeg concatenate multiple input files .ts .ts.NNN
mdd
parents: 11
diff changeset
378 idx += 1
11
821c02fa7070 do not overwrite output file if exists
mdd
parents: 10
diff changeset
379
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
380 cmd = [
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
381 "ffmpeg", "-hide_banner",
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
382 "-i %s" % fn["in"],
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
383 ]
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
384
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
385 if self.config["overwrite"]:
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
386 cmd.append("-y")
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
387
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
388 for tmp in submap:
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
389 self.info["msg_prepare"] += "Subtitle Stream selected: Stream #%s\n" % tmp
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
390 cmd.append("-map %s" % tmp)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
391
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
392 cmd.append("-map %s" % v)
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
393 self.info["msg_prepare"] += "Video Stream selected: Stream #%s\n" % v
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
394
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
395 flt = []
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
396 crop = self.get_crop_option()
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
397 if crop:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
398 flt.append(crop)
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
399 if self.config["scaledown"]:
10
mdd
parents: 9
diff changeset
400 # -2 ensures division by two for codec
mdd
parents: 9
diff changeset
401 flt.append("scale='min(1280,iw)':-2'")
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
402 self.info["msg_prepare"] += "Scaling output stream to 720p if width >1280\n"
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
403 if len(flt) > 0:
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
404 # append video filters
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
405 cmd.append('-filter:v "%s"' % ",".join(flt))
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
406
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
407 for tmp in audiomap:
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
408 self.info["msg_prepare"] += "Audio Stream selected: Stream #%s\n" % tmp
14
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
409 cmd.append("-map %s" % tmp)
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
410 if len(submap) > 0:
b398ae388328 added support for dvb_teletext subtitles
mdd
parents: 13
diff changeset
411 cmd.append("-c:s dvdsub")
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
412 cmd.extend(self.config["video"])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
413 cmd.extend(self.config["audio"])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
414 cmd.append(ffmpeg_filename(fn["out"]))
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
415
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
416 return [" ".join(cmd)]
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
417
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
418 def load(self, filename):
10
mdd
parents: 9
diff changeset
419 """
mdd
parents: 9
diff changeset
420 First step: setup, analyze & prepare for conversion
mdd
parents: 9
diff changeset
421 """
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
422 self.__reset()
13
cf5c5cec1b2b bugfix: cleanup status messages when processing multiple files
mdd
parents: 12
diff changeset
423
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
424 self.filename = filename
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
425 self.outfilebase = os.path.splitext(filename)[0]
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
426 self.__get_movie_description()
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
427 self.command = self.get_ffmpeg_command()
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
428
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
429 def convert(self):
10
mdd
parents: 9
diff changeset
430 """
mdd
parents: 9
diff changeset
431 Second step: write info text file and start ffmpeg conversion
mdd
parents: 9
diff changeset
432 requires successful load as first step
mdd
parents: 9
diff changeset
433 returns ffmpeg conversion exit status
mdd
parents: 9
diff changeset
434 """
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
435 if not self.command:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
436 return None
20
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
437 if not self.info["msg_eit"]:
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
438 self.info["msg_eit"] = "No EIT file found, sorry - no description"
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
439 fd = open(self.outfilebase + ".txt", "wb")
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
440 fd.write(self.info["msg_eit"])
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
441 fd.write("\n\n# ---DEBUG---\n\n")
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
442 fd.write(self.info["msg_prepare"])
842120f00078 code cleanup
mdd
parents: 16
diff changeset
443 fd.write(self.info["msg_ffmpeg"])
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
444 fd.close()
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
445 #print self.info["msg_ffmpeg"]
7
0d021d47eca5 added ts2mkv converter
mdd
parents:
diff changeset
446
10
mdd
parents: 9
diff changeset
447 for cmd in self.command:
8
92409c985e0d added autocrop and 720p rescaler
mdd
parents: 7
diff changeset
448 print "Executing ffmpeg:\n%s\n" % cmd
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
449 #return run_command(cmd, self.total_frames)
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
450 return run_ffmpeg_watch(cmd, frames_total=self.info["frames_total"])
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
451
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
452
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
453
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
454 if __name__ == "__main__":
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
455 # parse command line options
10
mdd
parents: 9
diff changeset
456 import argparse, glob
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
457
10
mdd
parents: 9
diff changeset
458 parser = argparse.ArgumentParser(description='DVB-TS to MKV kung-fu')
mdd
parents: 9
diff changeset
459 parser.add_argument('--crf', type=int, default=19, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
460 help='h264 crf (default 19)')
10
mdd
parents: 9
diff changeset
461 parser.add_argument('--tune', default='film', \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
462 help='ffmpeg tune preset [film, animation] (default is film)')
10
mdd
parents: 9
diff changeset
463 parser.add_argument('--ns', action='store_true', default=False, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
464 help='no rescaling (default is scale to 720p)')
10
mdd
parents: 9
diff changeset
465 parser.add_argument('--rename', action='store_true', default=False, \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
466 help='rename file basename to name and genre from EIT file if present')
10
mdd
parents: 9
diff changeset
467 parser.add_argument('input', metavar='input', nargs='+', \
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
468 help='one or more files, glob style syntax')
15
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
469 parser.add_argument('-f', action='store_true', default=False, \
82361ad7b3fe some changes, also implemented ffmpeg progress info and added force overwrite mode
mdd
parents: 14
diff changeset
470 help='force overwrite of existing file')
20
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
471 parser.add_argument('--fa', action='store_true', default=False, \
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
472 help='use first audio stream found')
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
473
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
474 args = parser.parse_args()
17
842120f00078 code cleanup
mdd
parents: 16
diff changeset
475 processor = ts2mkv(crf=args.crf, tune=args.tune)
18
91cf8d348c74 brainfuck
mdd
parents: 17
diff changeset
476 processor.config["scaledown"] = not args.ns
91cf8d348c74 brainfuck
mdd
parents: 17
diff changeset
477 processor.config["rename"] = args.rename
91cf8d348c74 brainfuck
mdd
parents: 17
diff changeset
478 processor.config["overwrite"] = args.f
20
5b433bdd2023 force first audio stream option
mdd
parents: 19
diff changeset
479 processor.config["firstaudio"] = args.fa
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
480
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
481 for srcstr in args.input:
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
482 src = glob.glob(srcstr)
10
mdd
parents: 9
diff changeset
483 for srcfile in src:
mdd
parents: 9
diff changeset
484 print "Processing: %s" % srcfile
mdd
parents: 9
diff changeset
485 processor.load(srcfile)
mdd
parents: 9
diff changeset
486 processor.convert()
9
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
487
1bf778001041 added option parser and automatic file rename feature
mdd
parents: 8
diff changeset
488

mercurial