async-yt-dlp
Строго типизированная асинхронная обёртка над yt-dlp для Python 3.11+.
Все блокирующие операции yt-dlp выполняются через asyncio.to_thread, поэтому event loop не блокируется. Подходит для Telegram-ботов, Discord-ботов, веб-сервисов (FastAPI, Litestar, aiohttp) и фоновых очередей задач.
Возможности
- Асинхронность: блокирующие вызовы yt-dlp вынесены в
asyncio.to_thread, event loop свободен. - Типизация: модели
MediaInfo,FormatInfo,DownloadResult,ProgressEvent— frozen dataclass соslots=True. PEP 561py.typed, совместимо сmypy --strict. - Потокобезопасность: каждая операция получает изолированный экземпляр
YoutubeDL. - Стриминг прогресса: асинхронный генератор
download_with_progressс адаптивным троттлингом. - Контроль параллельности:
DownloadManagerна базеasyncio.Semaphoreс ограничением очереди (backpressure). - Отмена и таймауты: корректная обработка
task.cancel(),asyncio.timeoutи graceful shutdown. - Объектная конфигурация:
FormatSelector(fluent-построитель форматов),OutputTemplate(построитель шаблонов имён файлов),VideoContainer(выбор контейнера). - Маскировка данных: пароли, токены, cookies и прокси автоматически скрываются в логах.
- Диагностика окружения:
check_dependencies()проверяет наличиеyt-dlp,ffmpeg,ffprobeи JS-движков.
Установка
Требуется Python 3.11+.
# Базовая установка:
pip install async-yt-dlp
# С интеграцией aio-ffmpeg (постобработка видео):
pip install "async-yt-dlp[ffmpeg]"
# Полный набор (aio-ffmpeg + curl-cffi, websockets и др.):
pip install "async-yt-dlp[full]"
Или через uv:
uv add async-yt-dlp
Быстрый старт
1. Извлечение метаданных
import asyncio
from async_yt_dlp import AsyncYTDLP
async def main() -> None:
async with AsyncYTDLP() as ytdlp:
info = await ytdlp.extract_info("https://www.youtube.com/watch?v=BaW_jenozKc")
print(f"Название: {info.title}")
print(f"Автор: {info.uploader}")
print(f"Длительность: {info.duration_seconds} сек.")
asyncio.run(main())
2. Скачивание видео
import asyncio
from pathlib import Path
from async_yt_dlp import AsyncYTDLP, YTDLPOptions, FormatSelector, OutputTemplate, VideoContainer
async def main() -> None:
options = YTDLPOptions(
format=FormatSelector.preset_720p(container=VideoContainer.MP4),
container=VideoContainer.MP4,
output_path=Path("./downloads"),
output_template=OutputTemplate.title_only(),
)
async with AsyncYTDLP(default_options=options) as ytdlp:
result = await ytdlp.download("https://www.youtube.com/watch?v=BaW_jenozKc")
print(f"Файл: {result.filepath} ({result.file_size} байт)")
asyncio.run(main())
3. Стриминг прогресса загрузки
import asyncio
from async_yt_dlp import AsyncYTDLP, DownloadStatus
async def main() -> None:
async with AsyncYTDLP() as ytdlp:
async for event in ytdlp.download_with_progress(
"https://www.youtube.com/watch?v=BaW_jenozKc",
throttle_interval=0.5,
):
if event.status == DownloadStatus.DOWNLOADING:
print(
f"\rЗагрузка: {event.percent:.1f}% | {event.speed_str} | ETA: {event.eta_str}",
end="",
)
elif event.status == DownloadStatus.COMPLETE:
print("\nГотово!")
asyncio.run(main())
Объектная конфигурация
FormatSelector — построитель строки --format
from async_yt_dlp import FormatSelector, VideoContainer
# Готовые пресеты:
FormatSelector.preset_720p() # 720p видео + аудио
FormatSelector.preset_1080p(container=VideoContainer.MP4) # 1080p, приоритет mp4
FormatSelector.preset_audio_only("m4a") # только аудио
FormatSelector.preset_max_quality() # максимальное качество
# Ручная сборка:
fmt = FormatSelector.video().max_height(480).ext("mp4").merge(FormatSelector.audio())
OutputTemplate — построитель шаблона имени файла
from async_yt_dlp import OutputTemplate
# Готовые пресеты:
OutputTemplate.title_only() # "%(title)s.%(ext)s"
OutputTemplate.title_and_id() # "%(title)s [%(id)s].%(ext)s"
OutputTemplate.dated() # "%(upload_date)s - %(title)s.%(ext)s"
OutputTemplate.playlist_folder() # "%(playlist_title)s/%(playlist_index)02d - %(title)s.%(ext)s"
OutputTemplate.channel_folder() # "%(uploader)s/%(upload_date)s - %(title)s.%(ext)s"
# Ручная сборка через fluent-API:
tpl = OutputTemplate().channel().dir().title().ext() # "%(channel)s/%(title)s.%(ext)s"
# Операторы:
tpl = OutputTemplate().channel() / OutputTemplate.title_only() # то же самое
VideoContainer — гарантия формата выходного файла
from async_yt_dlp import VideoContainer, YTDLPOptions
# Гарантирует .mp4 на выходе (ffmpeg remux без перекодирования):
options = YTDLPOptions(container=VideoContainer.MP4)
# Доступные: MP4, MKV, WEBM, MOV, AVI, FLV, TS
Архитектура
flowchart TD
App["Приложение<br/>(Telegram, Web, CLI, Bot)"] --> Client["AsyncYTDLP<br/>фасад, lifecycle, API"]
Client --> Manager["DownloadManager<br/>Semaphore, backpressure"]
Manager --> Backend["ThreadBackend<br/>asyncio.to_thread"]
Backend --> YTDLP["yt_dlp.YoutubeDL<br/>синхронное ядро"]
Примеры использования
В каталоге examples/ представлены готовые примеры:
simple_extract.py— извлечение метаданныхsimple_download.py— скачивание файлаprogress.py— отображение прогрессаplaylist.py— работа с плейлистамиaudio_extraction.py— извлечение аудиоpostprocessing_pipeline.py— постобработка через aio-ffmpegcustom_options.py— настройка параметровcancellation.py— отмена задач и таймаутыconcurrency.py— параллельная загрузка
Лицензия
Проект распространяется под лицензией MIT. См. файл LICENSE.
Release files for async-yt-dlp 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| async_yt_dlp-0.1.2.tar.gz | 329.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| async_yt_dlp-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 389.0 kB
Release files / async_yt_dlp-0.1.2.tar.gz
| Download URL | async_yt_dlp-0.1.2.tar.gz |
|---|---|
| Size | 329.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
53fc2008a532939130dbe74d694d863ab29243dd253fb71fa47e3031872499a6
|
|
BLAKE2b-256 checksum How to use checksums |
952a413158fc7cfb7b27f8859ab264eef76fd06bd49fd91807cd93748b39c0b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / async_yt_dlp-0.1.2-py3-none-any.whl
| Download URL | async_yt_dlp-0.1.2-py3-none-any.whl |
|---|---|
| Size | 59.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
96326c77411393ca9ed2fa900c255479e89c91f0663f572822430194983ce8f7
|
|
BLAKE2b-256 checksum How to use checksums |
5d5c1ad22ffc546cb2501e687bcaf61c9e5eb5f122ed43aac0c81c5b950fdf84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|