Skip to main content

fast-dlp

fast-dlp

Быстрая альтернатива yt-dlp. Чистый Python, без зависимостей.
YouTube · Spotify · Яндекс Музыка · SoundCloud · TikTok · VK · Pinterest · Pornhub · Steam Workshop

  • Скорость: 4K-видео на 345 МиБ скачивается за 7.3 с (~47 МиБ/с).
  • Без ffmpeg: видео и звук склеиваются встроенным муксером меньше чем за секунду.
  • Музыка: теги, обложки, тексты песен и ReplayGain пишутся сами.
  • Поиск: один запрос сразу по всем источникам.
  • Экран выбора: треки отмечаются в терминале, качаются параллельно.

Установка

Нужен Python 3.9+.

pip install fast-dlp

Обновление: pip install -U fast-dlp. Чтобы команда была изолирована от остальных пакетов, можно поставить через pipx: pipx install fast-dlp.

Из исходников:

git clone https://github.com/valkdzx/fast-dlp
cd fast-dlp
pip install -e .

Без установки: py -m fast_dlp ... или fast-dlp.cmd ... из папки проекта.

Необязательные программы:

  • ffmpeg — только для MP3 и смешанных контейнеров;
  • Deno, Node.js или Bun — только для возрастных видео через login.

Примеры

fast-dlp https://youtu.be/VIDEO_ID                  # лучшее видео + звук
fast-dlp https://youtu.be/VIDEO_ID -q 1080          # не выше 1080p
fast-dlp https://youtu.be/VIDEO_ID -x               # только звук
fast-dlp https://youtu.be/VIDEO_ID --audio-format mp3
fast-dlp https://youtu.be/VIDEO_ID -F               # список форматов
fast-dlp https://youtu.be/VIDEO_ID -f 137+140       # конкретные itag
fast-dlp https://youtu.be/VIDEO_ID -g               # вывести прямые ссылки
fast-dlp https://open.spotify.com/track/TRACK_ID    # трек Spotify
fast-dlp https://open.spotify.com/album/ALBUM_ID    # альбом, экран выбора
fast-dlp "https://www.youtube.com/playlist?list=PLAYLIST_ID"
fast-dlp исполнитель - название                     # поиск по всем источникам
fast-dlp URL -N 32 -P D:\Video -o "{author} - {title}.{ext}"
fast-dlp web                                        # сайт-загрузчик на http://127.0.0.1:8000

Сайт-загрузчик

fast-dlp web                         # http://127.0.0.1:8000
fast-dlp web --host 0.0.0.0 --port 8080   # доступ из локальной сети

Чёрная страница: вставляете ссылку на видео, выбираете параметры, нажимаете «Скачать».

Параметры:

  • что скачать: видео со звуком, только звук или только видео;
  • формат: MP4 (H.264 / AV1 + AAC) или WebM (VP9 + Opus); для звука M4A, Opus или MP3;
  • качество от 144p до 4K, с размером каждого варианта;
  • кодек и битрейт MP3;
  • отрывок по времени;
  • теги, обложка, ReplayGain;
  • шаблон имени файла;
  • число соединений с YouTube.

Сервер ничего не сохраняет. Файл передаётся потоком (HTTP streaming):

  1. Сначала скачиваются только заголовки и оглавления форматов (sidx / Cues). По ним заранее рассчитывается весь файл: новый заголовок, порядок фрагментов и точный размер, поэтому браузер сразу видит Content-Length и показывает прогресс.
  2. Фрагменты качаются с googlevideo параллельно, в ограниченном окне памяти (~80 МиБ на загрузку). На лету правятся номера дорожек и времена, и всё сразу пишется в ответ. Результат побайтно совпадает с файлом, который склеил бы встроенный муксер.
  3. MP3 кодируется ffmpeg прямо из потока и передаётся частями (Transfer-Encoding: chunked).

Подтверждение доставки. После последнего байта сервер закрывает свою сторону соединения и ждёт, пока браузер закроет свою. Браузер закрывает соединение только после того, как прочитал всё, поэтому файл помечается «Доставлено» только при настоящем подтверждении.

Другие исходы:

  • сброс соединения означает «Прервано», и ту же ссылку можно открыть снова;
  • если браузер молчит 60 с, статус будет «Отправлено».

Ссылка на скачивание одноразовая и живёт час. Страница следит за статусом через /api/status.

Запрос Что делает
GET /api/info?url= название, длительность, все форматы с размерами
POST /api/jobs параметры → токен, имя файла, точный размер
GET /dl/<токен> сам файл, потоком
GET /api/status?t=a,b состояние загрузок: передано байт, скорость, статус

Замер: 4K-видео на 232 МиБ доходит до браузера за 3.8 с (~60 МиБ/с).

Почему быстро

  • Один запрос к API. Нет загрузки watch-страницы и base.js: InnerTube-клиент VISIONOS отдаёт прямые ссылки (до 4K, без подписи и без n-параметра) примерно за 0.25 с.
  • Параллельная загрузка. Файл качается в 16 потоков, у каждого постоянное HTTPS-соединение.
  • Куски под скорость сети. Каждое соединение замеряет свою скорость и берёт следующий кусок примерно на 2 секунды загрузки:
    • на 60 Мбит/с это ~1 МиБ;
    • на гигабите 8 МиБ, это потолок: googlevideo режет скорость на диапазонах больше ~10 МБ;
    • к концу файла куски дробятся, чтобы все соединения закончили вместе.
  • Сразу в готовый файл. Видео и звук YouTube качаются не в .part-файлы с последующей склейкой. По оглавлениям форматов (sidx / Cues) итоговый файл рассчитывается заранее, и каждый кусок пишется прямо на своё место. После загрузки правятся только заголовки фрагментов (несколько КиБ). Каждый байт скачивается и пишется на диск один раз.
  • Без записи нулей. Windows при увеличении файла физически пишет нули: 3 ГБ нулей перед загрузкой выглядят как «фоновая закачка». Файл создаётся разреженным (NTFS sparse), и его размер задаётся мгновенно.
  • MP3 без промежуточного файла. Звук идёт из сети прямо в ffmpeg.
  • Без перезапуска. Протухшую ссылку (HTTP 403) обновляет новый запрос к /player, и загрузка продолжается с того же места.

IPv4 и IPv6

YouTube проверяет каждый адрес отдельно. У домашнего подключения общий IPv4-адрес, а у каждого устройства свой IPv6, и Windows по умолчанию предпочитает IPv6. Если на IPv6-адрес YouTube отвечает bot-check («Sign in to confirm you're not a bot»), fast-dlp сам переключает весь процесс на IPv4 и запоминает это на 6 часов (%LOCALAPPDATA%\fast-dlp\route.json). Переключается весь процесс сразу, потому что ссылки на поток привязаны к адресу, с которого их запросили. Флаги -4 / -6 задают семейство адресов вручную.

Возрастные видео

Если VISIONOS отвечает LOGIN_REQUIRED, fast-dlp переходит на клиент TVHTML5 (Tizen, версия 5.<дата>) с OAuth-токеном аккаунта:

  • client_id и client_secret берутся из бандла youtube.com/tv (кэш 6 ч);
  • refresh token меняется на access token (кэш до истечения срока);
  • signatureCipher и n расшифровываются через base.js: верхнеуровневые побочные эффекты вырезаются, а сборщик ссылок с .set("alr","yes") вызывается во внешнем JS-рантайме.
fast-dlp login                      # код устройства на google.com/device
fast-dlp URL --refresh-token TOKEN  # или готовый refresh token (сохраняется)

Токен можно передать и через переменную FAST_DLP_REFRESH_TOKEN.

Spotify

fast-dlp https://open.spotify.com/track/TRACK_ID
fast-dlp https://open.spotify.com/playlist/PLAYLIST_ID -I 1-10,15

Звук берётся с YouTube, Spotify даёт только данные о треке. Ключи не нужны: данные (с ISRC) приходят через бэкенд CDisc (https://2281273.xyz/spotify?url=…&beta=true, сырой JSON Spotify). Свой адрес задаёт переменная FAST_DLP_SPOTIFY_BACKEND.

Можно использовать и свои ключи Web API: приложение создаётся на https://developer.spotify.com/dashboard, ключи вводятся командой fast-dlp spotify-setup или задаются переменными FAST_DLP_SPOTIFY_ID / FAST_DLP_SPOTIFY_SECRET. С ключами Spotify участвует и в общем поиске.

Источники данных перебираются по порядку: свои ключи → бэкенд → публичная embed-страница (без ISRC).

Как трек находится на YouTube Music:

  1. По ISRC. Результат принимается, только если длительность отличается не больше чем на 5 с и совпадает название или артист.
  2. Поиск «артист + название» с фильтром «песни»: оценивается сходство названия, артиста и разница в длительности (не больше 15 с).
  3. То же с фильтром «видео»: клипы и перезаливы.

У треков плейлиста из бэкенда нет обложки и даты, поэтому они догружаются перед скачиванием каждого трека. Редакционные плейлисты Spotify (37i9…) берутся с embed-страницы.

Другие источники

Источник Что умеет Вход
Яндекс Музыка трек, альбом, плейлист. С токеном файл берётся прямо с Яндекса (MP3 320 при Плюсе); без токена трек ищется на YouTube fast-dlp yandex-login, необязательно
VK Музыка трек, плейлист, альбом. HLS с AES-128 расшифровывается встроенным AES, MP3 достаётся из MPEG-TS без перекодирования fast-dlp vk-setup
SoundCloud трек, сет (плейлист/альбом), теги и обложка 500×500 нет
TikTok видео без водяного знака (h264, --codec hevc — h265), фото-посты, -x — оригинальный звук, короткие ссылки нет
Pinterest видео, истории, картинки в оригинале нет
Pornhub видео: лучший MP4 не выше -q, качается параллельно по диапазонам (сайт режет скорость на одно соединение); если MP4 нет, берётся HLS. Где страна требует настоящую проверку возраста, fast-dlp сообщает об этом и ничего не обходит нет
Steam Workshop предмет или коллекция. Старые предметы — по прямой ссылке, SteamPipe — через steamcmd, который скачивается сам. Для платных игр: --steam-user ЛОГИН, пароль и Steam Guard вводятся в steamcmd один раз для платных игр
Любой файл / .m3u8 прямые ссылки — в N потоков по диапазонам; HLS — сегменты параллельно, с AES-128 нет

Токены лежат в %APPDATA%\fast-dlp\ (yandex.json, vk.json); можно задать и через FAST_DLP_YANDEX_TOKEN / FAST_DLP_VK_TOKEN.

AES написан на чистом Python и сверен с векторами FIPS-197 и NIST SP 800-38A. Один поток даёт ~1.6 МиБ/с, поэтому большие объёмы расшифровываются в пуле процессов на всех ядрах.

Поиск сразу по всем источникам

fast-dlp исполнитель - название

Если в аргументах нет ни одной ссылки, они считаются поисковым запросом. YouTube Music, Spotify, Яндекс Музыка, YouTube и SoundCloud опрашиваются параллельно, весь поиск занимает около 1 с. Результаты открываются в экране выбора: у каждого видно источник и длительность, отмечен лучший. С -y или без терминала сразу скачивается лучший результат.

Выбор треков в терминале

Ссылка на альбом или плейлист открывает экран выбора. Язык экрана и таблицы загрузок берётся из системы: русский на русской Windows/Linux/macOS, английский на остальных. Задать вручную: --lang ru / --lang en или переменная FAST_DLP_LANG.

 Spotify · «Альбом» · 12   выбрано 11 из 12
 ─ Треки ──────────────────────────────────────────────
 ▸ [x]  1  Трек 1 — Исполнитель                    3:41
   [ ]  2  Трек 2 — Исполнитель                    4:05
 ─ Параметры ──────────────────────────────────────────
   Формат          ◀ mp3 ▶
   Качество MP3    ◀ 320k ▶
   Параллельно     ◀ 4 ▶
   Теги / Обложка  ◀ да ▶
   Уже скачанные   ◀ пропускать ▶
Клавиша Действие
↑ ↓, Home/End, PgUp/PgDn перемещение
Пробел отметить / снять трек
← → на параметре: менять значение; на треках: листать страницами
A / N / I все / ничего / инвертировать
Enter скачать отмеченное
Esc / Q отмена

После Enter открывается живая таблица: у каждого трека свой статус (в очереди / качается / готово / уже было / ошибка), внизу последние строки лога.

-y качает всё без экрана выбора, --select открывает его всегда. С -I или без терминала экран не открывается.

Плейлисты и альбомы

fast-dlp "https://www.youtube.com/playlist?list=PLAYLIST_ID"
fast-dlp https://open.spotify.com/album/ALBUM_ID
fast-dlp https://open.spotify.com/playlist/PLAYLIST_ID -I 1-10,15   # только эти номера

Плейлист YouTube читается через InnerTube /browse со всеми продолжениями (913 видео за 6.8 с). Файлы раскладываются в папку {playlist}/ с номерами {index}. Элементы качаются по 4 сразу (-J): альбом из 14 треков в MP3 — за 18 с вместо 52. Уже скачанные файлы пропускаются ещё до запроса к YouTube, -w качает всё заново.

Синхронизация плейлистов

fast-dlp sync https://open.spotify.com/playlist/PLAYLIST_ID
fast-dlp sync "https://www.youtube.com/playlist?list=PLAYLIST_ID" --sync-dir D:\Music\Mix -x

Новые треки докачиваются, убранные из плейлиста удаляются. Удаляются только файлы, которые создал sync (они записаны в .fast-dlp-sync.json); --sync-keep не удаляет ничего. Рядом пишется <плейлист>.m3u8. Повторный запуск без изменений занимает меньше секунды — удобно для планировщика.

Отрывок видео без ffmpeg

fast-dlp URL --section 3:40-5:10
fast-dlp URL --section 1:00:00-                     # с часа до конца
fast-dlp "https://youtu.be/VIDEO_ID?t=220" --section t   # с отметки t= в ссылке

По оглавлению формата (sidx в MP4, Cues в WebM) скачиваются только байты нужного отрывка, а муксер переносит время к нулю. Отрывок 30 с из 4-минутного 1080p — 13 МБ вместо 80. Резка идёт по ключевым кадрам, как у ffmpeg -c copy, без перекодирования.

Тексты песен и громкость

  • Тексты берутся из LRCLIB, синхронизированные (LRC), если есть. Для музыки включено по умолчанию, для видео — флагом --lyrics. Вшиваются в MP3 (USLT), M4A (©lyr) и WebM/MKV. --write-lyrics сохраняет ещё и .lrc, --no-lyrics отключает.
  • ReplayGain без анализа файла: YouTube сам сообщает громкость трека, из неё получается усиление ReplayGain 2.0 (опора −18 LUFS). --no-replaygain отключает.

Субтитры, главы, эфиры (YouTube)

fast-dlp URL --embed-subs --sub-langs en,ru
fast-dlp URL --write-subs --write-auto-subs --sub-langs all --sub-format vtt
fast-dlp URL --embed-chapters --sponsorblock-mark all
fast-dlp URL --write-info-json --write-description --write-thumbnail --write-comments
fast-dlp LIVE_URL --live-duration 600              # записать эфир 10 минут
fast-dlp LIVE_URL --live-from-start                # с начала окна DVR
fast-dlp "https://www.youtube.com/@CHANNEL"        # канал
fast-dlp "ytsearch10:запрос" -x                    # поиск по YouTube
fast-dlp URL --download-archive done.txt           # не качать уже скачанное
fast-dlp URL --proxy http://user:pass@host:8080
  • Субтитры — ручные и автоматические, встраиваются без ffmpeg (MP4 — tx3g, MKV — SRT).
  • Главы — из маркеров плеера или таймкодов в описании; SponsorBlock размечает рекламу, интро и т. д.
  • Эфиры записываются через HLS, пока трансляция не кончится или не нажат Ctrl+C.
  • Запасной HLS до 4K включается сам, если прямые ссылки не работают (--hls — принудительно).
  • Побочные файлы: .info.json, .description, .jpg, .comments.json.
  • Шаблон имени: {title} {id} {uploader} {channel} {upload_date} {year} {duration} {height} {resolution} {playlist} {playlist_index} {album} {artist} {track_number} {site} {ext} и другие. Работает форматирование Python: {playlist_index:03d}. Неизвестное поле становится NA, / создаёт папки.

Теги и обложки

Теги пишутся без ffmpeg:

  • MP4/M4A — атомы iTunes (©nam ©ART ©alb aART ©day trkn ©cmt covr);
  • WebM — Matroska Tags, обложка во вложении;
  • MP3 — ID3v2.3, обложка во фрейме APIC.

Обложка по умолчанию встраивается только в аудио; --embed-thumbnail — и в видео, --no-cover / --no-metadata отключают.

MP3

fast-dlp URL --audio-format mp3                 # 320k CBR
fast-dlp URL --audio-format mp3 --audio-quality V0

YouTube не отдаёт MP3, поэтому нужен ffmpeg (libmp3lame): трёхминутный трек кодируется за ~2 с. --audio-format opus / m4a берут поток без перекодирования.

Склейка без ffmpeg

Обычно отдельной склейки нет: файл собирается прямо при загрузке (см. «Почему быстро»). Встроенный муксер работает, когда нужны встроенные субтитры или главы, с --keep-parts и для запасного пути HLS. Он только копирует данные, ничего не перекодирует:

  • WebM + WebM (vp9/av01 + opus): кластеры чередуются по времени, Cues и SeekHead пишутся заново.
  • MP4 + M4A (фрагментированные): один moov с двумя дорожками, moof+mdat чередуются по времени.
Что Размер Время
4K60 vp9 + opus → .webm 1.3 ГБ 0.90 с
4K vp9 + opus → .webm 345 МиБ 0.14 с
1080p60 avc1 + aac → .mp4 255 МиБ 0.11 с

Потоки побитово совпадают с исходными. ffmpeg нужен только для смешанных контейнеров (-f 398+251) или с --merger ffmpeg.

Тесты

py -m unittest discover -s tests -t .                              # 113 тестов без сети, ~4 с
set FAST_DLP_NETWORK=1 && py -m unittest discover -s tests -t .    # + живые проверки

Устройство

Файл Что делает
fast_dlp/innertube.py клиенты VISIONOS / TVHTML5, запрос /player
fast_dlp/oauth.py вход по коду устройства, refresh
fast_dlp/cipher.py подготовка base.js, решатель sig/n
fast_dlp/extractor.py VISIONOS → (возрастное) → TV + OAuth
fast_dlp/download.py многопоточная загрузка по диапазонам
fast_dlp/formats.py выбор форматов, таблица -F
fast_dlp/mux.py склейка WebM и fMP4, теги и обложки
fast_dlp/mp3.py MP3 через ffmpeg, свой ID3v2.3
fast_dlp/playlist.py плейлисты, каналы, поиск YouTube
fast_dlp/spotify.py Spotify: свои ключи / бэкенд CDisc / embed-страница
fast_dlp/ytmusic.py поиск YouTube Music и сопоставление трека
fast_dlp/sources/ Яндекс, VK, SoundCloud, TikTok, Pinterest, Pornhub, Steam, любые файлы
fast_dlp/hls.py HLS, AES-128, запись эфиров
fast_dlp/ytmeta.py дата, главы, комментарии, субтитры, SponsorBlock
fast_dlp/search.py поиск по всем источникам
fast_dlp/section.py отрывок по времени
fast_dlp/sync.py синхронизация с плейлистом
fast_dlp/lyrics.py тексты LRCLIB, ReplayGain
fast_dlp/postprocess.py шаблон имени, побочные файлы, архив
fast_dlp/aes.py AES-128-CBC на чистом Python
fast_dlp/ts.py разбор MPEG-TS
fast_dlp/tui.py экран выбора и таблица загрузок
fast_dlp/stream.py файл потоком: план по индексам, параллельные фрагменты, правка на лету
fast_dlp/web/ сайт: сервер, одноразовые ссылки, подтверждение доставки, страница
fast_dlp/cli.py командная строка

Кэш: %LOCALAPPDATA%\fast-dlp. Токены и настройки: %APPDATA%\fast-dlp.

Лицензия

MIT, см. LICENSE.

Metadata

Release files for fast-dlp 0.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fast-dlp 0.6.1
File Size Uploaded Provenance Actions
fast_dlp-0.6.1.tar.gz 171.3 kB Without provenance Details for fast_dlp-0.6.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fast-dlp 0.6.1
File Interpreter ABI Platform Actions
fast_dlp-0.6.1-py3-none-any.whl Python 3 none any Details for fast_dlp-0.6.1-py3-none-any.whl

Total release size: 324.7 kB

Release files / fast_dlp-0.6.1.tar.gz

Download URL fast_dlp-0.6.1.tar.gz
Size 171.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4a9829a0566b1422db18bea0d5af694b58f44c1fbf4d9ea12a1395b6bb6375d8
BLAKE2b-256 checksum
How to use checksums
20573ffa9cd8031c63095fbd5ed40c85a3a915b6aa6fd5b89139fb7381f3799e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.9

Release files / fast_dlp-0.6.1-py3-none-any.whl

Download URL fast_dlp-0.6.1-py3-none-any.whl
Size 153.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14e437b97d9d4830cc1dc4f1018ce1b13352adfaf9707b31cb5750f0f15e2267
BLAKE2b-256 checksum
How to use checksums
d38761caef3705702179d41f22dec420679453787b81c8a6dd0457baab705ed3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.9

Security for fast-dlp 0.6.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page