import time
from .fragment import FragmentFD
-from ..compat import (
- compat_setenv,
- compat_str,
-)
-from ..postprocessor.ffmpeg import FFmpegPostProcessor, EXT_TO_OUT_FORMATS
+from ..compat import compat_setenv, compat_str
+from ..postprocessor.ffmpeg import EXT_TO_OUT_FORMATS, FFmpegPostProcessor
from ..utils import (
+ Popen,
+ _configuration_args,
+ check_executable,
classproperty,
+ cli_bool_option,
cli_option,
cli_valueless_option,
- cli_bool_option,
- _configuration_args,
determine_ext,
- encodeFilename,
encodeArgument,
+ encodeFilename,
handle_youtubedl_headers,
- check_executable,
- Popen,
remove_end,
+ traverse_obj,
)
fragment_filename = '%s-Frag%d' % (os.path.basename(tmpfilename), frag_index)
url_list.append('%s\n\tout=%s' % (fragment['url'], fragment_filename))
stream, _ = self.sanitize_open(url_list_file, 'wb')
- stream.write('\n'.join(url_list).encode('utf-8'))
+ stream.write('\n'.join(url_list).encode())
stream.close()
cmd += ['-i', url_list_file]
else:
if not self.params.get('verbose'):
args += ['-hide_banner']
- args += info_dict.get('_ffmpeg_args', [])
+ args += traverse_obj(info_dict, ('downloader_options', 'ffmpeg_args'), default=[])
- # This option exists only for compatibility. Extractors should use `_ffmpeg_args` instead
+ # These exists only for compatibility. Extractors should use
+ # info_dict['downloader_options']['ffmpeg_args'] instead
+ args += info_dict.get('_ffmpeg_args') or []
seekable = info_dict.get('_seekable')
if seekable is not None:
# setting -seekable prevents ffmpeg from guessing if the server
# if end_time:
# args += ['-t', compat_str(end_time - start_time)]
- if info_dict.get('http_headers') is not None and re.match(r'^https?://', urls[0]):
- # Trailing \r\n after each HTTP header is important to prevent warning from ffmpeg/avconv:
- # [http @ 00000000003d2fa0] No trailing CRLF found in HTTP header.
- headers = handle_youtubedl_headers(info_dict['http_headers'])
- args += [
+ http_headers = None
+ if info_dict.get('http_headers'):
+ youtubedl_headers = handle_youtubedl_headers(info_dict['http_headers'])
+ http_headers = [
+ # Trailing \r\n after each HTTP header is important to prevent warning from ffmpeg/avconv:
+ # [http @ 00000000003d2fa0] No trailing CRLF found in HTTP header.
'-headers',
- ''.join(f'{key}: {val}\r\n' for key, val in headers.items())]
+ ''.join(f'{key}: {val}\r\n' for key, val in youtubedl_headers.items())
+ ]
env = None
proxy = self.params.get('proxy')
args += ['-rtmp_conn', conn]
for i, url in enumerate(urls):
+ # We need to specify headers for each http input stream
+ # otherwise, it will only be applied to the first.
+ # https://github.com/yt-dlp/yt-dlp/issues/2696
+ if http_headers is not None and re.match(r'^https?://', url):
+ args += http_headers
args += self._configuration_args((f'_i{i + 1}', '_i')) + ['-i', url]
args += ['-c', 'copy']