From 1605371fcb20d04b3a30c625ded906bf2ded944d Mon Sep 17 00:00:00 2001 From: Andrei Troie Date: Fri, 26 Dec 2014 15:51:24 +0200 Subject: [PATCH 1/2] Added a workaround option called fallback_mkv that, when merging separately downloaded video & audio that can't fit in the same container (e.g. webm video & m4a audio), tries instead to output to an mkv container --- youtube_dl/__init__.py | 1 + youtube_dl/options.py | 5 +++++ youtube_dl/postprocessor/ffmpeg.py | 21 +++++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index e79320323..022800aa1 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -324,6 +324,7 @@ def _real_main(argv=None): 'encoding': opts.encoding, 'exec_cmd': opts.exec_cmd, 'extract_flat': opts.extract_flat, + 'fallback_mkv': opts.fallback_mkv, 'postprocessors': postprocessors, } diff --git a/youtube_dl/options.py b/youtube_dl/options.py index 21c452141..4351ec423 100644 --- a/youtube_dl/options.py +++ b/youtube_dl/options.py @@ -385,6 +385,11 @@ def parseOpts(overrideArguments=None): '--bidi-workaround', dest='bidi_workaround', action='store_true', help='Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH') + workarounds.add_option( + '--fallback-mkv', + dest='fallback_mkv', action='store_true', + help='If downloading separate vieo and audio (e.g. -f bestvideo+bestaudio) and merging fails, try to use an mkv container' + ) verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options') verbosity.add_option( diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 048525efc..2d9fcf52e 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -516,13 +516,30 @@ class FFmpegMetadataPP(FFmpegPostProcessor): os.rename(encodeFilename(temp_filename), encodeFilename(filename)) return True, info - class FFmpegMergerPP(FFmpegPostProcessor): def run(self, info): filename = info['filepath'] args = ['-c', 'copy', '-map', '0:v:0', '-map', '1:a:0', '-shortest'] self._downloader.to_screen('[ffmpeg] Merging formats into "%s"' % filename) - self.run_ffmpeg_multiple_files(info['__files_to_merge'], filename, args) + #first attempt to merge them as normal but if a merge error happens attempt to eat it and try again with mkv output + #attempt to merge the files into the filename that the upstream methods have determined + #there's little point to try to guess from the start which video format will be compatible with which audio + #if the standard merge fails, fallback to mkv instead + try: + self.run_ffmpeg_multiple_files(info['__files_to_merge'], filename, args) + except FFmpegPostProcessorError as fpe: + if self._downloader.params.get('fallback_mkv', False) and "incorrect codec parameters" in fpe.msg.lower(): + warning = "Could not merge to %s format, ffmpeg said: '%s'\nAttempting to merge to mkv instead" % (info['ext'], fpe.msg) + self._downloader.report_warning(warning) + fname, ext = os.path.splitext(filename) + mkv_filename = fname + ".mkv" + self._downloader.to_screen('[ffmpeg] Merging formats into "%s"' % mkv_filename) + self.run_ffmpeg_multiple_files(info['__files_to_merge'], mkv_filename, args) + os.remove(encodeFilename(filename)) + info['filepath'] = mkv_filename + info['ext'] = 'mkv' + else: + raise fpe return True, info From 6e11a64452150346a1ababd17486d5e3e47fef19 Mon Sep 17 00:00:00 2001 From: Andrei Troie Date: Sat, 27 Dec 2014 02:29:19 +0200 Subject: [PATCH 2/2] Changed comments --- youtube_dl/postprocessor/ffmpeg.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 2d9fcf52e..5ebf0e016 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -521,10 +521,9 @@ class FFmpegMergerPP(FFmpegPostProcessor): filename = info['filepath'] args = ['-c', 'copy', '-map', '0:v:0', '-map', '1:a:0', '-shortest'] self._downloader.to_screen('[ffmpeg] Merging formats into "%s"' % filename) - #first attempt to merge them as normal but if a merge error happens attempt to eat it and try again with mkv output #attempt to merge the files into the filename that the upstream methods have determined #there's little point to try to guess from the start which video format will be compatible with which audio - #if the standard merge fails, fallback to mkv instead + #so instead just try merging with what we have and see what happens try: self.run_ffmpeg_multiple_files(info['__files_to_merge'], filename, args) except FFmpegPostProcessorError as fpe: