Перейти к содержимому

yt-dlp как API: встраивание, свой REST-враппер или хостинговый сервис

Автор Команда TunelioОпубликовано

Официального REST API у yt-dlp нет — это библиотека и CLI. Чтобы вызывать его по HTTP, вы либо встраиваете его в свой сервис, либо разворачиваете один из community-врапперов, либо платите хостинговому API, который держит парк извлечения за вас. Здесь — минимальный самодельный враппер, реальная стоимость эксплуатации в масштабе (CPU, репутация IP, поломки, трафик) и честное правило выбора между «строить» и «купить».

Вариант 1: встроить yt-dlp в свой код

Если приложение на Python, импортируйте yt_dlp и вызывайте extract_info напрямую — без HTTP-прыжка и второго сервиса. Руководство по Python описывает опции, хуки, обработку ошибок и подводные камни async. Это правильный ответ для скриптов, внутренних инструментов и одноарендных приложений.

Вариант 2: свой REST-враппер

Враппер открывает yt-dlp не-Python коду, ботам и другим сервисам. Минимально жизнеспособная версия — несколько десятков строк:

# app.py — минимальный REST-враппер yt-dlp (FastAPI)
import asyncio, yt_dlp
from fastapi import FastAPI, HTTPException, Query

app = FastAPI()
SEM = asyncio.Semaphore(4)                 # каждое извлечение ≈ 1 с CPU; ограничиваем

def extract(url: str, fmt: str) -> dict:
    opts = {"quiet": True, "skip_download": True, "format": fmt, "noplaylist": True,
            "source_address": "0.0.0.0"}   # IPv4
    with yt_dlp.YoutubeDL(opts) as ydl:
        return ydl.extract_info(url, download=False)

@app.get("/info")
async def info(url: str = Query(...)):
    try:
        async with SEM:
            i = await asyncio.to_thread(extract, url, "b")
    except yt_dlp.utils.DownloadError as e:
        raise HTTPException(status_code=502, detail=str(e)[:200])
    return {"id": i["id"], "title": i["title"], "duration": i["duration"],
            "formats": [{"id": f["format_id"], "height": f.get("height"), "ext": f["ext"]}
                        for f in i["formats"] if f.get("vcodec") != "none" and f.get("acodec") != "none"]}

@app.get("/url")
async def direct_url(url: str, quality: int = 720):
    async with SEM:
        i = await asyncio.to_thread(extract, url, f"b[height<={quality}]")
    return {"url": i["url"], "expires_in_hours": 6}   # подписана под IP ЭТОГО сервера

Запускайте через uvicorn за nginx в Docker-образе из руководства по Python (yt-dlp + ffmpeg + Deno). Community-проекты вроде yt-dlp-web-ui, MeTube и разные образы «yt-dlp server» делают то же с интерфейсом и очередью; они наследуют все ограничения ниже.

Чего враппер не решает

Возвращаемая ссылка привязана к вашему серверу

Ссылки googlevideo подписаны под запрашивающий IP и клиент и истекают примерно через шесть часов. Отдавать их конечным пользователям в других сетях — получить 403; настоящий дизайн — гнать медиа через свой сервер (трафик ×2) либо скачивать и раздавать заново (диск + трафик). Именно эту часть хостинговые API называют «туннелем».

Слияние и аудио требуют ffmpeg на каждый запрос

Всё выше 720p — отдельные видео- и аудиопотоки; MP3 — транскодирование. И то и другое — CPU ffmpeg на вашей машине при каждой загрузке (руководство по ffmpeg).

CPU на извлечение

На нашем парке одно извлечение YouTube стоит около 1,2–1,3 секунды CPU, в основном на выполнение JavaScript плеера, и платится на каждый запрос. Десять запросов в секунду — дюжина ядер ещё до отдачи единственного байта медиа. Кешируйте результаты извлечения по видео на несколько часов, чтобы переживать всплески.

Репутация IP — настоящий потолок

