Incolla lo stream, non la pagina. L'audio reale di una stazione si trova a un indirizzo che termina in .mp3, .aac o .m3u8, e una volta che una trascrizione in diretta lo riceve, nessuno deve più restare in ascolto.
Una redazione che monitora tre stazioni radio, due stream televisivi e una manciata di dirette su YouTube ha un problema di personale prima ancora di avere un problema di trascrizione. Qualcuno deve stare in ascolto, e qualcuno deve premere registra. Una trascrizione in diretta con uno stream come sorgente svolge entrambi i compiti: basta fornirle l'indirizzo dello stream e il server lo apre, lo decodifica e lo trascrive mentre va in onda, così nessuno deve essere alla scrivania quando una conferenza stampa inizia in anticipo. La parte difficile, si scopre, è trovare quell'indirizzo.
Una trascrizione in diretta può prendere l'audio da uno stream che il server recupera da solo: una radio internet, una playlist HLS (.m3u8), un manifest DASH (.mpd) o una diretta YouTube. Nella Dashboard, si tratta di una nuova trascrizione in diretta da Transcriptions → New → Live la cui sorgente è uno stream anziché il microfono. L'indirizzo viene impostato al momento della creazione e non cambia mai, quindi un monitoraggio si configura una volta sola e si avvia ogni volta che la stazione merita di essere registrata.
L'indirizzo deve essere lo stream stesso, non la pagina web che lo riproduce. La pagina di una stazione è HTML; l'audio che riproduce arriva da un'altra parte, di solito da un server Icecast o Shoutcast, e il lettore della pagina trova quell'indirizzo con JavaScript dopo il caricamento. Cerca sul sito un link "Listen", "Direct stream" o "Other players": il suo indirizzo termina con .mp3, .aac, .m3u, .m3u8 o .pls. Un .pls o un .m3u non è nemmeno audio. È un breve file di testo di poche righe, ciascuna con l'indirizzo di uno stream; esiste perché i lettori desktop possano ricevere un solo link, e VocalStack trascrive lo stream che indica. Se incolli invece la pagina, VocalStack la richiede, vede tornare HTML e te lo segnala. Ogni stazione nasconde lo stream in modo leggermente diverso; la maggior parte lo nasconde dietro un pulsante con scritto "Listen", che è l'unica cosa nella pagina che non vale la pena cliccare.
Due tipi di link vengono rifiutati senza eccezioni. I link a pagine che riproducono media, come Spotify, SoundCloud o Twitch, vengono respinti prima ancora che si stabilisca una connessione. Non sono supportati nemmeno gli stream protetti da copyright: una playlist o un manifest che richiede una licenza DRM fallisce con un messaggio che lo dichiara. Alcuni stream rifiutano inoltre le richieste provenienti da fuori dal paese della stazione, quindi un indirizzo che funziona in ufficio potrebbe non funzionare da un server all'estero. Se uno stream si riproduce nel browser ma non in VocalStack, la stazione sta respingendo altri lettori; chiedi alla stazione un indirizzo che altre app possono usare. La maggior parte offre uno stream MP3, AAC o HLS. Una volta trovato l'indirizzo giusto, la domanda successiva è se finisce mai.
Uno stream in diretta non finisce mai, quindi non è un file. La distinzione conta soprattutto per YouTube. Una diretta YouTube in onda appartiene a una trascrizione in diretta, e la Dashboard la segue mentre va in onda. Una diretta YouTube programmata ma non ancora iniziata viene mostrata come Not live yet e può essere registrata quando va in onda. Un video concluso è un'altra cosa: ha una durata, quindi viene trascritto come file: incolla il link in Transcriptions → New.
È la playlist stessa a dire di che tipo è, ed è così che ogni lettore distingue i due casi. Una playlist HLS conclusa contiene il tag #EXT-X-ENDLIST oppure #EXT-X-PLAYLIST-TYPE:VOD; una playlist in diretta non ha nessuno dei due e continua a crescere, quindi il lettore la richiede di nuovo ogni pochi secondi per i nuovi segmenti. Un manifest DASH dichiara type="dynamic" mentre la trasmissione è in onda e type="static" quando diventa una registrazione. Uno stream MP3 o AAC da un server Icecast non ha alcuna durata: semplicemente non si ferma mai.
Dal codice, GET /v1/transcriptions/probe?url= risolve la questione prima che qualsiasi cosa venga salvata. Il campo kind della risposta è live per una diretta YouTube in onda o programmata, per uno stream HTTP senza fine, per una playlist HLS senza conclusione o per un manifest DASH dinamico. È file per tutto ciò che ha una fine, e unknown quando il probe non riesce a stabilirlo. Quando il link non si apre come media, ok è false e problem contiene una frase che puoi mostrare. Il probe non conserva nulla ed è limitato a 60 chiamate al minuto.
Le trascrizioni di file girano molte volte più veloci della riproduzione dell'audio, quindi un'ora di televisione già andata in onda non richiede un'ora. Uno stream in diretta viene trascritto in tempo reale, ma il "tempo reale" è già in ritardo rispetto alla trasmissione, e conviene sapere di quanto. Uno stream Icecast arriva a un lettore pochi secondi dopo il microfono. HLS e DASH sono segmentati, e un lettore non parte finché non ha in memoria due o tre segmenti di circa sei secondi ciascuno, quindi uno stream HLS è di solito in ritardo di 10-30 secondi rispetto alla trasmissione, prima che il sistema di trascrizione aggiunga il proprio ritardo. Una riga che sembra arrivare in ritardo è di solito il ritardo della stazione, non quello del sistema. Uno stream produce una registrazione; una redazione ne fa girare diverse, e finiscono tutte nello stesso posto.
Ogni trascrizione in diretta finisce nella libreria Transcriptions accanto a ogni file. Ogni registrazione è conservata con la sua trascrizione e, quando le parole sono definitive, viene scritto per essa un titolo e un riepilogo, in ogni lingua. La lingua parlata viene rilevata automaticamente, e i parlanti possono passare da una lingua all'altra in qualsiasi momento. Quando conosci la lingua, indicarla migliora la qualità della trascrizione.
La libreria è ricercabile tra lingue diverse: cerca in tutte le trascrizioni, qualunque sia la loro lingua, e ottieni i risultati nella tua. Un cronista che legge solo inglese può cercare il nome di un ministro nel programma del mattino di una radio romena e leggere i risultati in inglese, ognuno con la trascrizione da cui proviene e l'istante in cui è stato pronunciato. Il nome del ministro sarà scritto in tre modi diversi su tre stazioni; cercarlo in inglese fa risparmiare la lettura di tutte e tre le versioni.
Una trascrizione può essere tradotta in fino a 10 lingue contemporaneamente, così la stessa registrazione si legge in ogni lingua con cui lavora la redazione. Un risultato di ricerca serve solo se puoi citarlo.
Una trascrizione non è un muro di testo. GET /v1/recordings/{id}/transcript dell'API restituisce sentences, segments con i tempi delle singole parole e speakers, così una citazione si può collocare al secondo nella registrazione. La Dashboard riproduce una registrazione in diretta esattamente com'è arrivata, con il suo audio, quindi una frase si può ascoltare prima di essere citata.
Prima di fidarti di qualsiasi trascrizione di audio radiofonico, da qualunque sistema, vale la pena sapere due cose. Il riconoscimento vocale fatica di più con nomi propri, luoghi e cifre, cioè proprio con ciò che un cronista cerca. Un nome che il riconoscitore non ha mai visto viene reso con la parola comune più vicina, e una ricerca con la grafia corretta non lo trova. Cerca invece una parola distintiva pronunciata nello stesso respiro, poi leggi il contesto intorno al risultato. E la radio non è fatta solo di parlato: sottofondi musicali, sigle e pause pubblicitarie producono righe che sembrano frasi ma non lo sono. Controlla l'audio prima di citare.
Le etichette dei parlanti hanno tre impostazioni: disattivate, attivate oppure When Needed, che mostra le etichette non appena si sente un secondo parlante. Puoi dare un nome a un parlante in una registrazione (PUT /v1/recordings/{id}/speakers/{idx}), e una volta registrata la voce di un parlante, le registrazioni future lo riconoscono per nome. Per una stazione i cui conduttori tornano ogni mattina, le etichette smettono di essere "Speaker 2" dopo la prima settimana. Una volta verificata la citazione, può uscire dalla redazione.
Ogni formato nella scheda Esporta di una trascrizione ha un compito in redazione. SRT va al montatore video, così una clip dello stream esce con i sottotitoli; un SRT tradotto li porta in un'altra lingua. Excel va a chi fa ricerca, una riga per frase con il suo orario, da filtrare e annotare. PDF va al redattore che vuole leggere l'intera ora nel tragitto in treno. JSON va a chi scrive gli strumenti interni della redazione. Tramite l'API, l'esportazione è GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, con lang= per una versione tradotta. Download audio restituisce la registrazione come MP3, da includere nel pezzo stesso.
Monitorare una trasmissione per fare informazione è pratica normale in redazione. Ripubblicare una clip è un'altra cosa. È regolato da fair dealing o fair use nel proprio paese e dalle condizioni della stazione, quindi le regole abituali della redazione sulla citazione di un concorrente valgono anche per l'audio del concorrente. Tutto quanto descritto sopra richiede pochi clic nella Dashboard; per una redazione con venti stazioni, conviene automatizzarlo con uno script.
L'intero percorso è nell'API, incluso in ogni piano e fatturato alla stessa tariffa della Dashboard. Una trascrizione in diretta con uno stream come sorgente viene creata in attesa, avviata dalla prima registrazione e controllata via HTTP. Poiché è il server a prelevare l'audio, avviare la registrazione non restituisce alcuno stream da pubblicare: da parte tua non c'è nulla che invii 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"
L'Idempotency-Key fa sì che una creazione ripetuta restituisca la prima trascrizione invece di una seconda. Gli SDK TypeScript e Python incapsulano le stesse chiamate e si scaricano dall'area Developers; il riferimento API elenca ogni route e i suoi frame.
Un agente AI può lavorare sulla libreria senza alcun codice. Il server MCP su /v1/mcp offre all'agente un insieme di strumenti; tra questi, quattro sono rilevanti qui. search_transcriptions cerca ciò che è stato detto nelle trascrizioni dell'account in qualsiasi lingua e restituisce le righe corrispondenti, ciascuna con la trascrizione di provenienza e l'istante in cui è stata detta. get_summary restituisce il riepilogo di una registrazione. transcribe_url e wait_for_transcription trascrivono un video concluso o il link di una registrazione e attendono il risultato. Avviare il monitoraggio di uno stream in diretta resta affidato alla Dashboard o all'API descritta sopra. La configurazione per Claude Code, Cursor o qualsiasi client Streamable HTTP si trova in Developers → Connect an AI agent; l'articolo sull'MCP la illustra passo passo. Quanto costa far girare lo script è l'ultima domanda.
La trascrizione in diretta costa $0.60 all'ora di audio, fatturata al secondo ($0.01 al minuto), con un minimo di 5 minuti per trascrizione. La diretta costa più di un file perché viene trascritta mentre accade, per tutto il tempo in cui dura. I file costano $0.20 all'ora ($0.0033 al minuto; un file di 30 minuti costa $0.10). Le tariffe sono le stesse in ogni piano e tramite l'API, e traduzioni, riepiloghi, nomi dei parlanti, trasmissione e condivisione non aumentano mai il conto.
Una stazione monitorata otto ore al giorno, cinque giorni a settimana, equivale a 40 ore in diretta: $24 a settimana, qualunque sia il numero di lingue in cui la redazione la legge.
I limiti che contano per il monitoraggio variano per piano. Ciascuno è elencato nell'ordine Pay as you go, Premium, Enterprise:
Un nuovo account inizia con un credito di iscrizione da $5 e senza carta, più di otto ore di monitoraggio in diretta per provarlo. La tabella completa è nella pagina dei prezzi.