페이지가 아니라 스트림을 붙여 넣으세요. 방송국의 실제 오디오는 .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)가 적용된 스트림도 지원되지 않습니다. 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"을 선언합니다. Icecast 서버의 MP3 또는 AAC 스트림에는 길이가 전혀 없으며, 그냥 끝나지 않습니다.
코드에서는 GET /v1/transcriptions/probe?url=을 호출해 무엇이든 저장하기 전에 이를 확인할 수 있습니다. 응답의 kind는 방송 중이거나 예정된 YouTube 라이브, 끝이 없는 HTTP 스트림, 끝이 없는 HLS 재생 목록, 또는 dynamic DASH 매니페스트이면 live입니다. 끝이 있는 것이면 file이고, 판별할 수 없으면 unknown입니다. 링크가 미디어로 열리지 않으면 ok는 false이고, problem에 보여 줄 수 있는 문장이 담깁니다. probe는 아무것도 저장하지 않으며 분당 60회로 제한됩니다.
파일 전사는 오디오가 재생되는 속도보다 몇 배 빠르게 진행되므로, 종료된 한 시간짜리 텔레비전 방송도 한 시간이 걸리지 않습니다. 라이브 스트림은 실시간으로 전사되지만, '실시간'이라고 해도 방송보다 얼마간 뒤처지며, 그 차이가 얼마인지 알아 두는 것이 좋습니다. Icecast 스트림은 마이크에서 소리가 나고 몇 초 뒤에 플레이어에 도달합니다. HLS와 DASH는 세그먼트로 나뉘어 있고, 플레이어는 각각 약 6초인 세그먼트를 두세 개 확보할 때까지 재생을 시작하지 않으므로, 전사가 자체 지연을 더하기 전에도 HLS 스트림은 보통 방송보다 10~30초 뒤처집니다. 늦게 도착하는 것처럼 보이는 줄은 대개 전사기의 지연이 아니라 방송국의 지연입니다. 스트림 하나가 녹음 하나를 만들고, 데스크에서 여러 개를 돌리더라도 모두 같은 곳에 모입니다.
모든 실시간 전사는 파일과 나란히 Transcriptions 라이브러리에 저장됩니다. 각 녹음은 전사본과 함께 보관되며, 단어가 확정되면 모든 언어로 제목과 요약이 작성됩니다. 말하는 언어는 자동으로 감지되며, 화자는 언제든 언어를 바꿀 수 있습니다. 언어를 알고 있다면 지정하는 것이 전사 품질을 높입니다.
라이브러리는 언어를 넘어 검색할 수 있습니다. 모든 전사본을 언어와 관계없이 검색하고, 결과를 자신의 언어로 받을 수 있습니다. 영어만 읽는 기자는 루마니아 방송국의 아침 프로그램에서 장관의 이름을 검색해 영어로 결과를 읽을 수 있으며, 각 결과에는 그 결과가 나온 전사와 말한 시간이 함께 표시됩니다. 세 방송국에서 장관의 이름은 세 가지 다른 철자로 표기되겠지만, 영어로 검색하면 셋을 모두 읽을 필요가 없습니다.
전사는 한 번에 최대 10개 언어로 번역할 수 있으므로, 같은 녹음을 데스크가 다루는 모든 언어로 읽을 수 있습니다. 검색 결과는 인용할 수 있을 때만 쓸모가 있습니다.
전사본은 긴 글 덩어리가 아닙니다. API의 GET /v1/recordings/{id}/transcript는 sentences, 단어 타이밍이 있는 segments, 그리고 speakers를 반환하므로, 인용문을 녹음의 몇 초 지점에 정확히 맞출 수 있습니다. 대시보드는 라이브 녹음을 도착한 그대로 오디오와 함께 다시 재생하므로, 인용하기 전에 문장을 직접 들어 볼 수 있습니다.
라디오 오디오의 전사를 신뢰하기 전에는, 어떤 시스템에서 나온 것이든 두 가지를 알아 두는 것이 좋습니다. 음성 인식은 고유명사, 지명, 숫자에서 가장 많이 실수하는데, 바로 기자가 검색하는 것들입니다. 인식기가 한 번도 본 적 없는 이름은 가장 가까운 일반 단어로 나오므로, 정확한 철자로 검색하면 결과를 놓치게 됩니다. 대신 같은 숨결에 말해진 구별되는 단어를 검색한 뒤 그 주변을 읽으세요. 그리고 라디오가 전부 음성은 아닙니다. 배경 음악, 징글, 광고 방송은 문장처럼 보이지만 문장이 아닌 줄을 만들어 냅니다. 인용하기 전에 오디오를 확인하세요.
화자 라벨에는 세 가지 설정이 있습니다. 끄기, 켜기, 또는 When Needed이며, 이 설정은 두 번째 화자가 들리는 순간 라벨을 표시합니다. 녹음 안에서 화자에게 이름을 붙일 수 있고(PUT /v1/recordings/{id}/speakers/{idx}), 화자의 목소리가 등록되면 이후 녹음에서는 이름으로 인식합니다. 매일 아침 돌아오는 진행자가 있는 방송국이라면, 첫 주가 지나면 라벨이 '화자 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를 사용하면 재시도한 생성 요청이 두 번째 전사를 만드는 대신 처음 만든 전사를 반환합니다. TypeScript와 Python SDK는 같은 호출을 감싸 제공하며, Developers 영역에서 내려받을 수 있습니다. API 레퍼런스에는 모든 경로와 그 프레임이 있습니다.
AI 에이전트는 코드 없이도 라이브러리를 다룰 수 있습니다. /v1/mcp의 MCP 서버는 에이전트에 도구 세트를 제공하며, 그중 여기서 중요한 것은 네 가지입니다. search_transcriptions는 계정의 모든 전사에서 언어와 관계없이 말해진 내용을 검색하고, 일치하는 줄을 각 줄이 속한 전사 및 말한 시간과 함께 반환합니다. get_summary는 녹음의 요약을 반환합니다. transcribe_url과 wait_for_transcription은 완료된 영상이나 녹음의 링크를 전사하고 결과를 기다립니다. 라이브 스트림 모니터를 시작하는 일은 위의 대시보드나 API에 남아 있습니다. Claude Code, Cursor 또는 Streamable HTTP를 지원하는 모든 클라이언트의 설정은 Developers → Connect an AI agent 아래에 있으며, MCP 아티클에서 단계별로 안내합니다. 마지막 질문은 이 스크립트를 실행하는 데 드는 비용입니다.
실시간 전사는 오디오 1시간당 $0.60이며, 초 단위로 청구됩니다(분당 $0.01). 전사 하나당 최소 5분이 적용됩니다. 실시간은 방송이 진행되는 동안 전사하고 그 시간만큼 계속 실행되므로 파일보다 비쌉니다. 파일은 1시간당 $0.20입니다(분당 $0.0033이며, 30분짜리 파일은 $0.10입니다). 요율은 모든 요금제와 API에서 동일하며, 번역, 요약, 화자 이름 지정, 방송 및 공유는 청구 금액을 늘리지 않습니다.
하루 여덟 시간, 주 5일 방송국을 모니터링하면 주 40시간의 라이브이며, 어떤 언어로 읽든 주 $24입니다.
모니터링에 중요한 한도는 요금제마다 다릅니다. 각 항목은 Pay as you go, Premium, Enterprise 순서로 나열합니다.
새 계정은 카드 없이 $5 가입 크레딧을 받으며, 이는 라이브 모니터링을 여덟 시간 넘게 시험해 볼 수 있는 금액입니다. 전체 표는 요금제 페이지에 있습니다.