Collez le flux, pas la page. Le son réel d’une station se trouve à une adresse qui se termine par .mp3, .aac ou .m3u8 ; une fois qu’une transcription en direct le reçoit, personne n’a besoin d’écouter.
Une rédaction qui surveille trois stations de radio, deux flux de télévision et quelques lives YouTube a d’abord un problème de personnel avant d’avoir un problème de transcription. Quelqu’un doit écouter, et quelqu’un doit appuyer sur enregistrer. Une transcription en direct dont la source est un flux prend en charge ces deux tâches : vous lui donnez l’adresse du flux, le serveur l’ouvre, le décode et le transcrit au fur et à mesure de sa diffusion, de sorte que personne n’a besoin d’être à son bureau quand une conférence de presse commence en avance. La difficulté, il s’avère, est de trouver l’adresse.
Une transcription en direct peut prendre son audio depuis un flux que le serveur récupère lui-même : une radio sur Internet, une playlist HLS (.m3u8), un manifeste DASH (.mpd) ou un live YouTube. Dans le tableau de bord, il s’agit d’une nouvelle transcription en direct, à Transcriptions → New → Live, dont la source est un flux et non le microphone. L’adresse est définie à la création de la transcription et ne change jamais : un suivi se configure une seule fois et se lance chaque fois que la station vaut la peine d’être enregistrée.
L’adresse doit être celle du flux lui-même, et non la page web qui le lit. La page d’une station est en HTML ; l’audio qu’elle joue provient d’ailleurs, généralement d’un serveur Icecast ou Shoutcast, et le lecteur de la page trouve cette adresse en JavaScript après le chargement. Cherchez sur le site un lien « Écouter », « Flux direct » ou « Autres lecteurs » : il se termine par .mp3, .aac, .m3u, .m3u8 ou .pls. Un .pls ou un .m3u n’est pas non plus de l’audio. C’est un petit fichier texte de quelques lignes, chacune donnant l’adresse d’un flux ; il existe pour que les lecteurs de bureau puissent recevoir un seul lien, et VocalStack transcrit le flux qu’il désigne. Si vous collez la page à la place, VocalStack la demande, voit du HTML en retour et vous le signale. Chaque station cache son flux un peu différemment ; la plupart le dissimulent derrière un bouton intitulé « Écouter », et c’est bien le seul élément de la page sur lequel il ne vaut pas la peine de cliquer.
Deux types de liens sont refusés d’emblée. Les liens vers des pages qui diffusent des médias, comme Spotify, SoundCloud ou Twitch, sont écartés avant toute connexion. Les flux protégés par copie ne sont pas non plus pris en charge : une playlist ou un manifeste qui nécessite une licence DRM échoue avec un message qui le dit. Certains flux refusent aussi les requêtes venant hors du pays de la station, si bien qu’une adresse qui fonctionne au bureau peut ne pas fonctionner depuis un serveur à l’étranger. Si un flux se lit dans un navigateur mais pas dans VocalStack, c’est que la station refuse les autres lecteurs ; demandez-lui une adresse que d’autres applications sont autorisées à utiliser. La plupart proposent un flux MP3, AAC ou HLS. Une fois la bonne adresse trouvée, reste la question de savoir si elle finit un jour.
Un flux en direct ne se termine jamais, il n’est donc pas un fichier. La distinction compte surtout pour YouTube. Un live YouTube à l’antenne relève d’une transcription en direct, et le tableau de bord le suit pendant sa diffusion. Un live YouTube programmé mais pas encore commencé s’affiche comme Not live yet et peut être enregistré une fois à l’antenne. Une vidéo terminée est tout autre chose : elle a une durée, elle se transcrit donc comme un fichier. Collez le lien dans Transcriptions → New.
La playlist elle-même indique de quel cas il s’agit, et c’est ainsi que tout lecteur fait la différence. Une playlist HLS terminée porte une balise #EXT-X-ENDLIST ou #EXT-X-PLAYLIST-TYPE:VOD ; une playlist en direct n’en porte aucune et ne cesse de grandir, si bien que le lecteur la récupère toutes les quelques secondes pour obtenir de nouveaux segments. Un manifeste DASH déclare type="dynamic" tant que la diffusion est à l’antenne et type="static" une fois qu’il s’agit d’un enregistrement. Un flux MP3 ou AAC issu d’un serveur Icecast n’a pas de durée du tout : il ne s’arrête tout simplement jamais.
Depuis le code, GET /v1/transcriptions/probe?url= tranche la question avant que quoi que ce soit ne soit enregistré. Le champ kind de la réponse vaut live pour un live YouTube à l’antenne ou programmé, un flux HTTP sans fin, une playlist HLS sans fin ou un manifeste DASH dynamique. Il vaut file pour tout ce qui a une fin, et unknown lorsque la sonde n’a pas pu trancher. Quand le lien ne s’est pas ouvert comme média, ok vaut false et problem est une phrase que vous pouvez afficher. La sonde ne conserve rien et est limitée à 60 appels par minute.
Les transcriptions de fichiers vont beaucoup plus vite que la lecture du son : une heure de télévision terminée ne prend pas une heure. Un flux en direct se transcrit en temps réel, mais le « temps réel » accuse déjà un retard sur la diffusion, et il vaut la peine de savoir de combien. Un flux Icecast atteint un lecteur quelques secondes après le micro. HLS et DASH sont découpés en segments, et un lecteur ne démarre qu’une fois qu’il en détient deux ou trois d’environ six secondes chacun ; un flux HLS accuse donc généralement 10 à 30 secondes de retard sur la diffusion, avant que la transcription n’ajoute son propre délai. Une ligne qui semble arriver tard est en général le retard de la station, pas celui du transcripteur. Un flux produit un enregistrement ; une rédaction en fait tourner plusieurs, et ils finissent tous au même endroit.
Chaque transcription en direct arrive dans la bibliothèque des transcriptions, à côté de tous les fichiers. Chaque enregistrement est conservé avec sa transcription et, une fois les mots définitifs, un titre et un résumé lui sont rédigés, dans chaque langue. La langue parlée est détectée automatiquement, et les intervenants peuvent changer de langue à tout moment. Lorsque vous connaissez la langue, la nommer améliore la qualité de la transcription.
La bibliothèque est consultable dans toutes les langues : recherchez dans toutes les transcriptions, quelle que soit leur langue, et obtenez les résultats dans la vôtre. Un journaliste qui ne lit que l’anglais peut chercher dans l’émission du matin de la station roumaine le nom d’un ministre et lire les résultats en anglais, chacun accompagné de la transcription d’origine et de l’instant où il a été prononcé. Le nom du ministre sera écrit de trois façons différentes selon les trois stations ; le chercher en anglais évite de lire les trois versions.
Une transcription peut être traduite en 10 langues au maximum à la fois, pour que le même enregistrement se lise dans chaque langue que parle la rédaction. Un résultat de recherche n’est utile que si l’on peut le citer.
Une transcription n’est pas un bloc de texte. L’API GET /v1/recordings/{id}/transcript renvoie sentences, les segments avec leurs temps par mot, et speakers, si bien qu’une citation se place à la seconde près dans l’enregistrement. Le tableau de bord rejoue un enregistrement en direct tel qu’il est arrivé, avec son audio, de sorte qu’une phrase peut être écoutée avant d’être citée.
Avant de faire confiance à une transcription de contenu radio, quel que soit le système, deux choses valent la peine d’être sues. La reconnaissance vocale trébuche surtout sur les noms propres, les lieux et les chiffres, précisément ce que cherche un journaliste. Un nom que le système n’a jamais entendu ressort sous le mot courant le plus proche, et une recherche de la bonne orthographe le manque. Cherchez plutôt un mot distinctif prononcé dans le même souffle, puis lisez le contexte autour du résultat. Et la radio n’est pas faite que de parole : les fonds musicaux, les jingles et les coupures publicitaires produisent des lignes qui ressemblent à des phrases sans en être. Écoutez l’audio avant de citer.
Les étiquettes d’intervenant ont trois réglages : désactivé, activé ou When Needed, qui affiche les étiquettes dès qu’un second intervenant est entendu. Vous pouvez nommer un intervenant dans un enregistrement (PUT /v1/recordings/{id}/speakers/{idx}), et, une fois la voix d’un intervenant enregistrée, les enregistrements suivants le reconnaissent par son nom. Pour une station dont les présentateurs reviennent chaque matin, les étiquettes cessent d’être « Speaker 2 » après la première semaine. Une fois la citation vérifiée, elle doit sortir de la rédaction.
Chaque format de l’onglet Export d’une transcription a un rôle dans une rédaction. Le SRT part vers le monteur vidéo, pour qu’un extrait du flux soit accompagné de sous-titres ; un SRT traduit les porte dans une autre langue. Le format Excel va au documentaliste, une ligne par phrase avec son horodatage, à filtrer et annoter. Le PDF va à l’éditeur qui veut lire toute l’heure dans le train. Le JSON va à celui qui écrit les outils internes de la rédaction. Via l’API, l’export se fait par GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, avec lang= pour une version traduite. Download audio fournit l’enregistrement en MP3 pour le dossier lui-même.
Surveiller une diffusion à des fins de reportage est une pratique courante en rédaction. Republier un extrait en est une autre. Elle est régie par l’usage loyal ou le fair use là où vous vous trouvez, ainsi que par les conditions propres de la station ; les règles habituelles de la rédaction sur la citation d’un concurrent s’appliquent donc aussi à l’audio du concurrent. Tout ce qui précède se fait en quelques clics dans le tableau de bord ; pour une rédaction qui suit vingt stations, il vaut mieux l’automatiser par script.
Tout le parcours est dans l’API, inclus dans chaque forfait et facturé au même tarif que le tableau de bord. Une transcription en direct dont la source est un flux est créée en attente, lancée par son premier enregistrement, et pilotée en HTTP. Comme c’est le serveur qui récupère l’audio, démarrer un enregistrement ne renvoie aucun flux à alimenter : rien de votre côté n’envoie d’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"
La clé Idempotency-Key fait qu’une création réessayée renvoie la première transcription au lieu d’en créer une seconde. Les SDK TypeScript et Python encapsulent les mêmes appels et se téléchargent depuis l’espace Developers ; la référence de l’API détaille chaque route et ses trames.
Un agent IA peut parcourir la bibliothèque sans aucun code. Le serveur MCP sur /v1/mcp donne à l’agent un ensemble d’outils ; quatre comptent ici. search_transcriptions recherche ce qui a été dit dans les transcriptions du compte, dans n’importe quelle langue, et renvoie les lignes correspondantes, chacune avec la transcription où elle se trouve et l’instant où elle a été prononcée. get_summary renvoie le résumé d’un enregistrement. transcribe_url et wait_for_transcription transcrivent une vidéo terminée ou le lien d’un enregistrement, et attendent le résultat. Lancer une surveillance de flux en direct reste dans le tableau de bord ou dans l’API ci-dessus. La configuration pour Claude Code, Cursor ou tout client Streamable HTTP se trouve sous Developers → Connect an AI agent ; l’article sur MCP la détaille. Reste enfin la question du coût de ce script.
La transcription en direct coûte $0.60 de l’heure d’audio, facturée à la seconde ($0.01 la minute), avec un minimum de 5 minutes par transcription. Le direct coûte plus cher qu’un fichier parce qu’il est transcrit au moment où il se produit, aussi longtemps qu’il dure. Les fichiers coûtent $0.20 de l’heure ($0.0033 la minute ; un fichier de 30 minutes coûte $0.10). Les tarifs sont les mêmes dans chaque forfait et via l’API, et les traductions, les résumés, la dénomination des intervenants, la diffusion et le partage ne s’ajoutent jamais à la facture.
Une station suivie huit heures par jour, cinq jours par semaine, représente 40 heures de direct : $24 par semaine, quelle que soit la langue dans laquelle la rédaction la lit.
Les limites qui comptent pour la surveillance varient selon le forfait. Chacune est indiquée dans l’ordre Paiement à l’usage, Premium, Enterprise :
Un nouveau compte reçoit un crédit d’inscription de $5 sans carte bancaire, ce qui suffit à plus de huit heures de surveillance en direct pour l’essayer. Le tableau complet figure sur la page tarifs.