1
0
mirror of https://github.com/l1ving/youtube-dl synced 2025-01-24 07:12:51 +08:00

Support --output-format (and -O)

Allow specifying an output format when using an external downloader,
either through --output-format or -O, in preference to the extractor's
default. This is particularly helpful as -O mkv, to allow Matroska
output from ffmpeg in cases where .mp4 isn't a great answer, such as
while trying to play during the download.
This commit is contained in:
John Hawkinson 2017-11-14 01:57:04 -05:00
parent 5871ebac47
commit a906d47bd2
5 changed files with 22 additions and 3 deletions

View File

@ -253,6 +253,7 @@ class YoutubeDL(object):
Progress hooks are guaranteed to be called at least once Progress hooks are guaranteed to be called at least once
(with status "finished") if the download is successful. (with status "finished") if the download is successful.
merge_output_format: Extension to use when merging formats. merge_output_format: Extension to use when merging formats.
outputformat: Extension and format to use when using an external downloader
fixup: Automatically correct known faults of the file. fixup: Automatically correct known faults of the file.
One of: One of:
- "never": do nothing - "never": do nothing
@ -635,6 +636,8 @@ class YoutubeDL(object):
template_dict['resolution'] = '%sp' % template_dict['height'] template_dict['resolution'] = '%sp' % template_dict['height']
elif template_dict.get('width'): elif template_dict.get('width'):
template_dict['resolution'] = '%dx?' % template_dict['width'] template_dict['resolution'] = '%dx?' % template_dict['width']
if self.params.get('outputformat'):
template_dict['ext'] = self.params.get('outputformat')
sanitize = lambda k, v: sanitize_filename( sanitize = lambda k, v: sanitize_filename(
compat_str(v), compat_str(v),
@ -1864,6 +1867,8 @@ class YoutubeDL(object):
if filename_real_ext == info_dict['ext'] if filename_real_ext == info_dict['ext']
else filename) else filename)
requested_formats = info_dict['requested_formats'] requested_formats = info_dict['requested_formats']
if self.params.get('outputformat'):
info_dict['ext'] = self.params.get('outputformat')
if self.params.get('merge_output_format') is None and not compatible_formats(requested_formats): if self.params.get('merge_output_format') is None and not compatible_formats(requested_formats):
info_dict['ext'] = 'mkv' info_dict['ext'] = 'mkv'
self.report_warning( self.report_warning(

View File

@ -417,6 +417,7 @@ def _real_main(argv=None):
'ffmpeg_location': opts.ffmpeg_location, 'ffmpeg_location': opts.ffmpeg_location,
'hls_prefer_native': opts.hls_prefer_native, 'hls_prefer_native': opts.hls_prefer_native,
'hls_use_mpegts': opts.hls_use_mpegts, 'hls_use_mpegts': opts.hls_use_mpegts,
'outputformat': opts.outputformat,
'external_downloader_args': external_downloader_args, 'external_downloader_args': external_downloader_args,
'postprocessor_args': postprocessor_args, 'postprocessor_args': postprocessor_args,
'cn_verification_proxy': opts.cn_verification_proxy, 'cn_verification_proxy': opts.cn_verification_proxy,

View File

@ -49,6 +49,7 @@ class FileDownloader(object):
external_downloader_args: A list of additional command-line arguments for the external_downloader_args: A list of additional command-line arguments for the
external downloader. external downloader.
hls_use_mpegts: Use the mpegts container for HLS videos. hls_use_mpegts: Use the mpegts container for HLS videos.
outputformat: Output format for downloader to use
Subclasses of this one must re-define the real_download method. Subclasses of this one must re-define the real_download method.
""" """

View File

@ -292,18 +292,26 @@ class FFmpegFD(ExternalFD):
if self.params.get('test', False): if self.params.get('test', False):
args += ['-fs', compat_str(self._TEST_FILE_SIZE)] args += ['-fs', compat_str(self._TEST_FILE_SIZE)]
if protocol in ('m3u8', 'm3u8_native'): if self.params.get('outputformat'):
args += ['-f', EXT_TO_OUT_FORMATS.get(self.params.get('outputformat'),
self.params.get('outputformat'))]
elif protocol in ('m3u8', 'm3u8_native'):
if self.params.get('hls_use_mpegts', False) or tmpfilename == '-': if self.params.get('hls_use_mpegts', False) or tmpfilename == '-':
args += ['-f', 'mpegts'] args += ['-f', 'mpegts']
else: else:
args += ['-f', 'mp4'] args += ['-f', 'mp4']
if (ffpp.basename == 'ffmpeg' and is_outdated_version(ffpp._versions['ffmpeg'], '3.2', False)) and (not info_dict.get('acodec') or info_dict['acodec'].split('.')[0] in ('aac', 'mp4a')):
args += ['-bsf:a', 'aac_adtstoasc']
elif protocol == 'rtmp': elif protocol == 'rtmp':
args += ['-f', 'flv'] args += ['-f', 'flv']
else: else:
args += ['-f', EXT_TO_OUT_FORMATS.get(info_dict['ext'], info_dict['ext'])] args += ['-f', EXT_TO_OUT_FORMATS.get(info_dict['ext'], info_dict['ext'])]
if (protocol in ('m3u8', 'm3u8_native') and
(ffpp.basename == 'ffmpeg' and
is_outdated_version(ffpp._versions['ffmpeg'], '3.2', False)) and
(not info_dict.get('acodec') or
info_dict['acodec'].split('.')[0] in ('aac', 'mp4a'))):
args += ['-bsf:a', 'aac_adtstoasc']
args = [encodeArgument(opt) for opt in args] args = [encodeArgument(opt) for opt in args]
args.append(encodeFilename(ffpp._ffmpeg_filename_argument(tmpfilename), True)) args.append(encodeFilename(ffpp._ffmpeg_filename_argument(tmpfilename), True))

View File

@ -516,6 +516,10 @@ def parseOpts(overrideArguments=None):
'--external-downloader-args', '--external-downloader-args',
dest='external_downloader_args', metavar='ARGS', dest='external_downloader_args', metavar='ARGS',
help='Give these arguments to the external downloader') help='Give these arguments to the external downloader')
downloader.add_option(
'-O', '--output-format',
metavar='FORMAT', dest='outputformat', default='',
help='Ask the downloader to encode the specified video format')
workarounds = optparse.OptionGroup(parser, 'Workarounds') workarounds = optparse.OptionGroup(parser, 'Workarounds')
workarounds.add_option( workarounds.add_option(