Lipește stream-ul, nu pagina. Adresa reală a unui post se termină în .mp3, .aac sau .m3u8, iar odată ce o transcriere live o are, nimeni nu mai trebuie să asculte.
O redacție care monitorizează trei posturi de radio, două stream-uri de televiziune și câteva transmisiuni live de pe YouTube are mai întâi o problemă de personal și abia apoi una de transcriere. Cineva trebuie să asculte, iar cineva trebuie să apese butonul de înregistrare. O transcriere live cu un stream drept sursă preia ambele sarcini: dai adresa stream-ului, iar serverul o deschide, o decodează și o transcrie pe măsură ce se difuzează, astfel încât nimeni nu trebuie să stea la birou când începe mai devreme o conferință de presă. Partea grea, se dovedește, este găsirea adresei.
O transcriere live își poate lua sunetul dintr-un stream pe care serverul îl trage singur: un post de radio pe internet, o listă de redare HLS (.m3u8), un manifest DASH (.mpd) sau un live de pe YouTube. În Dashboard, aceasta este o transcriere live nouă la Transcriptions → New → Live, a cărei sursă este un stream și nu microfonul. Adresa se setează la crearea transcrierii și nu se mai schimbă, deci un monitor se configurează o singură dată și se pornește ori de câte ori postul merită înregistrat.
Adresa trebuie să fie chiar stream-ul, nu pagina web care îl redă. Pagina unui post este HTML; sunetul pe care îl redă vine de altundeva, de obicei de pe un server Icecast sau Shoutcast, iar playerul paginii găsește adresa cu JavaScript după ce se încarcă. Caută pe site un link „Listen”, „Direct stream” sau „Other players”: el se termină în .mp3, .aac, .m3u, .m3u8 sau .pls. Un .pls sau un .m3u nu este nici el audio. Este un fișier text scurt, de câteva rânduri, fiecare cu adresa unui stream; există ca un player desktop să poată primi un singur link, iar VocalStack transcrie stream-ul pe care îl numește. Dacă lipești pagina în schimb, VocalStack cere pagina, vede că revine HTML și îți spune asta. Fiecare post își ascunde stream-ul puțin diferit; cele mai multe îl ascund în spatele unui buton marcat „Listen”, iar acesta este singurul lucru de pe pagină care nu merită apăsat.
Două tipuri de link sunt refuzate din capul locului. Linkurile către pagini care redau media, precum Spotify, SoundCloud sau Twitch, sunt respinse înainte de orice conexiune. Nici stream-urile protejate la copiere nu sunt acceptate: o listă sau un manifest care cere o licență DRM eșuează, cu un mesaj care spune asta. Unele stream-uri refuză și cererile din afara țării postului, deci o adresă care merge la birou s-ar putea să nu meargă de pe un server din străinătate. Dacă un stream se redă într-un browser, dar nu în VocalStack, postul respinge alți playere; cere postului o adresă pe care alte aplicații au voie să o folosească. Cele mai multe oferă un stream MP3, AAC sau HLS. Odată ce ai adresa corectă, următoarea întrebare este dacă se termină vreodată.
Un stream live nu se termină niciodată, deci nu este un fișier. Distincția contează mai ales la YouTube. Un live de pe YouTube care este în aer aparține unei transcrieri live, iar Dashboard-ul îl urmărește pe măsură ce se difuzează. Un live de pe YouTube programat, dar care nu a început, apare ca Not live yet și poate fi înregistrat după ce intră în aer. Un video terminat este altceva: are o durată, deci se transcrie ca fișier. Lipește linkul în Transcriptions → New.
Lista de redare spune singură ce este, iar așa își dă seama orice player de diferență. O listă HLS încheiată conține eticheta #EXT-X-ENDLIST sau #EXT-X-PLAYLIST-TYPE:VOD; una live nu are niciuna și crește continuu, deci playerul o reîncarcă la câteva secunde ca să ia segmentele noi. Un manifest DASH declară type="dynamic" cât timp transmisiunea este în aer și type="static" odată ce devine o înregistrare. Un stream MP3 sau AAC de pe un server Icecast nu are deloc durată; pur și simplu nu se oprește niciodată.
Din cod, GET /v1/transcriptions/probe?url= lămurește lucrurile înainte ca ceva să fie salvat. Răspunsul kind este live pentru un live de pe YouTube în aer sau programat, pentru un stream HTTP fără sfârșit, pentru o listă HLS fără sfârșit sau pentru un manifest DASH dinamic. Este file pentru orice are un sfârșit și unknown când sondarea nu poate spune. Când linkul nu s-a deschis ca media, ok este false, iar problem este o propoziție pe care o poți afișa. Sondarea nu păstrează nimic și este limitată la 60 de apeluri pe minut.
Transcrierile de fișiere rulează de multe ori mai repede decât se redă audio-ul, deci o oră terminată de televiziune nu durează o oră. Un stream live se transcrie în timp real, dar „timpul real” rămâne în urma transmisiunii, iar merită să știi cu cât. Un stream Icecast ajunge la un player la câteva secunde după microfon. HLS și DASH sunt segmentate, iar un player nu pornește până nu are două sau trei segmente de circa șase secunde fiecare, deci un stream HLS este de obicei cu 10 până la 30 de secunde în urma transmisiunii, înainte ca transcrierea să adauge propria întârziere. O replică ce pare să sosească târziu este de obicei întârzierea postului, nu a transcriptorului. Fiecare stream produce o singură înregistrare; o redacție rulează mai multe, iar toate ajung în același loc.
Fiecare transcriere live ajunge în biblioteca Transcriptions, alături de toate fișierele. Fiecare înregistrare se păstrează împreună cu transcrierea ei, iar odată ce cuvintele sunt definitive, i se scrie un titlu și un rezumat, în fiecare limbă. Limba vorbită se detectează automat, iar vorbitorii pot trece oricând de la o limbă la alta. Când știi limba, o precizare îmbunătățește calitatea transcrierii.
Biblioteca se poate căuta peste limbi: caută în toate transcrierile, oricare ar fi limba lor, și primești rezultatele în a ta. Un reporter care citește doar engleza poate căuta în emisiunea de dimineață a postului românesc numele unui ministru și poate citi rezultatele în engleză, fiecare cu transcrierea din care provine și momentul în care a fost rostit. Numele ministrului va fi scris în trei feluri la trei posturi; căutarea lui în engleză te scutește de citirea a trei variante.
O transcriere poate fi tradusă în până la 10 limbi deodată, astfel încât aceeași înregistrare se citește în fiecare limbă în care lucrează redacția. Un rezultat al căutării este util doar dacă îl poți cita.
O transcriere nu este un perete de text. GET /v1/recordings/{id}/transcript din API returnează sentences, segments cu marcajele de timp ale cuvintelor și speakers, deci un citat poate fi plasat până la secundă în raport cu înregistrarea. Dashboard-ul redă o înregistrare live exact cum a sosit, cu audio-ul ei, așa că o propoziție poate fi ascultată înainte de a fi citată.
Înainte să ai încredere într-o transcriere a unui audio radio, din orice sistem, două lucruri merită știute. Recunoașterea vorbirii greșește cel mai des la nume proprii, locuri și cifre, adică exact ce caută un reporter. Un nume pe care recunoașterea nu l-a mai văzut ajunge cuvântul comun cel mai apropiat, iar o căutare după forma corectă nu îl găsește. Caută în schimb un cuvânt distinctiv rostit în aceeași respirație, apoi citește în jurul rezultatului. Iar radioul nu este numai vorbire: fundalurile muzicale, indicativele și pauzele de publicitate produc replici care arată ca propoziții, dar nu sunt. Verifică audio-ul înainte să citezi.
Etichetele de vorbitor au trei setări: oprit, pornit sau When Needed, care afișează etichetele după ce se aude un al doilea vorbitor. Poți da un nume unui vorbitor într-o înregistrare (PUT /v1/recordings/{id}/speakers/{idx}), iar odată ce vocea unui vorbitor este înrolată, înregistrările viitoare îl recunosc după nume. Pentru un post ai cărui prezentatori revin în fiecare dimineață, etichetele încetează să mai fie „Speaker 2” după prima săptămână. Odată verificat, citatul trebuie să ajungă la public.
Fiecare format din tabul Export al unei transcrieri are un rol în redacție. SRT merge la editorul video, astfel încât un clip din stream vine cu subtitrări; un SRT tradus le are într-o altă limbă. Excel merge la cercetător, cu un rând pe propoziție și cu momentul ei, ca să fie filtrat și adnotat. PDF merge la editorul care vrea să citească toată ora în tren. JSON merge la cine scrie uneltele proprii ale redacției. Prin API, exportul este GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, cu lang= pentru o versiune tradusă. Download audio dă înregistrarea ca MP3, pentru pachetul propriu-zis.
Monitorizarea unei transmisiuni pentru raportare este practică obișnuită în redacții. Republicarea unui clip din ea este altceva. Se supune regulilor privind utilizarea loială (fair dealing sau fair use) din țara ta și termenilor propriilor posturi, deci regulile obișnuite ale redacției privind citarea unui concurent se aplică și audio-ului concurentului. Tot ce e de mai sus înseamnă câteva clicuri în Dashboard; pentru o redacție cu douăzeci de posturi, e mai bine să fie scriptat.
Tot drumul este în API, inclus în fiecare plan și facturat la același tarif ca în Dashboard. O transcriere live cu sursă stream este creată inactivă, pornită de prima ei înregistrare și controlată prin HTTP. Deoarece serverul trage sunetul, pornirea unei înregistrări nu returnează un stream în care să publici: nu există nimic de partea ta care să trimită audio.
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 face ca o creare reluată să returneze prima transcriere, în loc de una a doua. SDK-urile TypeScript și Python învelesc aceleași apeluri și se descarcă din zona Developers; referința API are fiecare rută și cadrele ei.
Un agent AI poate lucra cu biblioteca fără niciun cod. Serverul MCP de la /v1/mcp îi oferă agentului un set de unelte; dintre ele, patru contează aici. search_transcriptions caută ce s-a spus în toate transcrierile contului, în orice limbă, și returnează rândurile potrivite, fiecare cu transcrierea din care provine și momentul în care a fost rostit. get_summary returnează rezumatul unei înregistrări. transcribe_url și wait_for_transcription transcriu un video terminat sau linkul unei înregistrări și așteaptă rezultatul. Pornirea unui monitor pe un stream live rămâne în Dashboard sau în API-ul de mai sus. Configurarea pentru Claude Code, Cursor sau orice client Streamable HTTP se găsește la Developers → Connect an AI agent; articolul despre MCP o parcurge pas cu pas. Cât costă rularea scriptului este ultima întrebare.
Transcrierea live costă $0.60 pe oră de audio, facturată pe secundă ($0.01 pe minut), cu un minim de 5 minute pe transcriere. Live costă mai mult decât un fișier, pentru că este transcris pe măsură ce se întâmplă, atât timp cât rulează. Fișierele costă $0.20 pe oră ($0.0033 pe minut; un fișier de 30 de minute costă $0.10). Tarifele sunt aceleași în fiecare plan și prin API, iar traducerile, rezumatele, denumirea vorbitorilor, transmisiunile și partajarea nu adaugă niciodată la factură.
Un post monitorizat opt ore pe zi, cinci zile pe săptămână, înseamnă 40 de ore live: $24 pe săptămână, oricare ar fi limbile în care o citește redacția.
Limitele care contează pentru monitorizare variază în funcție de plan. Fiecare este listată în ordinea Pay as you go, Premium, Enterprise:
Un cont nou începe cu un credit de bun venit de $5 și fără card, ceea ce înseamnă mai mult de opt ore de monitorizare live pentru a-l încerca. Tabelul complet este pe pagina de prețuri.