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

Текст ролика YouTube

Отдаёт текст ролика YouTube по ссылке: субтитры с таймкодами, окно по времени и лимит символов. Нужен, когда агенту нужен именно текст записи - конспект, точная цитата с таймкодом или длинный ролик целиком, до 200 000 символов.

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

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

bash
curl -X POST https://srezai.ru/api/v1/transcript \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SREZAI_API_KEY" \
  -d '{
    "videos": ["https://youtu.be/dQw4w9WgXcQ"],
    "languages": ["ru", "en"],
    "timestamps": true,
    "from": 120,
    "to": 420,
    "maxChars": 40000
  }'

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

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

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

Ссылки на ролики YouTube, от 1 до 5 за вызов. Подходят youtu.be/ID, youtube.com/watch?v=ID, shorts и embed. Ссылки идут массивом: одна строка вместо массива - это 400. Дубликаты отбрасываются до чтения; ссылка не на YouTube возвращает ошибку not_youtube по этому ролику, а не роняет вызов.

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

Языки субтитров в порядке приоритета, от 1 до 5, коды вида ru, en, de (регистр не важен, региональный суффикс срезается: ru-RU → ru). В REST взятое сверх пяти и мусор отбрасываются, а не роняют запрос; если валидных не осталось, берутся ru и en. MCP-схема строже - см. раздел Через MCP. Побеждает первый доступный у ролика вариант: ручные субтитры точнее автоматических - какой источник выбран, видно в поле languageSource.

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

Добавлять таймкод к каждой реплике. По умолчанию false - приходит сплошной текст. Включается только значением true: строка "true" или единица флагом не считаются. С true каждая строка начинается с [mm:ss], а у роликов от часа - с [h:mm:ss]. Нужен, когда цитату надо привязать к моменту в записи.

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

Начало окна в секундах от начала ролика. По умолчанию 0. Окно задаёт, какой фрагмент нужен, - так берут один тезис, а не два часа записи. Отрицательное значение - 400.

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

Конец окна в секундах, должен быть больше from (иначе 400). По умолчанию - конец ролика.

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

Сколько символов текста вернуть, от 200 до 200000 (по умолчанию 200000). В REST значение вне границ зажимается к ближайшей, а не отклоняется с ошибкой; MCP-схема строже - см. раздел Через MCP. Если текст не влез, в ответе truncated: true, а продолжение берётся сдвигом окна from/to, а не offset: у субтитров окно по времени.

Ответ

В results - по блоку на каждый запрошенный ролик: успешный ролик с текстом или ошибка с кодом. Частичный успех - норма: один недоступный ролик не роняет остальные.

json
{
  "results": [
    {
      "url": "https://youtu.be/dQw4w9WgXcQ",
      "videoId": "dQw4w9WgXcQ",
      "title": "Как устроен поиск по видео",
      "channel": "Название канала",
      "duration": 2130,
      "language": "ru",
      "languageSource": "manual",
      "chars": 18142,
      "truncated": false,
      "window": { "from": 120, "to": 420 },
      "text": "…текст субтитров за окно 2:00-7:00…",
      "segments": [
        { "start": 120.4, "end": 123.1, "text": "…" }
      ],
      "tookMs": 2123
    }
  ],
  "meta": { "requested": 1, "succeeded": 1, "failed": 0, "tookMs": 2500 },
  "credits": 15
}
textstringнеобязательный

Текст субтитров за запрошенное окно. С timestamps: true каждая реплика начинается с таймкода.

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

Реплики субтитров: start и end в секундах от начала ролика (не окна) и text. Пригодится, когда нужна точная привязка цитаты к моменту.

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

Язык, с которого прочитан текст, и languageSource: manual - субтитры загрузил автор, auto - автоматические. Авто бывают с ошибками распознавания - для дословной цитаты это важно.

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

Фактическое окно выдачи: from и to в секундах. По нему видно, где закончился текст и откуда читать дальше.

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

Сколько символов в text; truncated говорит, что текст обрезан по maxChars.

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

Длительность ролика целиком в секундах - по ней удобно выбирать окно.

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

Сколько роликов запрошено, прочитано и не прочиталось (requested, succeeded, failed) и сколько занял вызов.

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

Сколько кредитов списано фактически - эта же цифра уходит в журнал запросов. Непрочитанные ролики не тарифицируются.

Когда ролик не прочитался

Ошибка по ролику приходит вместо блока результата: url и объект error с машинным code и сообщением. Остальные ролики в том же вызове отдаются как обычно.

json
{
  "results": [
    {
      "url": "https://youtu.be/ID-без-субтитров",
      "error": { "code": "no_subtitles", "message": "…" }
    },
    {
      "url": "https://youtu.be/ID-нормальный",
      "videoId": "ID-нормальный",
      "title": "…",
      "chars": 9210,
      "truncated": false,
      "window": { "from": 0, "to": 905 },
      "text": "…",
      "segments": [],
      "tookMs": 1890
    }
  ],
  "meta": { "requested": 2, "succeeded": 1, "failed": 1, "tookMs": 4000 },
  "credits": 15
}
not_youtubeссылка не YouTubeнеобязательный

