}
else:
params = self.params
- fd = get_suitable_downloader(info, params)(self, params)
+ fd = get_suitable_downloader(info, params, to_stdout=(name == '-'))(self, params)
if not test:
for ph in self._progress_hooks:
fd.add_progress_hook(ph)
'Requested formats are incompatible for merge and will be merged into mkv.')
def correct_ext(filename):
+ if filename == '-':
+ return filename
filename_real_ext = os.path.splitext(filename)[1][1:]
filename_wo_ext = (
os.path.splitext(filename)[0]
directly_mergable = FFmpegFD.can_merge_formats(info_dict)
if dl_filename is not None:
pass
- elif (directly_mergable and get_suitable_downloader(info_dict, self.params) == FFmpegFD):
+ elif (directly_mergable and get_suitable_downloader(
+ info_dict, self.params, to_stdout=(temp_filename== '-')) == FFmpegFD):
info_dict['url'] = '\n'.join(f['url'] for f in requested_formats)
success, real_download = self.dl(temp_filename, info_dict)
info_dict['__real_download'] = real_download
'You have requested merging of multiple formats but ffmpeg is not installed. '
'The formats won\'t be merged.')
+ if temp_filename == '-':
+ reason = ('using a downloader other than ffmpeg' if directly_mergable
+ else 'but the formats are incompatible for simultaneous download' if merger.available
+ else 'but ffmpeg is not installed')
+ self.report_warning(
+ f'You have requested downloading multiple formats to stdout {reason}. '
+ 'The formats will be streamed one after the other')
+ fname = temp_filename
for f in requested_formats:
new_info = dict(info_dict)
del new_info['requested_formats']
new_info.update(f)
- fname = prepend_extension(temp_filename, 'f%s' % f['format_id'], new_info['ext'])
- if not self._ensure_dir_exists(fname):
- return
- downloaded.append(fname)
+ if temp_filename != '-':
+ fname = prepend_extension(temp_filename, 'f%s' % f['format_id'], new_info['ext'])
+ if not self._ensure_dir_exists(fname):
+ return
+ downloaded.append(fname)
partial_success, real_download = self.dl(fname, new_info)
info_dict['__real_download'] = info_dict['__real_download'] or real_download
success = success and partial_success
)
-def get_suitable_downloader(info_dict, params={}, default=NO_DEFAULT, protocol=None):
+def get_suitable_downloader(info_dict, params={}, default=NO_DEFAULT, protocol=None, to_stdout=False):
info_dict['protocol'] = determine_protocol(info_dict)
info_copy = info_dict.copy()
if protocol:
info_copy['protocol'] = protocol
+ info_copy['to_stdout'] = to_stdout
return _get_suitable_downloader(info_copy, params, default)
external_downloader = (
downloaders if isinstance(downloaders, compat_str) or downloaders is None
else downloaders.get(shorten_protocol_name(protocol, True), downloaders.get('default')))
- if external_downloader and external_downloader.lower() == 'native':
- external_downloader = 'native'
- if external_downloader not in (None, 'native'):
+ if external_downloader is None:
+ if info_dict['to_stdout'] and FFmpegFD.can_merge_formats(info_dict, params):
+ return FFmpegFD
+ elif external_downloader.lower() != 'native':
ed = get_external_downloader(external_downloader)
if ed.can_download(info_dict, external_downloader):
return ed
if protocol in ('m3u8', 'm3u8_native'):
if info_dict.get('is_live'):
return FFmpegFD
- elif external_downloader == 'native':
+ elif (external_downloader or '').lower() == 'native':
return HlsFD
- elif get_suitable_downloader(info_dict, params, None, protocol='m3u8_frag_urls'):
+ elif get_suitable_downloader(
+ info_dict, params, None, protocol='m3u8_frag_urls', to_stdout=info_dict['to_stdout']):
return HlsFD
elif params.get('hls_prefer_native') is True:
return HlsFD
fragments = info_dict['fragments'][:1] if self.params.get(
'test', False) else info_dict['fragments']
- real_downloader = get_suitable_downloader(info_dict, self.params, None, protocol='dash_frag_urls')
+ real_downloader = get_suitable_downloader(
+ info_dict, self.params, None, protocol='dash_frag_urls', to_stdout=(filename== '-'))
ctx = {
'filename': filename,
class ExternalFD(FileDownloader):
SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps')
+ can_download_to_stdout = False
def real_download(self, filename, info_dict):
self.report_destination(filename)
@classmethod
def supports(cls, info_dict):
- return info_dict['protocol'] in cls.SUPPORTED_PROTOCOLS
+ return (
+ (cls.can_download_to_stdout or not info_dict.get('to_stdout'))
+ and info_dict['protocol'] in cls.SUPPORTED_PROTOCOLS)
@classmethod
def can_download(cls, info_dict, path=None):
class FFmpegFD(ExternalFD):
SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'm3u8', 'm3u8_native', 'rtsp', 'rtmp', 'rtmp_ffmpeg', 'mms')
+ can_download_to_stdout = True
@classmethod
def available(cls, path=None):
if is_webvtt:
real_downloader = None # Packing the fragments is not currently supported for external downloader
else:
- real_downloader = get_suitable_downloader(info_dict, self.params, None, protocol='m3u8_frag_urls')
+ real_downloader = get_suitable_downloader(
+ info_dict, self.params, None, protocol='m3u8_frag_urls', to_stdout=(filename== '-'))
if real_downloader and not real_downloader.supports_manifest(s):
real_downloader = None
if real_downloader: