From f8f9b7778b8424984fc2f8313b0fda1746a92ec5 Mon Sep 17 00:00:00 2001 From: Mort Yao Date: Sun, 3 Aug 2014 21:05:51 +0200 Subject: [PATCH] use concat demuxer on FFmpeg >= 1.1, fix #324 --- src/you_get/processor/ffmpeg.py | 102 +++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 23 deletions(-) diff --git a/src/you_get/processor/ffmpeg.py b/src/you_get/processor/ffmpeg.py index e2106f60..019efe03 100644 --- a/src/you_get/processor/ffmpeg.py +++ b/src/you_get/processor/ffmpeg.py @@ -9,58 +9,78 @@ def get_usable_ffmpeg(cmd): out, err = p.communicate() vers = str(out, 'utf-8').split('\n')[0].split(' ') assert (vers[0] == 'ffmpeg' and vers[2][0] > '0') or (vers[0] == 'avconv') - return cmd + return cmd, [int(i) for i in vers[2].split('.')] except: return None -FFMPEG = get_usable_ffmpeg('ffmpeg') or get_usable_ffmpeg('avconv') +FFMPEG, FFMPEG_VERSION = get_usable_ffmpeg('ffmpeg') or get_usable_ffmpeg('avconv') def has_ffmpeg_installed(): return FFMPEG is not None -def ffmpeg_convert_ts_to_mkv(files, output = 'output.mkv'): +def ffmpeg_convert_ts_to_mkv(files, output='output.mkv'): for file in files: if os.path.isfile(file): params = [FFMPEG, '-i'] params.append(file) params.append(output) subprocess.call(params) - + return -def ffmpeg_concat_mp4_to_mpg(files, output = 'output.mpg'): +def ffmpeg_concat_mp4_to_mpg(files, output='output.mpg'): + # Use concat demuxer on FFmpeg >= 1.1 + if FFMPEG == 'ffmpeg' and (FFMPEG_VERSION[0] >= 2 or (FFMPEG_VERSION[0] == 1 and FFMPEG_VERSION[1] >= 1)): + concat_list = open(output + '.txt', 'w') + for file in files: + if os.path.isfile(file): + concat_list.write("file '%s'\n" % file) + concat_list.close() + + params = [FFMPEG, '-f', 'concat', '-i'] + params.append(output + '.txt') + params += ['-c', 'copy', output] + + if subprocess.call(params) == 0: + os.remove(output + '.txt') + return True + else: + raise + for file in files: if os.path.isfile(file): params = [FFMPEG, '-i'] params.append(file) params.append(file + '.mpg') subprocess.call(params) - + inputs = [open(file + '.mpg', 'rb') for file in files] with open(output + '.mpg', 'wb') as o: for input in inputs: o.write(input.read()) - + params = [FFMPEG, '-i'] params.append(output + '.mpg') params += ['-vcodec', 'copy', '-acodec', 'copy'] params.append(output) subprocess.call(params) - - for file in files: - os.remove(file + '.mpg') - os.remove(output + '.mpg') - - return -def ffmpeg_concat_ts_to_mkv(files, output = 'output.mkv'): + if subprocess.call(params) == 0: + for file in files: + os.remove(file + '.mpg') + os.remove(output + '.mpg') + return True + else: + raise + +def ffmpeg_concat_ts_to_mkv(files, output='output.mkv'): params = [FFMPEG, '-isync', '-i'] params.append('concat:') for file in files: if os.path.isfile(file): params[-1] += file + '|' params += ['-f', 'matroska', '-c', 'copy', output] - + try: if subprocess.call(params) == 0: return True @@ -69,16 +89,34 @@ def ffmpeg_concat_ts_to_mkv(files, output = 'output.mkv'): except: return False -def ffmpeg_concat_flv_to_mp4(files, output = 'output.mp4'): +def ffmpeg_concat_flv_to_mp4(files, output='output.mp4'): + # Use concat demuxer on FFmpeg >= 1.1 + if FFMPEG == 'ffmpeg' and (FFMPEG_VERSION[0] >= 2 or (FFMPEG_VERSION[0] == 1 and FFMPEG_VERSION[1] >= 1)): + concat_list = open(output + '.txt', 'w') + for file in files: + if os.path.isfile(file): + concat_list.write("file '%s'\n" % file) + concat_list.close() + + params = [FFMPEG, '-f', 'concat', '-i'] + params.append(output + '.txt') + params += ['-c', 'copy', output] + + if subprocess.call(params) == 0: + os.remove(output + '.txt') + return True + else: + raise + for file in files: if os.path.isfile(file): params = [FFMPEG, '-i'] params.append(file) params += ['-map', '0', '-c', 'copy', '-f', 'mpegts', '-bsf:v', 'h264_mp4toannexb'] params.append(file + '.ts') - + subprocess.call(params) - + params = [FFMPEG, '-i'] params.append('concat:') for file in files: @@ -89,7 +127,7 @@ def ffmpeg_concat_flv_to_mp4(files, output = 'output.mp4'): params += ['-c', 'copy', output] else: params += ['-c', 'copy', '-absf', 'aac_adtstoasc', output] - + if subprocess.call(params) == 0: for file in files: os.remove(file + '.ts') @@ -97,16 +135,34 @@ def ffmpeg_concat_flv_to_mp4(files, output = 'output.mp4'): else: raise -def ffmpeg_concat_mp4_to_mp4(files, output = 'output.mp4'): +def ffmpeg_concat_mp4_to_mp4(files, output='output.mp4'): + # Use concat demuxer on FFmpeg >= 1.1 + if FFMPEG == 'ffmpeg' and (FFMPEG_VERSION[0] >= 2 or (FFMPEG_VERSION[0] == 1 and FFMPEG_VERSION[1] >= 1)): + concat_list = open(output + '.txt', 'w') + for file in files: + if os.path.isfile(file): + concat_list.write("file '%s'\n" % file) + concat_list.close() + + params = [FFMPEG, '-f', 'concat', '-i'] + params.append(output + '.txt') + params += ['-c', 'copy', output] + + if subprocess.call(params) == 0: + os.remove(output + '.txt') + return True + else: + raise + for file in files: if os.path.isfile(file): params = [FFMPEG, '-i'] params.append(file) params += ['-c', 'copy', '-f', 'mpegts', '-bsf:v', 'h264_mp4toannexb'] params.append(file + '.ts') - + subprocess.call(params) - + params = [FFMPEG, '-i'] params.append('concat:') for file in files: @@ -117,7 +173,7 @@ def ffmpeg_concat_mp4_to_mp4(files, output = 'output.mp4'): params += ['-c', 'copy', output] else: params += ['-c', 'copy', '-absf', 'aac_adtstoasc', output] - + if subprocess.call(params) == 0: for file in files: os.remove(file + '.ts')