Адрес не похож на ролик YouTube. Нужна ссылка вида https://youtu.be/ID или https://www.youtube.com/watch?v=ID. Повтор не поможет.

unavailableролик недоступеннеобязательный

Удалён, скрыт или закрыт по региону. Повтор той же ссылки не поможет - берите другую запись по теме.

privateприватный роликнеобязательный

Субтитры приватного ролика без доступа к нему не читаются. Публичной ссылки на текст нет.

no_subtitlesсубтитров нетнеобязательный

У ролика нет субтитров - ни ручных, ни автоматических. Это не сбой: текста не существует. Нужен другой ролик.

liveпрямой эфирнеобязательный

Идёт прямой эфир: субтитры появятся только после публикации записи. Дождитесь записи или возьмите другой ролик.

timeoutповторитенеобязательный

Сервис не уложился в отведённое время: ролик длинный или YouTube медленно отдаёт субтитры. Повторите через минуту; если снова не выйдет - сузьте окно from/to.

rate_limitedповторитенеобязательный

YouTube ограничил частоту запросов с нашего сервера. Подождите минуту и повторите - этот отказ квоту ключа не расходует.

blockedповторите позженеобязательный

YouTube временно перестал отдавать автоматические субтитры нашему серверу. Это наша сторона, а не ваш запрос: сервис сам перебирает варианты загрузки, так что повод для повтора - время.

internalповторитенеобязательный

Сервис субтитров не ответил или сломался на своей стороне. Запрос корректен - повторите через 15 секунд.

HTTP-статус самого вызова: 200 - запрос обработан, включая частичный успех и случай, когда не прочитался ни один ролик (тогда credits: 0, а причины - в results); 400 - тело не JSON, videos не массив, пустой или длиннее пяти ссылок, отрицательные from/to либо to не больше from; 401 - ключ не принят; 402 - не хватает кредитов; 429 - лимит запросов; 502 или 503 - сервис субтитров упал или выключен. Коды отказа по ролику перечислены выше: они приходят внутри results при 200 и ошибкой вызова не являются. Полный список кодов и что повторять - в разделе Ошибки.

Цена

  • 15 кредитов за каждый успешно отданный ролик. Пять роликов в одном вызове - до 75 кредитов.
  • Непрочитанный ролик не тарифицируется: no_subtitles, private, live, not_youtube и прочие отказы стоят ноль. Если не прочитался ни один - credits: 0.

1 кредит = 0,10 ₽. Актуальная сетка - на странице тарифов, расход по услугам за сутки и неделю отдаёт get_usage (в MCP - бесплатно).

Через MCP: yt_srt

Тот же функционал доступен агенту как инструмент yt_srt MCP-сервера - с теми же полями: videos, languages, timestamps, from, to, maxChars. Вызов JSON-RPC выглядит так (его же выполняет любой MCP-клиент):

json
{"jsonrpc":"2.0","id":2,"method":"tools/call",
 "params":{
   "name":"yt_srt",
   "arguments":{
     "videos":["https://youtu.be/dQw4w9WgXcQ"],
     "languages":["ru","en"],
     "timestamps":true,
     "from":120,
     "to":420,
     "maxChars":40000
   }
 }}

Ответ приходит текстом, а не JSON: заголовок блока на ролик (название, канал, длительность, язык и его источник, окно, число сегментов, символов и время чтения), затем сам текст, а в конце - строка о списанных кредитах (Списано N; если не отдан ни один ролик - 0 credits charged). С timestamps: true каждая реплика начинается с [mm:ss]. Нужен полный JSON с сегментами - берите REST: POST /api/v1/transcript. Метода в Python- и JavaScript-SDK для этого инструмента нет.

Ограничения

  • Только YouTube. VK Видео, Rutube, «Дзен» и другие площадки не поддерживаются: для них вернётся not_youtube. Это не универсальный «текст любого видео».
  • Это текст, а не файл. Инструмент отдаёт субтитры - скачать сам ролик или звук им нельзя. Нужен файл видео - это не наша задача.
  • Разметки по говорящим нет. В этой версии инструмент не разделяет реплики по спикерам: он не знает, кто именно говорит. Обещать диаризацию мы не будем, пока её нет.
  • Текста нет без субтитров: если автор их не загрузил и автоматические не распознались, вернётся no_subtitles - пересказать ролик по звуку инструмент не умеет.
  • До пяти роликов за вызов; сервис обрабатывает по два параллельно и держит один ролик не дольше 45 секунд, весь запрос - до 120 секунд. Пять длинных роликов в одном вызове могут упереться в таймаут: тогда делите пачку.
  • Окно from/to задаётся в секундах от начала ролика, а не таймкодом строкой. Секунды удобно брать из segments или window.to предыдущего ответа.

Когда это не он