Вставляйте поток, а не страницу. Настоящее аудио станции лежит по адресу, который заканчивается на .mp3, .aac или .m3u8, и когда живая транскрибация получит его, слушать никому не нужно.
Редакция, которая следит за тремя радиостанциями, двумя телеканалами и несколькими прямыми эфирами на YouTube, сначала сталкивается с проблемой кадров, а не с транскрибацией. Кто-то должен слушать, и кто-то должен нажать «запись». Живая транскрибация с потоком в качестве источника берёт на себя обе задачи: вы даёте адрес потока, сервер открывает его, декодирует и транскрибирует в эфире, так что никому не нужно сидеть за столом, когда пресс-конференция начинается раньше времени. Самое сложное, как выясняется, — найти этот адрес.
Живая транскрибация может брать звук из потока, который сервер получает сам: интернет-радио, плейлист HLS (.m3u8), манифест DASH (.mpd) или прямой эфир YouTube. В панели управления это новая живая транскрибация в разделе Transcriptions → New → Live, где источником служит поток, а не микрофон. Адрес задаётся при создании транскрибации и не меняется, поэтому монитор настраивают один раз, а запускают, когда станция становится интересной для записи.
Адрес должен вести к самому потоку, а не к веб-странице, которая его воспроизводит. Страница станции — это HTML; звук, который она проигрывает, приходит с другого сервера, обычно Icecast или Shoutcast, а плеер на странице находит этот адрес с помощью JavaScript уже после загрузки. Поищите на сайте ссылку «Listen», «Direct stream» или «Other players»: она заканчивается на .mp3, .aac, .m3u, .m3u8 или .pls. Файл .pls или .m3u тоже не является аудио. Это короткий текстовый файл из нескольких строк, в каждой из которых указан адрес потока; он нужен, чтобы настольные плееры могли открыть станцию по одной ссылке, и VocalStack транскрибирует тот поток, который в нём назван. Если вставить страницу, VocalStack запросит её, увидит в ответе HTML и сообщит вам об этом. Каждая станция прячет поток по-своему; чаще всего он спрятан за кнопкой «Listen», и именно на неё на странице не стоит нажимать.
Два вида ссылок отклоняются сразу. Ссылки на страницы, которые проигрывают медиа, например Spotify, SoundCloud или Twitch, отсекаются ещё до подключения. Защищённые от копирования потоки тоже не поддерживаются: плейлист или манифест, для которого нужна лицензия DRM, завершается ошибкой с соответствующим сообщением. Некоторые потоки также не отдают данные запросам из-за пределов страны станции, поэтому адрес, который работает в офисе, может не работать с сервера за рубежом. Если поток воспроизводится в браузере, но не в VocalStack, станция не пускает сторонние плееры; попросите у неё адрес, которым могут пользоваться другие приложения. Чаще всего доступны потоки MP3, AAC или HLS. Когда адрес правильный, остаётся вопрос: заканчивается ли он когда-нибудь.
Живой поток никогда не заканчивается, поэтому это не файл. Различие особенно важно для YouTube. Прямой эфир YouTube, который идёт в эфире, относится к живой транскрибации, и панель управления следит за ним по мере выхода в эфир. Запланированный, но ещё не начавшийся эфир показан как Not live yet и может быть записан, когда выйдет в эфир. Готовое видео — это другое: у него есть длительность, поэтому его транскрибируют как файл. Вставьте ссылку в Transcriptions → New.
Сам плейлист говорит, что он собой представляет, и по этому признаку любой плеер отличает одно от другого. У завершённого плейлиста HLS есть тег #EXT-X-ENDLIST или #EXT-X-PLAYLIST-TYPE:VOD; у живого нет ни того ни другого, и он продолжает расти, поэтому плеер каждые несколько секунд запрашивает его заново, чтобы получить новые сегменты. Манифест DASH объявляет type="dynamic", пока трансляция идёт в эфире, и type="static", когда она становится записью. MP3- или AAC-поток с сервера Icecast не имеет длительности вовсе: он просто никогда не прекращается.
Из кода GET /v1/transcriptions/probe?url= решает этот вопрос до того, как что-либо сохранено. В ответе kind равно live для прямого эфира YouTube, который идёт в эфире или запланирован, для бесконечного HTTP-потока, плейлиста HLS без конца или динамического манифеста DASH. Значение file означает всё, что имеет конец, а unknown — что проба не смогла определить тип. Если ссылка не открылась как медиа, ok равно false, а problem содержит фразу, которую можно показать пользователю. Проба ничего не сохраняет и ограничена 60 вызовами в минуту.
Файлы транскрибируются во много раз быстрее, чем звучат, поэтому час записанного телевидения не занимает час. Живой поток транскрибируется в реальном времени, но «реальное время» всё равно идёт с отставанием от эфира, и полезно знать, насколько. Поток Icecast доходит до плеера через несколько секунд после микрофона. HLS и DASH разбиты на сегменты, и плеер не начнёт воспроизведение, пока не накопит два-три сегмента примерно по шесть секунд, поэтому HLS-поток обычно отстаёт от эфира на 10–30 секунд, а транскрибация добавляет свою задержку. Строка, которая появляется с опозданием, обычно связана с задержкой станции, а не с транскрибатором. Один поток даёт одну запись; редакция ведёт несколько, и все они попадают в одно место.
Каждая живая транскрибация попадает в библиотеку Transcriptions рядом с каждым файлом. Каждая запись хранится вместе со своей расшифровкой, а когда слова окончательно установлены, для неё пишутся заголовок и краткое содержание на всех языках. Язык речи определяется автоматически, и говорящие могут переходить с языка на язык в любой момент. Если вы знаете язык, его указание повышает качество транскрибации.
Библиотека ищется между языками: можно искать по всем расшифровкам, на каком бы языке они ни были, и получать результаты на своём языке. Репортёр, который читает только по-английски, может искать в утреннем шоу румынской станции имя министра и читать совпадения по-английски, каждое со ссылкой на транскрибацию и временем, когда это было сказано. Имя министра на трёх станциях будет записано тремя разными способами; поиск по английскому написанию избавляет от необходимости читать все три варианта.
Транскрипцию можно перевести сразу на 10 языков, поэтому одна и та же запись читается на каждом языке, с которым работает редакция. Результат поиска полезен, только если его можно процитировать.
Расшифровка — это не сплошной текст. GET /v1/recordings/{id}/transcript в API возвращает sentences, segments с таймингами слов и speakers, поэтому цитату можно привязать к секунде записи. Панель управления воспроизводит живую запись так, как она шла в эфире, вместе со звуком, поэтому предложение можно услышать, прежде чем процитировать его.
Прежде чем доверять расшифровке радиозаписи, из любой системы, стоит знать две вещи. Распознавание речи чаще всего спотыкается на собственных именах, географических названиях и цифрах, а именно их репортёр и ищет. Имя, которое распознаватель никогда не встречал, превращается в ближайшее обычное слово, и поиск по правильному написанию его не находит. Поэтому ищите отличительное слово, произнесённое в той же фразе, а потом читайте вокруг совпадения. И радио — это не только речь: музыкальные подложки, джинглы и рекламные блоки дают строки, которые выглядят как предложения, но таковыми не являются. Проверьте аудио, прежде чем цитировать.
Метки говорящих имеют три настройки: off, on или When Needed, которая показывает метки, как только услышан второй говорящий. Говорящего в записи можно назвать (PUT /v1/recordings/{id}/speakers/{idx}), а когда голос говорящего зарегистрирован, в будущих записях его узнают по имени. Для станции, ведущие которой возвращаются каждое утро, через первую неделю метки перестают быть «Speaker 2». Когда цитата проверена, ей пора покинуть редакцию.
Каждый формат на вкладке Export у транскрибации имеет свою задачу в редакции. SRT уходит видеоредактору, чтобы у фрагмента из потока были субтитры; переведённый SRT несёт субтитры на другом языке. Excel уходит исследователю: по одной строке на предложение с его временем, чтобы фильтровать и комментировать. PDF уходит редактору, который хочет прочитать весь час в поезде. JSON — тому, кто пишет собственные инструменты редакции. Через API экспорт выглядит так: GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, а lang= задаёт переведённую версию. Download audio даёт запись в виде MP3 для самого материала.
Мониторинг эфира ради репортажа — обычная практика редакций. Републикация фрагмента — уже другое действие. Оно регулируется правом добросовестного использования (fair dealing или fair use) там, где вы находитесь, и собственными условиями станции, поэтому обычные правила редакции о цитировании конкурента распространяются и на его аудио. Всё выше делается в несколько кликов в панели управления; для редакции из двадцати станций удобнее скрипт.
Весь путь доступен в API, он входит в каждый тариф и оплачивается по той же ставке, что и в панели управления. Живая транскрибация с потоком в качестве источника создаётся в простое, запускается первой записью и управляется по HTTP. Поскольку звук забирает сервер, запуск записи не возвращает поток для отправки: с вашей стороны ничего не передаёт аудио.
API=$VOCALSTACK_API_ORIGIN # the origin shown in the API reference
AUTH="Authorization: Bearer $VOCALSTACK_API_KEY"
# A live transcription whose source the server pulls itself.
TX=$(jq -n '{name: "Morning show", source: {kind: "stream", url: "https://example.org/live.mp3"},
settings: {speakerLabels: "auto"}}' \
| curl -sSf "$API/v1/transcriptions/live" -H "$AUTH" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" -d @- | jq -r .id)
# Start recording: the server opens the stream now.
REC=$(curl -sSf -X POST "$API/v1/transcriptions/$TX/recordings" -H "$AUTH" \
-H "Content-Type: application/json" -d '{}' | jq -r .recording.id)
# Later: pause, then stop (a live recording must be paused before it is stopped).
curl -sSf -X POST "$API/v1/recordings/$REC/pause" -H "$AUTH"
curl -sSf -X POST "$API/v1/recordings/$REC/stop" -H "$AUTH" -H "Content-Type: application/json" -d '{}'
# Search everything that was said, in English.
curl -sSfG "$API/v1/search" -H "$AUTH" --data-urlencode "q=budget" --data-urlencode "lang=en"
Ключ Idempotency-Key гарантирует, что повторный запрос на создание вернёт первую транскрибацию, а не вторую. SDK для TypeScript и Python оборачивают те же вызовы и скачиваются из раздела для разработчиков; в справочнике API описаны все маршруты и их кадры.
ИИ-агент может работать с библиотекой без единой строки кода. MCP-сервер по адресу /v1/mcp предоставляет агенту набор инструментов; из них здесь важны четыре. search_transcriptions ищет по тому, что было сказано, во всех транскрибациях аккаунта на любом языке и возвращает совпавшие строки, каждую с транскрибацией, в которой она находится, и временем, когда это было сказано. get_summary возвращает краткое содержание записи. transcribe_url и wait_for_transcription транскрибируют готовое видео или ссылку на запись и ждут результата. Запуск монитора живого потока остаётся за панелью управления или API выше. Настройка для Claude Code, Cursor или любого клиента Streamable HTTP находится в разделе Developers → Connect an AI agent; статья о MCP описывает её по шагам. Последний вопрос — сколько это стоит.
Живая транскрибация стоит $0.60 за час аудио, тарификация посекундная ($0.01 в минуту), с минимумом 5 минут на транскрибацию. Живая транскрибация дороже файла, потому что она расшифровывается по ходу эфира, столько, сколько он длится. Файлы стоят $0.20 в час ($0.0033 в минуту; 30-минутный файл стоит $0.10). Тарифы одинаковы во всех планах и через API, а переводы, краткие содержания, именование говорящих, трансляция и обмен никогда не увеличивают счёт.
Станция, которую мониторят восемь часов в день, пять дней в неделю, — это 40 часов эфира: $24 в неделю, на каком бы языке ни читала её редакция.
Ограничения, важные для мониторинга, зависят от тарифа. Каждое перечислено в порядке Pay as you go, Premium, Enterprise:
Новый аккаунт получает стартовый кредит $5 без карты, чего хватает больше чем на восемь часов живого мониторинга для пробы. Полная таблица — на странице тарифов.