CodeVetter · Repo Unpack · Behavior traces
ytdl-org/youtube-dl
Three core flows were traced end-to-end: (1) CLI startup from argv to download; (2) a single-video download from URL through extraction, format selection, HTTP download, fixup and postprocessing to the archive write; (3) the YouTube signature-deciphering path that downloads player JS and interprets it with the built-in JSInterpreter. A fourth trace covers self-update.
- Startup trace: `main()` -> `_real_main()` -> compat_register_utf8 + setproctitle -> parseOpts (reads /etc/youtube-dl.conf, user config, argv) -> header/batch-file handling -> option validation (netrc/password conflicts, numeric parsing of --limit-rate/--min-filesize, playlist bounds) -> postprocessor list assembly -> ydl_opts dict -> `with YoutubeDL(ydl_opts) as ydl` -> optional update_self / cache.remove -> ydl.download(all_urls) -> sys.exit(retcode).
- YoutubeDL init trace: __init__ stores params, creates Cache, loads header cookies, warns on deprecated params, optionally spawns bidiv/fribidi for --bidi-workaround, then _setup_opener builds cookie jar (loading --cookies file), proxy handler, HTTPS/HTTP handlers, redirect handler and disables file://; auto_init then prints debug header and registers all extractor classes plus configured postprocessors and progress hooks, finishing with register_socks_protocols.
- Download dispatch trace: download(url_list) -> extract_info -> ie.suitable(url) scan -> __extract_info (wrapped by __handle_extraction_exceptions) -> ie.extract(url) -> _real_extract -> process_ie_result -> dispatch on _type; for 'video' -> process_video_result -> format selection -> process_info -> dl() -> get_suitable_downloader(info) -> fd.download(name, info) -> real_download.
- Playlist trace: process_ie_result sees _type playlist -> __process_playlist computes entries (list slice, PagedList.getslice, or islice over iterables, honoring --playlist-items) -> optional reverse/shuffle -> per entry: _match_entry(incomplete) filter -> __process_iterable_entry -> process_ie_result (recursion back into the same dispatch).
- HTTP file download trace: FileDownloader.download checks overwrite/resume preconditions and applies randomized sleep_interval -> HttpFD.real_download -> establish_connection() (sanitized_Request with Range header, Content-Range validation, 416 fallback) -> download() loop: read block -> sanitize_open just-in-time -> stream.write -> slow_down rate limit -> _hook_progress -> loop until data_len -> try_rename .part -> try_utime -> 'finished' hook; errors route through RetryDownload/NextFragment/SucceedDownload control-flow exceptions.
- YouTube signature trace: _decrypt_signature -> _cached(_extract_signature_function) -> filesystem cache 'sigfuncs' (keyed by player_url + signature-shape id) -> on miss _load_player downloads player JS -> _parse_sig_js regex-locates the sig function -> JSInterpreter.extract_function_from_code produces a Python callable -> the result is reduced to a char-permutation cache_spec and cached; _decrypt_nsig does the analogous flow for the throttling 'n' parameter.
- Post-download trace: on dl() success, process_info applies fixup policy (FFmpegFixupStretchedPP for stretched_ratio, FFmpegFixupM4aPP for m4a_dash, FFmpegFixupM3u8PP for native HLS AAC) -> post_process runs __postprocessors then self._pps -> each pp.run returns files_to_delete which are removed unless keepvideo -> record_download_archive appends `extractor id` -> MaxDownloadsReached checked.
- Self-update trace: update_self refuses non-zip/non-frozen installs -> GET https://yt-dl.org/update/LATEST_VERSION -> GET versions.json -> rsa_verify(json, signature, pinned UPDATES_RSA_KEY) -> sha256 the downloaded exe/bin blob -> write alongside the running binary (Windows: write .new + a youtube-dl-updater.bat that moves it after exit).
- Error/abort trace: extraction errors funnel through __handle_extraction_exceptions (GeoRestrictedError gets a VPN hint, ExtractorError is reported, unexpected exceptions re-raise unless --ignore-errors); DownloadError propagates to main() -> sys.exit(1); MaxDownloadsReached exits 101; KeyboardInterrupt exits with an interrupted message.