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.3

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.3
File Size Uploaded
async_yt_dlp-0.1.3.tar.gz 330.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for async-yt-dlp 0.1.3
File Interpreter ABI Platform
async_yt_dlp-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 389.6 kB

Release files / async_yt_dlp-0.1.3.tar.gz

Download URL async_yt_dlp-0.1.3.tar.gz
Size 330.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b8335e826c446c2200f6d29a1600231f6baaf41442537c26de2c17878b774a02
BLAKE2b-256 checksum
How to use checksums
d280c7d3dd348ce957de14009caf862570209ec116a9c69b40ba06cd8c12a7d8
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.3-py3-none-any.whl

Download URL async_yt_dlp-0.1.3-py3-none-any.whl
Size 59.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ecab0ce10d7b15aade94e05b53c9772bce25e86261e7628aeca6e423b0d580c
BLAKE2b-256 checksum
How to use checksums
c0f16446b9cb66685dbdebfd05760eb2c0abe794cda2e3f1307ffb76b2e2e61d
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

This release

0.1.3 This release

2 release files

0.1.2

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