Dán luồng, không dán trang. Âm thanh thật của đài nằm ở một địa chỉ kết thúc bằng .mp3, .aac hoặc .m3u8, và khi phiên âm trực tiếp đã nhận được nó, không ai cần phải ngồi nghe.
Một tòa soạn theo dõi ba đài phát thanh, hai luồng truyền hình và vài buổi YouTube trực tiếp thì trước hết gặp vấn đề nhân sự chứ chưa phải vấn đề phiên âm. Phải có người ngồi nghe, và phải có người bấm ghi. Phiên âm trực tiếp với một luồng làm nguồn đảm nhận cả hai việc: bạn đưa địa chỉ luồng, máy chủ sẽ mở luồng, giải mã và phiên âm khi luồng đang phát, nên không ai phải ngồi ở bàn khi buổi họp báo bắt đầu sớm. Phần khó, hóa ra, là tìm được địa chỉ đó.
Phiên âm trực tiếp có thể lấy âm thanh từ một luồng mà máy chủ tự kéo về: một đài phát thanh internet, một danh sách phát HLS (.m3u8), một manifest DASH (.mpd), hoặc một buổi YouTube trực tiếp. Trong Bảng điều khiển, đây là một phiên âm trực tiếp mới tại Transcriptions → New → Live, với nguồn là một luồng thay vì micro. Địa chỉ được thiết lập khi phiên âm được tạo và không bao giờ thay đổi, nên một bộ giám sát chỉ cần cài một lần, rồi bật lên mỗi khi đài đáng để ghi lại.
Địa chỉ phải là chính luồng, không phải trang web phát luồng đó. Trang của đài là HTML; âm thanh mà trang phát thường đến từ một nơi khác, thường là máy chủ Icecast hoặc Shoutcast, và trình phát trên trang tìm ra địa chỉ đó bằng JavaScript sau khi trang tải xong. Hãy tìm trên trang một liên kết ghi "Listen", "Direct stream" hoặc "Other players": nó kết thúc bằng .mp3, .aac, .m3u, .m3u8 hoặc .pls. Một tệp .pls hay .m3u cũng không phải là âm thanh. Đó là một tệp văn bản ngắn vài dòng, mỗi dòng ghi địa chỉ của một luồng; nó tồn tại để các trình phát trên máy tính có thể nhận một liên kết duy nhất, và VocalStack sẽ phiên âm luồng mà tệp đó trỏ tới. Nếu bạn dán trang thay vì luồng, VocalStack sẽ yêu cầu trang, thấy HTML trả về và báo cho bạn biết. Mỗi đài giấu luồng theo một cách hơi khác nhau; đa số giấu sau một nút có chữ "Listen", và đó là thứ duy nhất trên trang không đáng bấm vào.
Có hai loại liên kết bị từ chối ngay. Liên kết đến các trang phát media, như Spotify, SoundCloud hay Twitch, bị chặn trước khi kết nối. Luồng có bảo vệ bản quyền cũng không được hỗ trợ: danh sách phát hoặc manifest cần giấy phép DRM sẽ thất bại kèm thông báo nói rõ điều đó. Một số luồng còn từ chối yêu cầu từ ngoài quốc gia của đài, nên địa chỉ phát được trong văn phòng có thể không phát được từ máy chủ ở nước ngoài. Nếu một luồng phát được trên trình duyệt nhưng không phát được trong VocalStack, đài đang từ chối các trình phát khác; hãy hỏi đài một địa chỉ mà các ứng dụng khác được phép dùng. Phần lớn đài đều cung cấp luồng MP3, AAC hoặc HLS. Khi đã có đúng địa chỉ, câu hỏi tiếp theo là luồng đó có bao giờ kết thúc không.
Luồng trực tiếp không bao giờ kết thúc, nên nó không phải là một tệp. Sự khác biệt này đặc biệt quan trọng với YouTube. Một buổi YouTube trực tiếp đang phát thuộc về một phiên âm trực tiếp, và Bảng điều khiển sẽ theo dõi nó khi nó đang lên sóng. Một buổi YouTube trực tiếp đã lên lịch nhưng chưa bắt đầu sẽ hiển thị Not live yet và có thể ghi lại khi đã lên sóng. Một video đã xong là chuyện khác: nó có độ dài, nên được phiên âm như một tệp. Hãy dán liên kết vào Transcriptions → New.
Chính danh sách phát cho biết nó thuộc loại nào, và đó là cách mọi trình phát phân biệt. Một danh sách phát HLS đã xong có thẻ #EXT-X-ENDLIST hoặc #EXT-X-PLAYLIST-TYPE:VOD; một danh sách trực tiếp không có cả hai và cứ dài thêm, nên trình phát tải lại nó vài giây một lần để lấy các đoạn mới. Một manifest DASH khai báo type="dynamic" khi buổi phát đang lên sóng và type="static" khi nó đã thành bản ghi. Luồng MP3 hoặc AAC từ máy chủ Icecast không có độ dài nào cả; nó chỉ không bao giờ dừng.
Từ mã nguồn, GET /v1/transcriptions/probe?url= xác định điều này trước khi bất kỳ thứ gì được lưu. Trường kind trong phản hồi là live đối với một buổi YouTube trực tiếp đang phát hoặc đã lên lịch, một luồng HTTP không dứt, một danh sách phát HLS không có điểm kết thúc, hoặc một manifest DASH dynamic. Giá trị là file với mọi thứ có điểm kết thúc, và unknown khi probe không xác định được. Khi liên kết không mở được như media, ok là false và problem là một câu bạn có thể hiển thị. Probe không lưu lại gì và giới hạn 60 lượt gọi mỗi phút.
Phiên âm tệp chạy nhanh hơn âm thanh phát nhiều lần, nên một giờ truyền hình đã xong không mất một giờ để xử lý. Luồng trực tiếp được phiên âm theo thời gian thực, nhưng "thời gian thực" vẫn chậm hơn buổi phát một chút, và đáng biết chậm bao nhiêu. Một luồng Icecast đến trình phát chậm vài giây so với micro. HLS và DASH được chia thành các đoạn, và trình phát sẽ không bắt đầu cho đến khi giữ được hai hoặc ba đoạn, mỗi đoạn khoảng sáu giây, nên luồng HLS thường chậm 10 đến 30 giây so với buổi phát trước khi phiên âm cộng thêm độ trễ riêng. Một dòng chữ có vẻ đến muộn thường là độ trễ của đài, không phải của bộ phiên âm. Mỗi luồng tạo ra một bản ghi; một bàn biên tập chạy nhiều luồng, và tất cả đều đổ về cùng một nơi.
Mọi phiên âm trực tiếp đều vào thư viện Transcriptions cùng với mọi tệp. Mỗi bản ghi được lưu cùng bản phiên âm của nó, và khi lời nói đã cố định, tiêu đề và bản tóm tắt được viết cho nó, bằng mọi ngôn ngữ. Ngôn ngữ nói được tự động nhận diện, và người nói có thể đổi ngôn ngữ bất cứ lúc nào. Nếu bạn biết ngôn ngữ, chọn sẵn sẽ cải thiện chất lượng phiên âm.
Thư viện có thể tìm kiếm xuyên ngôn ngữ: tìm trong mọi bản phiên âm, bất kể ngôn ngữ nào, và nhận kết quả bằng ngôn ngữ của bạn. Một phóng viên chỉ đọc tiếng Anh có thể tìm tên một bộ trưởng trong chương trình buổi sáng của đài Romania và đọc kết quả bằng tiếng Anh, mỗi kết quả kèm bản phiên âm gốc và thời điểm được nói. Tên bộ trưởng sẽ được viết theo ba cách khác nhau ở ba đài; tìm bằng tiếng Anh giúp bạn khỏi phải đọc cả ba.
Một bản phiên âm có thể được dịch sang tối đa 10 ngôn ngữ cùng lúc, để cùng một bản ghi đọc được bằng mọi ngôn ngữ mà bàn biên tập làm việc. Kết quả tìm kiếm chỉ hữu ích khi bạn có thể trích dẫn nó.
Bản phiên âm không phải là một khối chữ liền nhau. GET /v1/recordings/{id}/transcript của API trả về sentences, segments kèm thời gian từng từ, và speakers, nên một trích dẫn có thể đặt chính xác đến từng giây trong bản ghi. Bảng điều khiển phát lại một bản ghi trực tiếp đúng như khi nó được thu, cùng âm thanh, nên bạn có thể nghe một câu trước khi trích dẫn nó.
Trước khi tin bất kỳ bản phiên âm âm thanh radio nào, từ hệ thống nào, có hai điều đáng biết. Nhận dạng giọng nói dễ vấp nhất ở tên riêng, địa danh và con số, chính là những thứ phóng viên tìm kiếm. Một cái tên mà bộ nhận dạng chưa từng gặp sẽ bị thay bằng từ thường gần nhất, và tìm đúng chính tả sẽ không ra. Thay vào đó, hãy tìm một từ đặc trưng được nói ngay trong cùng một hơi, rồi đọc xung quanh kết quả. Và radio không chỉ có lời nói: nền nhạc, jingle và quảng cáo tạo ra những dòng trông như câu nhưng không phải. Hãy kiểm tra âm thanh trước khi trích dẫn.
Nhãn người nói có ba cài đặt: tắt, bật, hoặc When Needed, cài đặt này chỉ hiện nhãn khi nghe thấy người nói thứ hai. Bạn có thể đặt tên cho một người nói trong một bản ghi (PUT /v1/recordings/{id}/speakers/{idx}), và khi giọng của người nói đã được đăng ký, các bản ghi sau sẽ nhận ra họ theo tên. Với một đài có các người dẫn chương trình lên sóng mỗi sáng, nhãn sẽ không còn là "Speaker 2" sau tuần đầu tiên. Khi trích dẫn đã được kiểm chứng, nó phải được đưa ra khỏi tòa soạn.
Mỗi định dạng trên tab Export của một phiên âm có một việc trong tòa soạn. SRT đi đến người biên tập video, nên một đoạn cắt từ luồng có phụ đề; một SRT đã dịch mang phụ đề bằng ngôn ngữ khác. Excel đi đến nhà nghiên cứu, mỗi dòng một câu kèm thời gian, để lọc và chú thích. PDF đi đến biên tập viên muốn đọc cả giờ trên tàu. JSON đi đến người đang viết công cụ riêng của bàn biên tập. Qua API, xuất là GET /v1/recordings/{id}/export?format=srt|json|xlsx|pdf, với lang= cho bản đã dịch. Download audio cho ra bản ghi dạng MP3 để đưa vào chính bài báo.
Theo dõi một buổi phát để đưa tin là việc thường thấy trong nghề báo. Đăng lại một đoạn trích của nó là chuyện khác. Việc đó chịu sự điều chỉnh của quy định về sử dụng hợp lý hoặc sử dụng công bằng tại nơi bạn ở, và của điều khoản riêng của đài, nên quy tắc thông thường của bàn biên tập khi trích dẫn một đối thủ cũng áp dụng cho âm thanh của đối thủ. Mọi điều trên chỉ cần vài cú nhấp trong Bảng điều khiển; với một bàn biên tập có hai mươi đài, viết thành script sẽ tốt hơn.
Toàn bộ quy trình đều có trong API, có trong mọi gói và được tính giá giống Bảng điều khiển. Một phiên âm trực tiếp có nguồn là luồng được tạo ở trạng thái rảnh, bắt đầu khi có bản ghi đầu tiên, và được điều khiển qua HTTP. Vì máy chủ tự kéo âm thanh, khi bắt đầu ghi sẽ không có luồng nào để bạn đẩy lên: phía bạn không có gì gửi âm thanh đi cả.
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 giúp một lần tạo được thử lại trả về phiên âm đầu tiên thay vì tạo thêm một phiên âm nữa. Các SDK TypeScript và Python bọc cùng các lệnh gọi này và được tải về từ khu vực Developers; tài liệu API liệt kê mọi route và các frame của nó.
Một tác tử AI có thể làm việc với thư viện mà không cần viết mã nào. Máy chủ MCP tại /v1/mcp cấp cho tác tử một bộ công cụ; trong số đó, bốn công cụ đáng chú ý ở đây. search_transcriptions tìm những gì đã được nói trong mọi phiên âm của tài khoản, bằng mọi ngôn ngữ, và trả về các dòng khớp, mỗi dòng kèm phiên âm chứa nó và thời điểm được nói. get_summary trả về bản tóm tắt của một bản ghi. transcribe_url và wait_for_transcription phiên âm một video đã xong hoặc liên kết của một bản ghi, rồi chờ kết quả. Việc bắt đầu giám sát một luồng trực tiếp vẫn thuộc về Bảng điều khiển hoặc API ở trên. Cách thiết lập cho Claude Code, Cursor hay bất kỳ client Streamable HTTP nào nằm trong Developers → Connect an AI agent; bài viết về MCP hướng dẫn từng bước. Chi phí để chạy kịch bản này là câu hỏi cuối cùng.
Phiên âm trực tiếp là $0.60 mỗi giờ âm thanh, tính theo từng giây ($0.01 mỗi phút), với mức tối thiểu 5 phút cho mỗi phiên âm. Trực tiếp đắt hơn tệp vì nó được phiên âm ngay khi diễn ra, trong suốt thời gian chạy. Tệp là $0.20 mỗi giờ ($0.0033 mỗi phút; một tệp 30 phút có giá $0.10). Mức giá giống nhau ở mọi gói và qua API; bản dịch, bản tóm tắt, đặt tên người nói, phát sóng và chia sẻ không bao giờ làm tăng hóa đơn.
Một đài được giám sát tám giờ mỗi ngày, năm ngày mỗi tuần, là 40 giờ trực tiếp: $24 mỗi tuần, bất kể bàn biên tập đọc bằng bao nhiêu ngôn ngữ.
Các giới hạn quan trọng với việc giám sát khác nhau theo gói. Mỗi giới hạn được liệt kê theo thứ tự Trả theo mức dùng, Premium, Enterprise:
Tài khoản mới bắt đầu với $5 tín dụng đăng ký và không cần thẻ, đủ để thử hơn tám giờ giám sát trực tiếp. Bảng đầy đủ nằm trên trang bảng giá.