Sat, 25 Nov 2017 16:51:08 +0100
added support for dvb_teletext subtitles
ts2mkv.py | file | annotate | diff | comparison | revisions |
--- a/ts2mkv.py Sat Nov 25 15:37:54 2017 +0100 +++ b/ts2mkv.py Sat Nov 25 16:51:08 2017 +0100 @@ -39,6 +39,14 @@ rc = process.poll() return rc +def ffmpeg_filename(filename): + """ + Escape filename path contents for ffmpeg shell command + """ + fn = "\\'".join(p for p in filename.split("'")) + fn = fn.replace(" ", "\\ ") + return fn + class ts2mkv(object): """ Main worker class, contains all the magic & ffmpeg voodoo @@ -135,6 +143,38 @@ self.msg_prepare += "Crop detected: %s\n" % option return option + def __get_audiomap(self, info): + """ + Select the wanted german and english audio streams from ffmpeg info + output: mapping list + """ + audiomap = [] + audioall = filter_lines(info, "Audio:") + audio = filter_lines(audioall, "(deu):") + aidx = self.get_stream_index( + filter_lines(audio, "ac3")) + if aidx == "": + print audioall + print "No AC3 german audio stream found" + # try to find the first german audio stream + aidx = self.get_stream_index(audio.split("\n")[0]) + if aidx == "": + print "No other german audio streams, trying english..." + else: + print "Selecting first german stream." + audiomap.append(aidx) + else: + audiomap.append(aidx) + + audio = filter_lines(audioall, "(eng):") + aidx = self.get_stream_index( + filter_lines(audio, "ac3")) + if aidx != "": + # append english audio too! + print "Selecting english ac3 stream." + audiomap.append(aidx) + return audiomap + def get_ffmpeg_command(self): """ Too complex to describe, this does all the magic @@ -145,8 +185,7 @@ commands = [] - fn = "\\'".join(p for p in self.filename.split("'")) - fn = fn.replace(" ", "\\ ") + fn = ffmpeg_filename(self.filename) outfn = self.outfilebase + ".mkv" # double-check: pull the kill switch and exit if outfile exists already! # we do not want to overwrite files in accident (caused by automatic file naming) @@ -154,82 +193,45 @@ print "Output file exists: %s" % outfn print "NOT overwriting it!" return None - outfn = "\\'".join(p for p in outfn.split("'")) - outfn = outfn.replace(" ", "\\ ") + outfn = ffmpeg_filename(outfn) - cmd = ["ffmpeg", - "-ss 00:05:00", "-t 1", # search to 5 minutes, analyze 1 second - "-i %s" % fn, - "-vf \"cropdetect=24:2:0\"", # detect black bar crop on top and bottom - "-f null", "-" # no output file - ] - print " ".join(cmd) + cmd = [ + "ffmpeg", "-hide_banner", + "-ss 00:05:00", "-t 1", # search to 5 minutes, analyze 1 second + "-i %s" % fn, + "-vf \"cropdetect=24:2:0\"", # detect black bar crop on top and bottom + "-f null", "-" # no output file + ] p = subprocess.Popen(shlex.split(" ".join(cmd)), \ stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() - print "Command return code: ", p.poll() self.msg_ffmpeg = out + "\n" + err self.msg_ffmpeg = self.msg_ffmpeg[self.msg_ffmpeg.find("Input #0"):] # find "Stream #0:" lines info = filter_lines(self.msg_ffmpeg, "Stream #0:") - - # CRAP! ffmpeg cannot decode dvb_teletext streams to srt :( - # are there any subtitle streams?! - #s = filter_lines(info, "Subtitle:") - #s = filter_lines(s, "(deu):") - #if s != "": - # s = self.get_stream_index(s.split("\n")[0]) - # commands.append([ - # "ffmpeg", - # "-txt_format text", - # "-i %s" % fn, - # "-map %s" % s, - # "%s.srt" % os.path.splitext(fn)[0] - # ]) - v = self.get_stream_index( filter_lines(info, "Video:")) if v == "": print "No video stream found" return None - audiomap = [] - audioall = filter_lines(info, "Audio:") - audio = filter_lines(audioall, "(deu):") - a = self.get_stream_index( - filter_lines(audio, "ac3")) - # TODO: wenn kein ac3 stream dann dts oder mpeg fallback - if a == "": - print audioall - print "No AC3 german audio stream found" - # try to find the first german audio stream - a = self.get_stream_index(audio.split("\n")[0]) - if a == "": - print "No other german audio streams, trying english ac3..." - else: - print "Selecting first german stream." - audiomap.append(a) - else: - audiomap.append(a) - audio = filter_lines(audioall, "(eng):") - a = self.get_stream_index( - filter_lines(audio, "ac3")) - if a != "": - # append english audio too! - print "Selecting english ac3 stream." - audiomap.append(a) + # TODO: copy ALL subtitle streams if present! + # Stream #0:0[0x20](deu): Subtitle: dvb_teletext ([6][0][0][0] / 0x0006), 492x250 + submap = [] + for tmp in filter_lines(info, "Subtitle: dvb_teletext").split("\n"): + if self.get_stream_index(tmp): + submap.append(self.get_stream_index(tmp)) + # select audio streams + audiomap = self.__get_audiomap(info) if len(audiomap) == 0: print "No suitable audio stream found, aborting." return None - - self.msg_prepare += "Video Stream selected: Stream #%s\n" % v - - # TODO: Old dreambox images did a file split: .ts .ts.001 .ts.002 etc. + # Old dreambox images did a file split: .ts .ts.001 .ts.002 etc. # Find all these files and join them! inputs = [fn] if os.path.splitext(fn)[1].lower() == '.ts': @@ -237,7 +239,6 @@ fn = "\\'".join(p for p in fpart.split("'")) fn = fn.replace(" ", "\\ ") inputs.append(fn) - #inputs.append(shlex.split(fpart)) if len(inputs) > 1: # use ffmpeg input concat function @@ -255,10 +256,17 @@ idx += 1 cmd = [ - "ffmpeg", + "ffmpeg", "-hide_banner", "-i %s" % fn, - "-map %s" % v, ] + + for tmp in submap: + self.msg_prepare += "Subtitle Stream selected: Stream #%s\n" % tmp + cmd.append("-map %s" % tmp) + + cmd.append("-map %s" % v) + self.msg_prepare += "Video Stream selected: Stream #%s\n" % v + flt = [] crop = self.get_crop_option() if crop: @@ -266,13 +274,15 @@ if self.scaleto_720p: # -2 ensures division by two for codec flt.append("scale='min(1280,iw)':-2'") - self.msg_prepare += "Scaling cropped output stream to 720p\n" + self.msg_prepare += "Scaling output stream to 720p if width >1280\n" if len(flt) > 0: # append video filters cmd.append('-filter:v "%s"' % ",".join(flt)) - for a in audiomap: - self.msg_prepare += "Audio Stream selected: Stream #%s\n" % a - cmd.append("-map %s" % a) + for tmp in audiomap: + self.msg_prepare += "Audio Stream selected: Stream #%s\n" % tmp + cmd.append("-map %s" % tmp) + if len(submap) > 0: + cmd.append("-c:s dvdsub") cmd.extend(self.video_options) cmd.extend(self.audio_options) cmd.append(outfn)