На этой странице

Субтитры YouTube

Текст ролика вместо просмотра: ручная или автоматическая дорожка субтитров приходит в контекст агента, а видео и звук не скачиваются. Дорогое место в работе с видео — не поиск ссылки, а то, что часовая лекция не влезает в контекст; субтитры решают это за 1 кредит.

POSThttps://srezai.ru/api/v1/transcript

Пример запроса

bash
curl -X POST https://srezai.ru/api/v1/transcript \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer srz_live_ВАШ_КЛЮЧ" \
  -d '{
    "videos": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "languages": ["ru", "en"],
    "maxChars": 12000
  }'

Параметры тела

Тело запроса - JSON. Обязателен только videos; неизвестные поля игнорируются, а недопустимые значения приводятся к безопасным.

videosstring[]обязательный

Ссылки на ролики YouTube или их 11-символьные id, до 5 за вызов. Понимаются формы watch?v=, youtu.be/, shorts, embed, live и голый id. Дубликаты и лишние ролики отбрасываются до работы — их число вернётся в skipped.

videostringнеобязательный

Алиас для одного ролика: {"video": "…"} вместо массива из одного элемента. Удобно в n8n и curl.

languagesstring[]необязательный

Языки в порядке предпочтения, по умолчанию ["ru", "en"], до 5. Ручная дорожка предпочтительнее автоматической. Если нужного языка нет, в ошибке придут доступные — повторите запрос с существующим.

timestampsbooleanнеобязательный

true - вернуть фрагменты с таймкодами вместо сплошного текста. Дороже по контексту, но удобно для навигации по длинному ролику и точных цитат «на такой-то минуте».

fromnumberнеобязательный

Начало окна в секундах. Для продолжения берите nextFrom из предыдущего ответа: уже прочитанное повторно не тарифицируется.

tonumberнеобязательный

Конец окна в секундах. Должно быть больше from; иначе вернётся bad_request.

maxCharsnumberнеобязательный

Сколько символов текста вернуть на ролик: от 200 до 50000, по умолчанию 12000. Обрезанный текст отмечен truncated: true и nextFrom.

Ответ

json
{
  "results": [
    {
      "videoId": "dQw4w9WgXcQ",
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "title": "Название ролика",
      "channel": "Название канала",
      "channelUrl": "https://www.youtube.com/@channel",
      "durationSec": 213,
      "published": "2024-05-01",
      "language": "ru",
      "kind": "manual",
      "text": "Первые 12 000 символов субтитров…",
      "totalChars": 48210,
      "truncated": true,
      "nextFrom": 1290,
      "segments": null,
      "cached": false,
      "tookMs": 3420
    }
  ],
  "errors": [
    {
      "input": "https://www.youtube.com/watch?v=XXXXXXXXXXX",
      "videoId": "XXXXXXXXXXX",
      "code": "empty_result",
      "reason": "у ролика нет субтитров ни на одном языке",
      "available": ["en"],
      "retryAfterSec": null
    }
  ],
  "skipped": 0,
  "credits": 1,
  "meta": {
    "tookMs": 6120,
    "requested": 2,
    "ok": 1,
    "from": 0,
    "to": null,
    "maxChars": 12000,
    "languages": ["ru", "en"]
  }
}

Ответ всегда содержит два списка: results - ролики, у которых текст получен, и errors - остальные с машинным кодом и причиной. Частичный успех — норма: из пяти роликов четыре могут прийти с текстом, а пятый — с empty_result и списком доступных языков.

results[].videoIdstringнеобязательный

Id ролика — с ним удобно продолжать чтение окнами.

results[].titlestringнеобязательный

Название ролика и channel / channelUrl — чтобы агент мог сослаться на источник, а не на безымянный текст.

results[].language, results[].kindstringнеобязательный

Язык дорожки и её вид: manual (загружена автором) или auto (распознана автоматически). Авто-дорожка бывает с ошибками распознавания — для точных цитат лучше ручная.

results[].text, totalChars, truncated, nextFromstringнеобязательный

Текст окна, полная длина, признак обрезки и секунда для продолжения. Пустой ролик (без дорожки) в results не попадает.

results[].segmentsobject[] | nullнеобязательный

Фрагменты с таймкодами, когда timestamps: true; иначе null. Тем же полем пользуется MCP-инструмент.

errors[].codestringнеобязательный

empty_result — дорожки нет (не сбой, не тарифицируется); rate_limited — YouTube притормозил, повторите позже (retryAfterSec); service_unavailable — не ответил наш сервис; bad_request — ссылка не на YouTube.

creditsnumberнеобязательный

Сколько кредитов списано фактически: по одному за каждый ролик с полученным текстом. Неудачи не списываются.

metaobjectнеобязательный

Параметры выполнения: tookMs, requested (сколько роликов приняли в работу) и ok (сколько получилось), плюс эхо from/to/maxChars/languages.

Как читать длинный ролик

Двухчасовой подкаст не влезет в контекст целиком, и это не повод платить дважды за один и тот же текст. Читайте окнами: первый запрос возвращает truncated: true и nextFrom, следующий — {"videos": ["…"], "from": nextFrom}. Продолжение отдаёт только новые символы и тарифицируется как новый ролик, поэтому выгоднее брать окно побольше, а не много маленьких.

В MCP-клиентах тот же инструмент называется yt_srt — контракт совпадает. В SDK: client.transcript(videos, opts) в JavaScript и client.transcript(videos, **opts) в Python. В n8n — операция «Субтитры YouTube» в узле срезAI.