Сервер, извлекающий сотни видео в день с одного дата-центрового адреса, получает «Sign in to confirm you’re not a bot» и медиа-403 — по нашим замерам примерно каждый четвёртый свежий дата-центровый выход получает проверку при первом контакте, а IPv6 делает хуже. Оставаться онлайн значит резидентные прокси, липкие сессии, выпуск PO-токенов и ротация cookies (руководства по прокси, cookies и 403). Именно эту эксплуатационную стоимость чаще всего недооценивают.

Поломки

YouTube что-то меняет каждые несколько недель; каждое изменение — обновление yt-dlp и редеплой, обычно обнаруживаемые через сбой (руководство по обновлению). Заложите дежурство.

Вариант 3: хостинговый YouTube download API

curl "https://tunelio.dev/create?url=https://youtu.be/dQw4w9WgXcQ&quality=720p" \
  -H "Authorization: Bearer tnl_your_api_key"
# → { "url": "https://…/tunnel?id=…&sig=…", "file_size_str": "28.52 MB", "status": "ok" }

Хостинговый API — это враппер выше плюс парк плюс туннель: один запрос возвращает подписанную ссылку на скачивание, которую можно отдать прямо пользователю, боту или загрузке в S3, а извлечение, ffmpeg, ротация IP и изменения YouTube обрабатываются на стороне сервиса. Tunelio — наш сервис, читайте сравнение с этой поправкой; цифры — те же, с которыми живём мы.

Строить или покупать — честная таблица

  • Объём до ~50 видео в день с одной машины, личное или внутреннее использование → встраивать или self-host; бесплатных инструментов достаточно, и вы изучите стек.
  • Функция продукта (бот, SaaS, пайплайн) с пользователями, которых вы не контролируете → обычно выигрывает хостинговый API: один счёт за прокси часто превышает счёт за API, и дежурство не на вас.
  • Жёсткие требования к локализации данных или изолированная сеть → self-host, но планируйте резидентные выходы и человека на сопровождение.
  • Сайты помимо YouTube → охват yt-dlp не имеет равных; хостинговые API обычно YouTube-first.
  • Нужны транскрипты, метаданные и медиа по одному контракту → хостинг (Tunelio отдаёт /info, /create и /transcript по одному ключу).

Проверка цен на здравый смысл

Self-hosting выглядит бесплатным, пока не сложить части: VPS с несколькими ядрами, резидентный прокси с оплатой за ГБ (через него идёт каждый байт видео), кто-то обновляющий yt-dlp в три ночи, и потерянные пользователи во время сбоев. Хостинговые цены — за запрос: Tunelio берёт 6 кредитов за /info или /transcript и 10 за /create, даёт 100 бесплатных кредитов при регистрации, платные тарифы от $9 в месяц за 100 000 кредитов. Посчитайте на своём объёме, прежде чем выбирать.

Источники

  • README yt-dlp — «Embedding yt-dlp», сетевые опции и опции форматов.
  • Community-врапперы — yt-dlp-web-ui, MeTube (GitHub) как референсные реализации.
  • Наши измерения (парк извлечения Tunelio, 2026): CPU на извлечение, доля проверок при первом контакте на дата-центровых IP, байты прокси на извлечение.

Частые вопросы

Есть ли официальный API у yt-dlp?

Нет. yt-dlp — библиотека Python и CLI. Любой REST API — это либо ваш враппер, либо community-проект, либо хостинговый сервис, выполняющий извлечение за вас.

Можно отдавать ссылку yt-dlp своим пользователям?

Ненадёжно: ссылка googlevideo подписана под IP и клиент вашего сервера и истекает через ~6 часов. Гоните медиа через свой сервер или используйте хостинговый API с безопасной для пользователя подписанной ссылкой.

Сколько запросов в секунду выдержит один сервер?

Примерно одно извлечение в секунду на ядро, плюс ffmpeg и трафик — пока вас не ограничит репутация IP. Кешируйте результаты и ограничивайте параллельность.

Когда self-hosting — лучший выбор?

Низкий объём, внутреннее использование, сайты помимо YouTube или жёсткие правила локализации данных. Для пользовательских продуктов в масштабе расходы на прокси и сопровождение обычно делают хостинговый API дешевле.

Похожие руководства