CodeVetter · Repo Unpack · Behavior traces
yt-dlp/yt-dlp
Three end-to-end flows were traced in code. Startup: `__main__` -> `main` -> `_real_main` (options, plugins, updater, YoutubeDL init). Primary action: `download` -> `extract_info` -> IE regex match -> `ie.extract` -> `process_ie_result` -> `process_video_result` -> `process_info` -> `dl` -> FileDownloader -> post_process -> archive write. Persistence/self-update: `Updater.query_update` fetches `_update_spec` + `SHA2-256SUMS`, verifies sha256, atomically swaps the executable, and `restart()` re-invokes the original argv.
- Startup trace: `__main__.py` -> `yt_dlp.main()` sets `IN_CLI` -> `_real_main` calls `setproctitle('yt-dlp')` -> `parse_options` (optparse + config files) -> `print_extractor_information` handles `--list-*` -> `plugin_dirs`/`_load_all_plugins` -> `YoutubeDL(ydl_opts)` -> `Updater` if `-U` -> `ydl.download` or `download_with_info_file`.
- YoutubeDL construction order: `__init__` stores params, initializes `_ies`/`_pps`, loads plugins if not loaded (`all_plugins_loaded`), resolves color policy and `_out_files`, applies js_runtimes/remote_components/compat_opts/http_headers, then `print_debug_header` when auto_init.
- Per-URL trace: `download(url_list)` wraps `extract_info` in `__download_wrapper` (per-URL error containment, dump_single_json) -> `extract_info` scans `self._ies` for `ie.suitable(url)` -> `__extract_info` applies header cookies, calls `ie.extract(url)`, adds default extra info, calls `process_ie_result`.
- Inside `ie.extract`: `initialize()` -> `_initialize_pre_login` -> optional `_perform_login(username, password)` from `_get_login_info` -> `_real_initialize` -> `_real_extract(url)`; GeoRestrictedError triggers `__maybe_fake_ip_and_retry` once.
- Video persistence trace: `process_ie_result` (video) -> `process_video_result` -> `process_info` -> `pre_process` PPs -> `prepare_filename`/`_ensure_dir_exists` -> `_write_description`/`_write_subtitles`/`_write_thumbnails` -> `dl()` -> `fd.download` -> `real_download` -> `post_process` PPs -> `record_download_archive`.
- Playlist trace: `process_ie_result` sees `_type` playlist -> `__process_playlist` builds `PlaylistEntries` (lazy iteration) -> `__process_iterable_entry` per entry -> recursive `extract_info` on each entry URL with `extra_info` carrying playlist metadata.
- HTTP request trace: extractor calls `_request_webpage`/`_download_webpage` -> `_create_request` builds a `Request` -> `YoutubeDL.urlopen` sanitizes URL, injects basic auth, cleans proxies/headers -> `RequestDirector.send` -> handlers sorted by preference -> `handler.validate`/`handler.send` -> `Response` returned to extractor for parsing.
- Self-update trace: `Updater.update` -> `query_update` -> `_download_update_spec`/`_process_update_spec` resolve tag -> `_download_asset('SHA2-256SUMS')` yields checksum -> `_download_asset(binary)` -> sha256 compare -> write `.new`, rename current to `.old`, rename `.new` -> `restart()` re-execs `self.cmd` via `Popen.run`.
- Cookie-load trace: `--cookies-from-browser`/`--cookies` -> `YoutubeDL` cookiejar property -> `load_cookies` -> `_parse_browser_specification` -> `extract_cookies_from_browser` decrypts the browser store (AES via `aes.py`, keyrings via secretstorage) -> jar shared with every RequestHandler; saved back on `__exit__` via `save_cookies`.
- Plugin-load trace: each subsystem calls `register_plugin_spec(PluginSpec(module_name, suffix, ...))` which inserts a `PluginFinder` on `sys.meta_path`; `_real_main` calls `_load_all_plugins` -> `load_plugins` iterates `yt_dlp_plugins.<module>` submodules -> classes ending in the suffix are merged (plugins first) into the subsystem's Indirect dict.
- Live-wait trace: for upcoming streams `_wait_for_video` computes a wait from `release_timestamp` (or randomized range), sleeps in a countdown loop, then raises `ReExtractInfo`, which `_handle_extraction_exceptions` catches to re-run the whole extraction.