Текст ролика YouTube
Отдаёт текст ролика YouTube по ссылке: субтитры с таймкодами, окно по времени и лимит символов. Нужен, когда агенту нужен именно текст записи - конспект, точная цитата с таймкодом или длинный ролик целиком, до 200 000 символов.
https://srezai.ru/api/v1/transcriptПример запроса
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 - по блоку на каждый запрошенный ролик: успешный ролик с текстом или ошибка с кодом. Частичный успех - норма: один недоступный ролик не роняет остальные.
{
"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 и сообщением. Остальные ролики в том же вызове отдаются как обычно.
{
"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-клиент):
{"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предыдущего ответа.