mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-12-22 06:00:00 +00:00
[downloader/ffmpeg] Improve simultaneous download and merge
This commit is contained in:
parent
975a0d0df9
commit
c111cefa5d
4 changed files with 18 additions and 12 deletions
|
@ -1179,6 +1179,8 @@ # FORMAT SELECTION
|
||||||
By default, yt-dlp tries to download the best available quality if you **don't** pass any options.
|
By default, yt-dlp tries to download the best available quality if you **don't** pass any options.
|
||||||
This is generally equivalent to using `-f bestvideo*+bestaudio/best`. However, if multiple audiostreams is enabled (`--audio-multistreams`), the default format changes to `-f bestvideo+bestaudio/best`. Similarly, if ffmpeg is unavailable, or if you use yt-dlp to stream to `stdout` (`-o -`), the default becomes `-f best/bestvideo+bestaudio`.
|
This is generally equivalent to using `-f bestvideo*+bestaudio/best`. However, if multiple audiostreams is enabled (`--audio-multistreams`), the default format changes to `-f bestvideo+bestaudio/best`. Similarly, if ffmpeg is unavailable, or if you use yt-dlp to stream to `stdout` (`-o -`), the default becomes `-f best/bestvideo+bestaudio`.
|
||||||
|
|
||||||
|
**Deprecation warning**: Latest versions of yt-dlp can stream multiple formats to the stdout simultaneously using ffmpeg. So, in future versions, the default for this will be set to `-f bv*+ba/b` similar to normal downloads. If you want to preserve the `-f b/bv+ba` setting, it is recommended to explicitly specify it in the configuration options.
|
||||||
|
|
||||||
The general syntax for format selection is `-f FORMAT` (or `--format FORMAT`) where `FORMAT` is a *selector expression*, i.e. an expression that describes format or formats you would like to download.
|
The general syntax for format selection is `-f FORMAT` (or `--format FORMAT`) where `FORMAT` is a *selector expression*, i.e. an expression that describes format or formats you would like to download.
|
||||||
|
|
||||||
**tl;dr:** [navigate me to examples](#format-selection-examples).
|
**tl;dr:** [navigate me to examples](#format-selection-examples).
|
||||||
|
|
|
@ -2744,14 +2744,9 @@ def correct_ext(filename, ext=new_ext):
|
||||||
dl_filename = existing_file(full_filename, temp_filename)
|
dl_filename = existing_file(full_filename, temp_filename)
|
||||||
info_dict['__real_download'] = False
|
info_dict['__real_download'] = False
|
||||||
|
|
||||||
_protocols = set(determine_protocol(f) for f in requested_formats)
|
|
||||||
if len(_protocols) == 1: # All requested formats have same protocol
|
|
||||||
info_dict['protocol'] = _protocols.pop()
|
|
||||||
directly_mergable = FFmpegFD.can_merge_formats(info_dict, self.params)
|
|
||||||
if dl_filename is not None:
|
if dl_filename is not None:
|
||||||
self.report_file_already_downloaded(dl_filename)
|
self.report_file_already_downloaded(dl_filename)
|
||||||
elif (directly_mergable and get_suitable_downloader(
|
elif get_suitable_downloader(info_dict, self.params, to_stdout=temp_filename == '-'):
|
||||||
info_dict, self.params, to_stdout=(temp_filename == '-')) == FFmpegFD):
|
|
||||||
info_dict['url'] = '\n'.join(f['url'] for f in requested_formats)
|
info_dict['url'] = '\n'.join(f['url'] for f in requested_formats)
|
||||||
success, real_download = self.dl(temp_filename, info_dict)
|
success, real_download = self.dl(temp_filename, info_dict)
|
||||||
info_dict['__real_download'] = real_download
|
info_dict['__real_download'] = real_download
|
||||||
|
@ -2769,7 +2764,7 @@ def correct_ext(filename, ext=new_ext):
|
||||||
'The formats won\'t be merged.')
|
'The formats won\'t be merged.')
|
||||||
|
|
||||||
if temp_filename == '-':
|
if temp_filename == '-':
|
||||||
reason = ('using a downloader other than ffmpeg' if directly_mergable
|
reason = ('using a downloader other than ffmpeg' if FFmpegFD.can_merge_formats(info_dict)
|
||||||
else 'but the formats are incompatible for simultaneous download' if merger.available
|
else 'but the formats are incompatible for simultaneous download' if merger.available
|
||||||
else 'but ffmpeg is not installed')
|
else 'but ffmpeg is not installed')
|
||||||
self.report_warning(
|
self.report_warning(
|
||||||
|
|
|
@ -10,10 +10,15 @@
|
||||||
def get_suitable_downloader(info_dict, params={}, default=NO_DEFAULT, protocol=None, to_stdout=False):
|
def get_suitable_downloader(info_dict, params={}, default=NO_DEFAULT, protocol=None, to_stdout=False):
|
||||||
info_dict['protocol'] = determine_protocol(info_dict)
|
info_dict['protocol'] = determine_protocol(info_dict)
|
||||||
info_copy = info_dict.copy()
|
info_copy = info_dict.copy()
|
||||||
if protocol:
|
|
||||||
info_copy['protocol'] = protocol
|
|
||||||
info_copy['to_stdout'] = to_stdout
|
info_copy['to_stdout'] = to_stdout
|
||||||
return _get_suitable_downloader(info_copy, params, default)
|
|
||||||
|
downloaders = [_get_suitable_downloader(info_copy, proto, params, default)
|
||||||
|
for proto in (protocol or info_copy['protocol']).split('+')]
|
||||||
|
if set(downloaders) == {FFmpegFD} and FFmpegFD.can_merge_formats(info_copy, params):
|
||||||
|
return FFmpegFD
|
||||||
|
elif len(downloaders) == 1:
|
||||||
|
return downloaders[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Some of these require get_suitable_downloader
|
# Some of these require get_suitable_downloader
|
||||||
|
@ -72,7 +77,7 @@ def shorten_protocol_name(proto, simplify=False):
|
||||||
return short_protocol_names.get(proto, proto)
|
return short_protocol_names.get(proto, proto)
|
||||||
|
|
||||||
|
|
||||||
def _get_suitable_downloader(info_dict, params, default):
|
def _get_suitable_downloader(info_dict, protocol, params, default):
|
||||||
"""Get the downloader class that can handle the info dict."""
|
"""Get the downloader class that can handle the info dict."""
|
||||||
if default is NO_DEFAULT:
|
if default is NO_DEFAULT:
|
||||||
default = HttpFD
|
default = HttpFD
|
||||||
|
@ -80,7 +85,7 @@ def _get_suitable_downloader(info_dict, params, default):
|
||||||
# if (info_dict.get('start_time') or info_dict.get('end_time')) and not info_dict.get('requested_formats') and FFmpegFD.can_download(info_dict):
|
# if (info_dict.get('start_time') or info_dict.get('end_time')) and not info_dict.get('requested_formats') and FFmpegFD.can_download(info_dict):
|
||||||
# return FFmpegFD
|
# return FFmpegFD
|
||||||
|
|
||||||
protocol = info_dict['protocol']
|
info_dict['protocol'] = protocol
|
||||||
downloaders = params.get('external_downloader')
|
downloaders = params.get('external_downloader')
|
||||||
external_downloader = (
|
external_downloader = (
|
||||||
downloaders if isinstance(downloaders, compat_str) or downloaders is None
|
downloaders if isinstance(downloaders, compat_str) or downloaders is None
|
||||||
|
|
|
@ -327,6 +327,10 @@ def available(cls, path=None):
|
||||||
# Fixme: This may be wrong when --ffmpeg-location is used
|
# Fixme: This may be wrong when --ffmpeg-location is used
|
||||||
return FFmpegPostProcessor().available
|
return FFmpegPostProcessor().available
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def supports(cls, info_dict):
|
||||||
|
return all(proto in cls.SUPPORTED_PROTOCOLS for proto in info_dict['protocol'].split('+'))
|
||||||
|
|
||||||
def on_process_started(self, proc, stdin):
|
def on_process_started(self, proc, stdin):
|
||||||
""" Override this in subclasses """
|
""" Override this in subclasses """
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in a new issue