Skip to main content

async-yt-dlp

CI PyPI version Python 3.11+ Typing: Typed License: MIT

Строго типизированная асинхронная обёртка над 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 561 py.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/ представлены готовые примеры:


Лицензия

Проект распространяется под лицензией 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)

Source distribution for async-yt-dlp 0.1.2
File Size Uploaded
async_yt_dlp-0.1.2.tar.gz 329.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for async-yt-dlp 0.1.2
File Interpreter ABI Platform
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}

Release history Release notifications | RSS feed

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

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