Pega el stream, no la página. La dirección real del audio de una emisora termina en .mp3, .aac o .m3u8, y, una vez que una transcripción en directo lo tiene, nadie necesita estar escuchando.
Una redacción que sigue tres emisoras de radio, dos canales de televisión en streaming y un puñado de directos de YouTube tiene primero un problema de personal y después uno de transcripción. Alguien tiene que estar escuchando y alguien tiene que pulsar grabar. Una transcripción en directo con un stream como fuente asume ambas tareas: le das la dirección del stream, el servidor lo abre, lo decodifica y lo transcribe mientras se emite, así que nadie tiene que estar en su mesa cuando una rueda de prensa empieza antes de lo previsto. Lo difícil, resulta, es encontrar la dirección.
Una transcripción en directo puede tomar su audio de un stream que el servidor descarga por su cuenta: una emisora de radio por internet, una lista de reproducción HLS (.m3u8), un manifiesto DASH (.mpd) o un directo de YouTube. En el panel, eso es una nueva transcripción en directo en Transcriptions → New → Live cuya fuente es un stream y no el micrófono. La dirección se fija al crear la transcripción y nunca cambia, así que un monitor se configura una vez y se inicia cada vez que la emisora merezca la pena grabar.
La dirección tiene que ser el stream en sí, no la página web que lo reproduce. La página de una emisora es HTML; el audio que reproduce viene de otro sitio, normalmente de un servidor Icecast o Shoutcast, y el reproductor de la página encuentra esa dirección con JavaScript después de cargar. Busca en el sitio un enlace que diga «Escuchar», «Direct stream» u «Other players»: termina en .mp3, .aac, .m3u, .m3u8 o .pls. Un .pls o un .m3u tampoco es audio. Es un archivo de texto corto de unas pocas líneas, cada una con la dirección de un stream; existe para que los reproductores de escritorio reciban un único enlace, y VocalStack transcribe el stream que nombra. Si pegas la página, VocalStack la pide, ve que llega HTML y te lo indica. Cada emisora esconde su stream de una manera distinta; la mayoría lo oculta tras un botón marcado «Escuchar», que es lo único de la página que no merece la pena pulsar.
Hay dos tipos de enlace que se rechazan directamente. Los enlaces a páginas que reproducen contenido multimedia, como Spotify, SoundCloud o Twitch, se descartan antes de conectar. Los streams protegidos contra copia tampoco son compatibles: una lista de reproducción o un manifiesto que necesite una licencia DRM falla con un mensaje que lo dice. Algunos streams además rechazan las peticiones que llegan desde fuera del país de la emisora, así que una dirección que se reproduce en la oficina puede no hacerlo desde un servidor en el extranjero. Si un stream se reproduce en el navegador pero no en VocalStack, la emisora está bloqueando a otros reproductores; pide a la emisora una dirección que otras aplicaciones puedan usar. La mayoría ofrece un stream en MP3, AAC o HLS. Una vez que tienes la dirección correcta, la siguiente pregunta es si llega a terminar.
Un stream en directo nunca termina, así que no es un archivo. La distinción importa sobre todo en YouTube. Un directo de YouTube que está en emisión pertenece a una transcripción en directo, y el panel lo sigue mientras se emite. Un directo de YouTube programado que aún no ha empezado aparece como Not live yet y se puede grabar cuando esté en emisión. Un vídeo finalizado es otra cosa: tiene una duración, así que se transcribe como archivo: pega el enlace en Transcriptions → New.
La propia lista de reproducción indica cuál es, y así es como cualquier reproductor distingue una cosa de otra. Una lista HLS finalizada lleva la etiqueta #EXT-X-ENDLIST o #EXT-X-PLAYLIST-TYPE:VOD; una en directo no tiene ninguna de las dos y sigue creciendo, así que el reproductor la vuelve a pedir cada pocos segundos para obtener los segmentos nuevos. Un manifiesto DASH declara type="dynamic" mientras la emisión está en directo y type="static" cuando es una grabación. Un stream MP3 o AAC de un servidor Icecast no tiene duración alguna; simplemente nunca se detiene.
Desde código, GET /v1/transcriptions/probe?url= resuelve esto antes de guardar nada. El kind de la respuesta es live para un directo de YouTube en emisión o programado, un stream HTTP sin fin, una lista HLS sin final o un manifiesto DASH dinámico. Es file para cualquier cosa con final, y unknown cuando la comprobación no puede determinarlo. Cuando el enlace no se abrió como contenido multimedia, ok es false y problem es una frase que puedes mostrar. La comprobación no guarda nada y está limitada a 60 llamadas por minuto.
Las transcripciones de archivos van muchas veces más rápido que la velocidad a la que se reproduce el audio, así que una hora de televisión ya emitida no tarda una hora. Un stream en directo se transcribe en tiempo real, pero el «tiempo real» ya va por detrás de la emisión, y conviene saber cuánto. Un stream Icecast llega a un reproductor unos segundos después del micrófono. HLS y DASH van por segmentos, y un reproductor no arranca hasta tener dos o tres segmentos de unos seis segundos cada uno, así que un stream HLS suele ir de 10 a 30 segundos por detrás de la emisión antes de que la transcripción añada su propio retraso. Una línea que parece llegar tarde suele ser el retraso de la emisora, no el del transcriptor. Cada stream genera una grabación; una mesa de redacción sigue varios, y todos acaban en el mismo sitio.
Cada transcripción en directo aparece en la biblioteca de Transcriptions, junto a todos los archivos. Cada grabación se guarda con su transcripción y, una vez que las palabras son definitivas, se escriben para ella un título y un resumen, en todos los idiomas. El idioma hablado se detecta automáticamente, y los hablantes pueden cambiar de idioma en cualquier momento. Cuando sabes qué idioma es, indicarlo mejora la calidad de la transcripción.
La biblioteca se puede buscar entre idiomas: busca en todas las transcripciones, sea cual sea su idioma, y recibe los resultados en el tuyo. Quien solo lee inglés puede buscar en el programa matinal de la emisora rumana el nombre de un ministro y leer los resultados en inglés, cada uno con la transcripción de la que procede y la hora en que se dijo. El nombre del ministro aparecerá escrito de tres formas distintas en tres emisoras; buscarlo en inglés evita tener que leer las tres.
Una transcripción se puede traducir a hasta 10 idiomas a la vez, así que la misma grabación se lee en todos los idiomas con los que trabaja la redacción. Un resultado de búsqueda solo sirve si puedes citarlo.
Una transcripción no es un bloque de texto. GET /v1/recordings/{id}/transcript de la API devuelve sentences, segments con los tiempos de cada palabra y speakers, así que una cita se puede situar al segundo dentro de la grabación. El panel reproduce una grabación en directo tal como llegó, con su audio, de modo que una frase se puede escuchar antes de citarla.
Antes de fiarte de cualquier transcripción de audio de radio, venga de donde venga, conviene saber dos cosas. El reconocimiento de voz tropieza sobre todo con nombres propios, lugares y cifras, que son justo lo que busca una persona de la redacción. Un nombre que el reconocedor nunca ha visto sale como la palabra común más parecida, y una búsqueda con la grafía correcta no lo encuentra. Busca en cambio una palabra distintiva dicha en la misma intervención y lee después el texto alrededor del resultado. Y la radio no es solo habla: las cortinillas musicales, las sintonías y los cortes publicitarios producen líneas que parecen frases pero no lo son. Comprueba el audio antes de citar.
Las etiquetas de hablante tienen tres ajustes: off, on o When Needed, que muestra las etiquetas cuando se oye a un segundo hablante. Puedes asignar un nombre a un hablante en una grabación (PUT /v1/recordings/{id}/speakers/{idx}), y una vez registrada la voz de un hablante, las grabaciones futuras lo reconocen por su nombre. En una emisora cuyos presentadores vuelven cada mañana, las etiquetas dejan de ser «Speaker 2» después de la primera semana. Una vez comprobada la cita, tiene que salir del edificio.
Cada formato de la pestaña Export de una transcripción tiene una función en la redacción. SRT va al editor de vídeo, para que un clip del stream lleve subtítulos; un SRT traducido los lleva en otro idioma. Excel va a quien investiga, una fila por frase con su hora, para filtrar y anotar. PDF va a quien quiere leer la hora entera en el tren. JSON va a quien escribe las herramientas propias de la mesa. A través de la API, la exportación es GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, con lang= para una versión traducida. Download audio entrega la grabación como MP3 para el propio paquete.
Monitorizar una emisión para informar es práctica habitual en la redacción. Volver a publicar un fragmento es otra cosa. Se rige por el uso legítimo (fair dealing o fair use) del país en el que estés y por las condiciones propias de la emisora, así que las normas habituales de la mesa sobre citar a la competencia se aplican también al audio de la competencia. Todo lo anterior son unos pocos clics en el panel; para una mesa con veinte emisoras, es mejor automatizarlo con scripts.
Todo el proceso está en la API, incluido en todos los planes y facturado a la misma tarifa que el panel. Una transcripción en directo con un stream como fuente se crea inactiva, se inicia con su primera grabación y se controla por HTTP. Como el servidor descarga el audio, al iniciar la grabación no se devuelve ningún stream al que tengas que publicar: en tu lado no hay nada que envíe 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"
El Idempotency-Key hace que un reintento de creación devuelva la primera transcripción en lugar de crear una segunda. Los SDK de TypeScript y Python envuelven las mismas llamadas y se descargan desde el área de desarrolladores; la referencia de la API recoge todas las rutas y sus frames.
Un agente de IA puede trabajar con la biblioteca sin escribir código. El servidor MCP en /v1/mcp le da al agente un conjunto de herramientas; de ellas, cuatro son relevantes aquí. search_transcriptions busca lo que se dijo en todas las transcripciones de la cuenta, en cualquier idioma, y devuelve las líneas coincidentes, cada una con la transcripción en la que está y la hora en que se dijo. get_summary devuelve el resumen de una grabación. transcribe_url y wait_for_transcription transcriben un vídeo finalizado o el enlace de una grabación y esperan el resultado. Iniciar un monitor de stream en directo sigue siendo tarea del panel o de la API de arriba. La configuración para Claude Code, Cursor o cualquier cliente Streamable HTTP está en Developers → Connect an AI agent; el artículo sobre MCP la explica paso a paso. Lo que cuesta ejecutar el script es la última pregunta.
La transcripción en directo cuesta $0.60 por hora de audio, facturada por segundo ($0.01 por minuto), con un mínimo de 5 minutos por transcripción. El directo cuesta más que un archivo porque se transcribe mientras ocurre, durante todo el tiempo que dura. Los archivos cuestan $0.20 por hora ($0.0033 por minuto; un archivo de 30 minutos cuesta $0.10). Las tarifas son las mismas en todos los planes y a través de la API, y las traducciones, los resúmenes, la asignación de nombres a hablantes, la difusión en directo y la compartición nunca suman nada a la factura.
Una emisora monitorizada ocho horas al día, cinco días a la semana, son 40 horas de directo: $24 a la semana, en los idiomas en que la mesa la lee.
Los límites que importan para monitorizar varían según el plan. Cada uno aparece en el orden Pago por uso, Premium, Enterprise:
Una cuenta nueva empieza con un crédito de registro de $5 y sin tarjeta, lo que equivale a más de ocho horas de monitorización en directo para probarlo. La tabla completa está en la página de precios.