Вставте посилання на потік, а не на сторінку. Справжнє аудіо станції лежить за адресою, що закінчується на .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, що йде в ефірі, належить до транскрибування наживо, і панель керування слідує за нею, поки вона триває. Трансляція 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, коли probe не зміг визначити. Якщо посилання не відкрилося як медіа, ok дорівнює false, а problem містить речення, яке можна показати. Probe нічого не зберігає і обмежений 60 викликами на хвилину.
Файли транскрибуються в багато разів швидше, ніж відтворюється звук, тож година завершеного телеепізоду не займає годину. Потік наживо транскрибується в реальному часі, але «реальний час» усе одно відстає від ефіру, і корисно знати, на скільки. Потік Icecast доходить до плеєра за кілька секунд після мікрофона. HLS і DASH поділені на сегменти, і плеєр не почне відтворення, поки не отримає два-три сегменти по близько шість секунд кожен, тож HLS-потік зазвичай відстає від ефіру на 10–30 секунд, до того як сервіс транскрибування додасть власну затримку. Рядок, що з’являється із запізненням, зазвичай спричинений затримкою станції, а не сервісу транскрибування. Один потік дає один запис; редакція запускає кілька, і всі вони опиняються в одному місці.
Кожне транскрибування наживо потрапляє до бібліотеки Transcriptions поруч з усіма файлами. Кожен запис зберігається разом зі своїм транскриптом, а щойно слова остаточно сформовано, для нього пишуться назва і підсумок — для кожної мови окремо. Мову мовлення визначають автоматично, і мовці можуть будь-коли перейти на іншу мову. Якщо мова відома, її вказівка покращує якість транскрибування.
Бібліотека доступна для пошуку між мовами: шукайте в усіх транскриптах, якою б мовою вони не були, і отримуйте результати вашою мовою. Репортер, який читає лише англійською, може знайти в ранковому шоу румунської станції ім’я міністра і прочитати знайдені фрагменти англійською, кожен із транскрибуванням, з якого він походить, і часом, коли це було сказано. Ім’я міністра на трьох станціях буде записане трьома різними способами; пошук за ним англійською заощаджує читання всіх трьох варіантів.
Транскрибування можна перекласти до 10 мов одночасно, тож один запис читається кожною мовою, якою працює редакція. Результат пошуку корисний, лише якщо його можна процитувати.
Транскрипт — це не суцільний текст. GET /v1/recordings/{id}/transcript в API повертає sentences, segments з таймінгами слів і speakers, тож цитату можна прив’язати до секунди в записі. Панель керування відтворює запис у реальному часі точно так, як він надходив, разом зі звуком, тож речення можна вислухати перед тим, як його процитувати.
Перш ніж довіряти будь-якому транскрипту радіоаудіо, з будь-якої системи, варто знати дві речі. Розпізнавання мовлення найчастіше помиляється на власних назвах, місцях і цифрах — саме те, що репортер шукає. Ім’я, яке система розпізнавання ніколи не бачила, перетворюється на найближче звичайне слово, і пошук за правильним написанням його не знаходить. Натомість шукайте відмітне слово, сказане в тій самій фразі, а потім читайте навколо знайденого. Радіо складається не лише з мовлення: музичні підкладки, джингли й рекламні блоки дають рядки, які схожі на речення, але ними не є. Перевіряйте аудіо, перш ніж цитувати.
Мітки мовців мають три налаштування: вимкнено, увімкнено або 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 містить кожен маршрут і його фрейми.
AI-агент може працювати з бібліотекою і без жодного коду. 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 на тиждень, якими б мовами редакція її не читала.
Обмеження, важливі для моніторингу, залежать від тарифу. Кожне перелічено в порядку: Оплата за використання, Premium, Enterprise:
Новий обліковий запис починається з бонусу $5 при реєстрації без картки, чого вистачає більш ніж на вісім годин моніторингу наживо, щоб його спробувати. Повна таблиця розміщена на сторінці цін.