Websocket Api
注意:此為合併版文件。詳細規格請參考 reference/websocket/ 下的獨立文件。
注意:本文件中的網址(
vas-poc.vurbo.ai)為預計部署網址,正式上線後將另行通知。
目錄
- 連線資訊
- 認證方式
- 訊息格式
- Health - 心跳服務
- Voice Translation - start
- Voice Translation - config
- Voice Translation - audio
- Voice Translation - pause
- Voice Translation - resume
- Voice Translation - stop
- Voice Translation - retranslate
- Voice Translation - switch_language
- Voice Translation - set_name
- Voice Translation - rename_speaker
- Voice Translation - reassign_speaker
- Voice Translation - merge_speakers
- Voice Translation - tts_play
- Voice Translation - tts_stop
- Voice Translation - tts_mode
- Voice Translation - set_tts
- Voice Translation - start_speaking
- Voice Translation - stop_speaking
- Voice Translation - switch_conversation_mode
- Voice Translation - set_speaker_language
- Voice Translation - broadcast_go_live
- Voice Translation - broadcast_announcement
- Voice Translation - set_standby_message
- 回應事件
連線資訊
| 項目 | 值 |
|---|---|
| 端點 | wss://vas-poc.vurbo.ai/ws |
| 協定 | WebSocket |
| 資料格式 | JSON |
| 認證方式 | Ticket(見下方) |
認證方式
VAS WebSocket 使用 Ticket 機制 進行認證,透過 Sec-WebSocket-Protocol 傳遞一次性 Ticket。詳細說明請參考 認證機制。
步驟 1:取得 Ticket
使用 API Key 向 REST API 換取一次性 Ticket:
POST /api/v1/auth/ticket
X-API-Key: vas_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
回應:
{
"ticket": "aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
"expires_in": 60
}
| 欄位 | 類型 | 說明 |
|---|---|---|
ticket | string | 一次性 Ticket(32 字元) |
expires_in | int | 有效期(秒) |
步驟 2:使用 Ticket 連線 WebSocket
將 Ticket 放入 Sec-WebSocket-Protocol,格式為 ticket.{TICKET_VALUE}:
// 瀏覽器原生支援
const ws = new WebSocket('wss://vas-poc.vurbo.ai/ws', [`ticket.${ticket}`]);
ws.onopen = () => {
console.log('Connected! Protocol:', ws.protocol);
// 開始使用 WebSocket...
};
ws.onerror = (error) => {
console.error('Connection failed:', error);
};
Node.js 範例:
const WebSocket = require('ws');
const ws = new WebSocket('wss://vas-poc.vurbo.ai/ws', [`ticket.${ticket}`]);
Ticket 特性
| 特性 | 說明 |
|---|---|
| 有效期 | 60 秒 |
| 使用次數 | 僅能使用一次(使用後立即刪除) |
| 安全性 | API Key 不會暴露在 WebSocket 連線中 |
| 防重放攻擊 | 使用原子操作確保一次性 |
Ticket 錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 |
|---|---|---|
ticket_invalid | 401 | Ticket 無效或已過期 |
ticket_expired | 401 | Ticket 已過期 |
ticket_already_used | 401 | Ticket 已被使用 |
ticket_validation_failed | 500 | Ticket 驗證失敗 |
完整 API 規格請參考 Auth Ticket API。
訊息格式
所有訊息使用統一的巢狀結構:
{
"type": "服務類型",
"data": { ... }
}
服務類型
| type | 說明 |
|---|---|
health | 心跳機制 |
voice-translation | 語音翻譯服務 |
error | 錯誤訊息 |
錯誤訊息格式
當發生錯誤時,伺服器會回傳 type: "error" 的訊息:
{
"type": "error",
"data": {
"error_code": "auth_invalid_api_key",
"severity": "fatal",
"message": "API Key 無效",
"context": "auth",
"request_id": "req_abc123xyz789",
"timestamp": "2026-01-15T10:30:45.123Z"
}
}
句子級錯誤(如某句的某個語言翻譯失敗)會額外帶上 sid 與 details:
{
"type": "error",
"data": {
"error_code": "llm_content_filtered",
"severity": "warning",
"message": "LLM 內容被過濾",
"context": "translation",
"sid": 5,
"request_id": "req_abc123xyz789",
"timestamp": "2026-01-15T10:30:45.123Z",
"details": {
"provider": "azure_openai",
"translation_language": "ja"
}
}
}
Session-level 翻譯服務錯誤(連續失敗達閾值升級)不帶 sid,前端應顯示全域提示但不需斷線:
{
"type": "error",
"data": {
"error_code": "translation_service_unavailable",
"severity": "error",
"message": "Translation service unavailable",
"context": "translation",
"request_id": "req_abc123xyz789",
"timestamp": "2026-01-15T10:30:45.123Z",
"details": {
"provider": "azure_openai",
"last_error_code": "llm_provider_error",
"fail_count": 5
}
}
}
完整觸發規則(連續失敗閾值、錯誤碼分類)請參考 錯誤碼參考 中的
translation_service_unavailable區塊。
單一訊息錯誤(per-message panic recovered)
當伺服器在處理單一 WebSocket 訊息(如 set_name、switch_language、tts_play 等)時發生內部錯誤(panic),會回傳 internal_error。此錯誤僅代表該則訊息處理失敗,連線不會被終結,前端應保持連線並可重試該操作:
{
"type": "error",
"data": {
"error_code": "internal_error",
"severity": "error",
"message": "Internal server error",
"context": "general",
"request_id": "req_abc123xyz789",
"timestamp": "2026-05-08T10:30:45.123Z",
"details": {
"message_type": "voice-translation",
"action": "set_name"
}
}
}
details 欄位
| 欄位 | 類型 | 說明 |
|---|---|---|
message_type | string | 服務類型:voice-translation / health |
action | string | (可選)失敗的具體操作,如 set_name、switch_language、tts_play、tts_mode、retranslate、config、speaker.rename 等。當訊息 payload 無 action 欄位(如純 init 訊息)時不會出現此欄位。 |
前端應做什麼
- 保持 WebSocket 連線:不要因為收到此錯誤而呼叫
ws.close()、跳轉頁面、或回到歷史頁。錄音仍在進行中。 - 依
details.action判斷後續處理:情境 建議動作 set_name/switch_language/tts_mode/config等冪等操作直接重送同一則訊息即可。這類操作以「最後一次寫入」為準,重試不會造成副作用。 tts_play/tts_stop/retranslate通常可直接重試;若使用者在等待 TTS 播放,建議顯示一個 transient toast 提示重試中。 speaker.rename/speaker.merge重試前先用 REST API(speakers) 確認當前 DB 狀態,避免重複操作(例如 rename 已成功只是回應 frame 失敗)。 details.action不存在表示伺服器在訊息 payload 解析後才 panic、無法回推具體操作。前端可依「使用者最近送出的訊息」反推;或顯示通用錯誤訊息「操作失敗,請重試」。 - 使用者體驗:建議顯示 transient toast / inline error,不要用 modal 或 redirect 中斷使用者流程。
- 遙測 / 上報:建議把
request_id+details上報到前端 error tracking(Sentry / Datadog 等),方便對應後端 log 排查。
不會發生的事(保證項)
- ✅ 錄音不會中斷:
segment_uploaded、result、origin等訊息會持續送達 - ✅ 連線不會被伺服器主動關閉
- ✅ session 狀態不會被重置(
session_id不變) - ✅ DB 中已寫入的狀態不會回滾(例如
set_name若 DB 寫入成功、僅回應 frame 失敗,名稱仍會生效)
Client 處理範例
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type !== 'error') {
handleNormalMessage(msg);
return;
}
const { error_code, severity, request_id, details } = msg.data;
// 單一訊息 panic:保持連線、視 action 決定是否重試
if (error_code === 'internal_error') {
console.warn('[ws] message handler panic recovered', {
request_id,
message_type: details?.message_type,
action: details?.action,
});
showTransientToast(`「${details?.action ?? '操作'}」處理失敗,請重試`);
// 注意:不呼叫 ws.close()、不導離當前頁
return;
}
// 其他錯誤照原本邏輯處理(含 fatal 等致命錯誤才需要斷連)
handleErrorBySeverity(severity, msg.data);
};
| 欄位 | 類型 | 說明 |
|---|---|---|
error_code | string | 錯誤碼(程式化處理用) |
severity | string | 嚴重程度:fatal / error / warning |
message | string | 人類可讀的錯誤訊息 |
context | string | 錯誤來源分類 |
sid | int | 可選。句子級錯誤的句子編號(如翻譯失敗);非句子級錯誤不帶 |
request_id | string | 請求追蹤 ID |
timestamp | string | 錯誤發生時間(ISO 8601) |
details | object | 可選。錯誤上下文,常見 key:provider、translation_language、source_lang 等 |
完整錯誤碼列表請參考 錯誤碼參考。
Health(心跳服務)
功能說明
用於確認 WebSocket 連線是否正常。建議每 30 秒發送一次 ping,若未收到 pong 則視為斷線並重連。
使用場景
- 維持長時間連線
- 檢測連線狀態
- 防止連線逾時
請求 - Ping
{
"type": "health",
"data": {
"action": "ping"
}
}
回應 - Pong
{
"type": "health",
"data": {
"action": "pong"
}
}
Voice Translation - start(開始語音翻譯)
功能說明
開始一個新的語音翻譯工作階段,並根據設定的參數開始處理音訊。
使用場景
- 開始會議記錄
- 開始即時翻譯
- 開始語音備忘錄
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 start |
transcription_languages | string | 是 | 語音辨識語言(最多 2 個) |
translation_languages | string | 否 | 翻譯目標語言(空=不翻譯) |
realtime_translation | boolean | 否 | 即時翻譯模式(預設 false) |
recognition_mode | string | 否 | 辨識模式:single(單人,預設)、multi_speaker(多人);multi_speaker 下 transcription_languages 必須恰好 1 個,否則回傳 diarization_multilang_conflict 錯誤並拒絕開始 |
type | string | 是 | 錄音類型:transcribe、conversation、record、broadcast |
audio_format | string | 否 | 音訊格式:pcm(預設)、webm |
summary_template | string | 條件 | 摘要模板。transcribe 在 summary_mode=builtin 時必填;summary_mode=custom 禁帶;conversation/broadcast 可選 |
options | object | 否 | 語音辨識選項 |
tts_enabled | boolean | 否 | 是否啟用 TTS 語音合成(預設 false) |
tts_language | string | 否 | TTS 輸出語言(需在 translation_languages 中) |
tts_voice | string | 否 | TTS 語音名稱(如 en-US-JennyNeural) |
tts_mode | string | 否 | TTS 播放模式:sync(同步,預設)、async(非同步) |
broadcast_token | string | 條件 | 廣播 Token(broadcast 類型必填,從 REST API 取得) |
active_language | string | 否 | 互譯模式初始 active 語言(預設 transcription_languages[0]) |
speakers | array | 條件 | 互譯模式用戶語言映射(互譯模式必填,恰好 2 位) |
conversation_mode | string | 否 | 互譯對話模式:auto(自動偵測,預設)、manual(手動 PTT) |
speaker_diarization | boolean | 否 | 語者分離(互譯模式下強制忽略) |
tts_config | object | 否 | 多語言 TTS 設定(廣播模式及互譯模式皆適用) |
broadcast_phase | string | 否 | 廣播初始階段:standby(預備)、live(正式,預設) |
standby_message | string | 否 | 預備階段觀眾看到的訊息(預設:「準備中,請稍候...」) |
name | string | 否 | 初始預設錄音名稱(最大 60 字,系統仍可覆蓋;未提供則自動生成如 Transcription #1) |
summary_language | string | 否 | 摘要輸出語言(不指定時預設使用辨識語言;廣播模式自動從頻道設定讀取) |
summary_mode | string | 否 | 摘要模式 enum:builtin(預設)/ custom。缺值時自動推斷 builtin |
summary_prompt | string | 否 | custom mode 必填、builtin mode 為補充指示。≤2000 字元 |
summary_prompt_slug | string | 否 | custom mode 必填、builtin mode 禁帶。客戶自家識別碼(≤64 字元,Unicode、禁控制字元;pass-through 保存於後端記錄,供歷史查詢) |
summary_plain_text | boolean | 否 | 摘要要求純文字輸出(預設 false;開啟後後端做 Markdown 後處理) |
錄音類型說明
| type | 說明 | 使用場景 |
|---|---|---|
transcribe | 語音轉文字 | 會議記錄、訪談紀錄 |
conversation | 對話記錄 | 雙向溝通、客服對話 |
record | 單純錄音 | 語音備忘、快速記錄 |
broadcast | 廣播/直播 | 講座、演講、直播內容 |
請求範例(基本)
{
"type": "voice-translation",
"data": {
"action": "start",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"realtime_translation": false,
"type": "transcribe",
"audio_format": "pcm",
"summary_template": "meeting",
"options": {
"speaking_speed": "normal",
"segmentation_mode": "auto",
"profanity_handling": "mask"
}
}
}
請求範例(初始預設名稱)
{
"type": "voice-translation",
"data": {
"action": "start",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"type": "transcribe",
"audio_format": "pcm",
"summary_template": "meeting",
"name": "產品規劃會議"
}
}
錄音名稱規則
| 情境 | 名稱 | name_source | 系統會覆蓋? |
|---|---|---|---|
start 帶 name 參數 | 初始預設名稱 | default | 是 |
start 未帶 name | 自動生成(如 Transcription #1、Broadcast #3) | default | 是 |
使用 set_name 設定 | 用戶明確設定的名稱 | user | 否 |
| Session 結束後系統自動生成 | 根據逐字稿內容生成摘要名稱 | llm | — |
注意:
start的name為初始預設名稱,Session 結束時系統仍可能覆蓋。若需固定名稱,請使用set_name。
預設名稱格式(固定英文):
| 錄音類型 | 預設名稱格式 |
|---|---|
transcribe | Transcription #N |
conversation | Conversation #N |
record | Recording #N |
broadcast | Broadcast #N |
N為該用戶同類型錄音的流水號。名稱優先順序:user>llm>default。用戶設定名稱後,Session 結束時 系統不會覆蓋。
請求範例(含 TTS)
{
"type": "voice-translation",
"data": {
"action": "start",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"realtime_translation": true,
"type": "transcribe",
"tts_enabled": true,
"tts_language": "en-US",
"tts_voice": "en-US-JennyNeural",
"tts_mode": "sync"
}
}
請求範例(互譯模式 - 自動偵測)
{
"type": "voice-translation",
"data": {
"action": "start",
"type": "conversation",
"transcription_languages": ["zh-TW", "en-US"],
"active_language": "zh-TW",
"audio_format": "pcm",
"realtime_translation": true,
"speakers": [
{ "id": 1, "language": "zh-TW" },
{ "id": 2, "language": "en-US" }
],
"tts_config": {
"zh-TW": { "voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0 },
"en-US": { "voice": "en-US-JennyNeural", "speaking_rate": 1.0 }
}
}
}
請求範例(互譯模式 - 手動模式)
{
"type": "voice-translation",
"data": {
"action": "start",
"type": "conversation",
"transcription_languages": ["zh-TW", "en-US"],
"conversation_mode": "manual",
"audio_format": "pcm",
"realtime_translation": true,
"speakers": [
{ "id": 1, "language": "zh-TW" },
{ "id": 2, "language": "en-US" }
],
"tts_config": {
"zh-TW": { "voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0 },
"en-US": { "voice": "en-US-JennyNeural", "speaking_rate": 1.0 }
}
}
}
請求範例(自訂摘要 prompt — custom mode)
mode=custom下客戶summary_prompt內容完整取代內建模板規則,後端已加 prompt injection 防護。summary_prompt_slug是給你自家識別用的 metadata(會保存於後端記錄),不會進入 prompt 內容。若想沿用內建模板 + 在其後加自家補充,請改用
summary_mode=builtin+summary_template=<slug>+summary_prompt=<補充指示>(builtin mode 下summary_prompt視為補充、append 在內建模板之後)。
{
"type": "voice-translation",
"data": {
"action": "start",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"type": "transcribe",
"audio_format": "pcm",
"summary_language": "zh-TW",
"summary_mode": "custom",
"summary_prompt": "你是會議記錄助手。請以條列方式列出討論的所有金額與承諾日期,並標註負責人。",
"summary_prompt_slug": "client_x_finance_v3",
"summary_plain_text": false
}
}
重要 — 摘要結果取得管道:WebSocket 模式下,摘要為非串流設計,final_content 不會由 WebSocket event 推回(summary_done event 僅通知完成但不含內容)。客戶端要事後透過 HTTP 取得:
- 收到
summary_doneevent 後,呼叫GET /api/v1/sse/history/transcribe/{taskId}取得摘要(init_summaryevent 帶 top-levelsummary純字串 +summary_mode/summary_template/summary_plain_text/summary_prompt_snapshot+ v1.5.5 新增的summary_fallback_level/summary_dropped_segments兩個內容過濾 fallback 審計欄位) - 或查 REST API
recordings表的summary_mode/summary_template/summary_prompt_slug三欄
v1.5.5 內容過濾自動降級:若客戶 prompt 或逐字稿內容觸發 LLM 服務的內容過濾,系統會自動降級(標準模式 → 中性模式 → 段落省略模式)。
summary_doneevent 的summary_fallback_level欄位(值2或3,標準模式直接成功則 omit)告知客戶端實際走的路徑,前端可據此顯示「使用中性模式」/「省略 N 段」提示。詳見 reference/websocket/events.md – summary_done 與 V1.5.5 changelog。
互譯模式特殊規則:
| 項目 | 說明 |
|---|---|
transcription_languages | 必須恰好 2 個,且不可相同 |
translation_languages | 不需提供(自動推導為非 active 的語言) |
active_language | 可選,預設 transcription_languages[0] |
recognition_mode | 強制 single(忽略 speaker_diarization) |
tts_enabled | 預設 true;設為 false 僅回傳文字翻譯 |
tts_config | 可選,為兩個語言各自設定 TTS 語音;留空自動使用預設語音 |
summary_template | 可選,提供時停止後自動生成摘要 |
speakers | 互譯模式必填,指定每位用戶的語言(恰好 2 位) |
conversation_mode | 可選,auto(自動偵測,預設)或 manual(手動 PTT) |
speakers 欄位說明:
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
id | int | 是 | 用戶編號(1 或 2) |
language | string | 是 | 該用戶的語言代碼(須在 transcription_languages 中) |
conversation_mode 說明:
| 模式 | 說明 |
|---|---|
auto(預設) | 系統自動偵測說話語言,自動斷句 |
manual | 用戶透過 start_speaking / stop_speaking 控制說話時段,期間音訊合併為單一句子 |
廣播模式說明(type: "broadcast")
廣播模式時,語言設定會自動從廣播頻道設定取得,無需在 WebSocket 訊息中傳送。
必填參數:
| 參數 | 類型 | 說明 |
|---|---|---|
type | string | 必須為 "broadcast" |
broadcast_token | string | 廣播 Token(透過 REST API 建立廣播後取得) |
audio_format | string | 音訊格式(pcm 或 webm) |
可選參數(覆蓋廣播頻道設定):
| 參數 | 類型 | 說明 |
|---|---|---|
tts_config | object | 多語言 TTS 設定(覆蓋建立時的設定) |
summary_template | string | 摘要模板 slug(覆蓋建立時的設定,不提供則使用廣播頻道預設值) |
自動設定的參數(可省略):
transcription_languages:自動從廣播設定讀取translation_languages:自動從廣播設定讀取realtime_translation:廣播模式預設啟用summary_template:自動從廣播設定讀取(WebSocket 傳入值優先)summary_language:自動從廣播設定讀取(WebSocket 傳入值優先)
廣播階段說明:
| broadcast_phase | 說明 | 行為 |
|---|---|---|
live(預設) | 正式階段 | STT/翻譯結果廣播給觀眾,寫入逐字稿 |
standby | 預備階段 | STT/翻譯結果只給主講者,觀眾看到 standby_message |
預備階段用途:讓主講者在正式開始前進行 STT/翻譯熱機測試,確認設備正常後再切換到正式階段。
廣播模式請求範例:
{
"type": "voice-translation",
"data": {
"action": "start",
"type": "broadcast",
"broadcast_token": "a3f9",
"audio_format": "pcm"
}
}
廣播模式請求範例(預備階段 + 覆蓋摘要模板):
{
"type": "voice-translation",
"data": {
"action": "start",
"type": "broadcast",
"broadcast_token": "a3f9",
"audio_format": "pcm",
"broadcast_phase": "standby",
"standby_message": "演講即將開始,請稍候...",
"summary_template": "lecture"
}
}
摘要模板優先順序:WebSocket
start傳入值 > 廣播頻道建立時設定的預設值。若兩者皆未設定,則不自動生成摘要。
廣播模式 TTS 設定(tts_config):
透過 tts_config 參數指定哪些翻譯語言需要產生 TTS 語音給觀眾。
| tts_config 欄位 | 類型 | 說明 |
|---|---|---|
| voice | string | TTS 語音名稱 |
| speaking_rate | number | 語速(0.5~2.0,預設 1.0) |
{
"type": "voice-translation",
"data": {
"action": "start",
"type": "broadcast",
"broadcast_token": "a3f9",
"audio_format": "pcm",
"tts_config": {
"en-US": {
"voice": "en-US-JennyNeural",
"speaking_rate": 1.0
},
"ja-JP": {
"voice": "ja-JP-NanamiNeural",
"speaking_rate": 1.0
}
}
}
}
注意:
- TTS 語言必須是
translation_languages中的有效語言,無效語言會被自動忽略- 主講者(WebSocket)不會收到 TTS 音訊,只有 SSE 觀眾會收到
tts_ready事件- TTS 只在
live階段發送,standby階段不會發送
TTS 播放模式說明
| 模式 | 說明 | 行為 |
|---|---|---|
sync | 同步模式(預設) | 自動播放最新的 is_final=true 翻譯句子,若前一句仍在播放則進入佇列等待 |
async | 非同步模式(手動控制) | 用戶可選擇任何已翻譯的句子進行 TTS,使用 tts_play 指令控制 |
成功回應
啟動成功後回傳 session_started 事件,包含完整的 Session 初始資訊。
一般錄音(transcribe / conversation / record):
{
"type": "voice-translation",
"data": {
"action": "session_started",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"recording_type": "transcribe",
"recognition_mode": "single",
"message": "語音辨識已開始"
}
}
廣播模式(broadcast):
{
"type": "voice-translation",
"data": {
"action": "session_started",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"recording_type": "broadcast",
"recognition_mode": "multi_speaker",
"phase": "standby",
"viewer_count": 0,
"queue_count": 0,
"peak_viewers": 0,
"total_viewers": 0,
"message": "語音辨識已開始"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
session_id | string | 會話 ID |
recording_id | string | 錄音 ID(可用於後續 API 查詢) |
recording_type | string | 錄音類型:transcribe、conversation、record、broadcast |
recognition_mode | string | 辨識模式:single、multi_speaker |
phase | string | 廣播階段:standby 或 live(僅廣播模式) |
viewer_count | int | 目前在線觀眾數(僅廣播模式) |
queue_count | int | 排隊等待中的觀眾數(僅廣播模式) |
peak_viewers | int | 本次廣播峰值觀眾數(僅廣播模式) |
total_viewers | int | 累計曾連線的觀眾總數(僅廣播模式) |
message | string | 狀態描述訊息 |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
missing_transcription_languages | 400 | 未提供語言參數 | 確認請求包含 transcription_languages |
invalid_transcription_language | 400 | 無效的語言代碼 | 確認語言代碼格式正確(如 zh-TW) |
too_many_languages | 400 | 語言數量超過上限 | 最多只能指定 2 個語言 |
invalid_recording_type | 400 | 錄音類型無效 | 使用有效的類型值 |
invalid_summary_template | 400 | 摘要模板無效 | 確認模板識別碼正確 |
stt_init_failed | 503 | 服務初始化失敗 | 稍後重試 |
auth_budget_exceeded | 402 | 月度預算已超額 | 等待下月預算重置或調整預算 |
tts_init_failed | 503 | TTS 服務初始化失敗 | 稍後重試 |
tts_invalid_language | 400 | TTS 語言不在翻譯語言中 | 確認 tts_language 在 translation_languages 中 |
broadcast_token_required | 400 | 廣播模式需要 Token | broadcast 類型必須提供 broadcast_token |
broadcast_token_invalid | 400 | 廣播 Token 無效 | 確認 Token 正確且未過期 |
broadcast_not_ready | 503 | 廣播服務尚未啟動 | 稍後重試 |
summary_invalid_mode | 400 | summary_mode 不是 builtin / custom | 改為合法 mode |
summary_mode_field_mismatch | 400 | mode 與欄位組合不符(必填缺漏 / 禁帶被帶入) | 依 mode 規則調整欄位 |
summary_prompt_too_long | 400 | summary_prompt 超過 2000 字元 | 縮短自訂 prompt |
summary_prompt_slug_too_long | 400 | summary_prompt_slug 超過 64 字元 | 縮短識別碼 |
summary_prompt_slug_invalid | 400 | summary_prompt_slug 含控制字元(\n / \r / \t / \0 等) | 移除控制字元 |
Voice Translation - config(設定術語庫/校正規則)
功能說明
在錄音開始前或進行中傳入術語庫、模糊詞校正規則和翻譯字典設定。這些設定可提升 STT 識別率、修正同音字錯誤、確保翻譯一致性。
自動生成校正規則:當傳入 terminology 時,系統會自動為每個術語生成模糊詞校正規則(同音字、近音字、繁簡體變體)。前端無需手動定義 fuzzy_correction,大幅簡化設定流程。
使用場景
- 錄音開始前傳入專業術語(Phrase List)
- 設定模糊詞校正規則(同音字修正)- 可選,系統會自動生成
- 設定翻譯字典(確保術語翻譯一致)
傳送時機
| 設定類型 | 建議時機 | 錄製中更新 |
|---|---|---|
| 術語庫(terminology) | start 之前或進行中 | 支援(下一回合生效) |
| 模糊詞校正 | start 之前或進行中 | 支援 |
| 翻譯字典 | start 之前或進行中 | 支援 |
注意:錄製中更新術語庫時,新的術語將在下一個辨識回合邊界自動生效,無需重新連線。回應中會包含
terminology_effective: "next_turn"欄位提示。
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 config |
terminology | object | 否 | 術語庫設定 |
fuzzy_correction | object | 否 | 模糊詞校正規則 |
translation_dict | object | 否 | 翻譯字典 |
注意:至少需要提供一個設定項目。
術語庫格式(terminology)
以語言代碼為 key,術語陣列為 value:
{
"zh-TW": [
{ "term": "語者分離", "boost": 1.5 },
{ "term": "WebSocket", "boost": 2.0 }
],
"en-US": [
{ "term": "diarization", "boost": 1.5 }
]
}
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
term | string | 是 | 術語(最大 100 字元) |
boost | number | 否 | 權重(預設 1.0,範圍 0.5-5.0) |
限制:每種語言最多 500 個術語。
模糊詞校正格式(fuzzy_correction)
注意:此欄位通常不需要手動設定。系統會根據
terminology自動生成校正規則。僅在需要自訂特殊規則時使用。
以語言代碼為 key,校正規則陣列為 value:
{
"zh-TW": [
{ "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] }
]
}
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
correct | string | 是 | 正確詞彙 |
incorrect | string | 是 | 錯誤變體列表 |
自動生成校正規則說明
當傳入 terminology 時,系統會自動為每個術語生成模糊詞校正規則:
| 生成類型 | 說明 | 範例 |
|---|---|---|
| 同音字 | 拼音相同的替代字 | 語者 → 語這、語折 |
| 近音字 | 聲調相近的替代字 | 媽 → 麻、馬 |
| 繁簡體 | 繁體/簡體轉換 | 製程 → 制程 |
中英混合術語支援:對於「CVD製程」這類混合術語,系統只對中文部分生成變體,英文保持不變。
| 原術語 | 自動生成的變體 |
|---|---|
| CVD製程 | CVD制程、CVD之程、CVD製城 |
| wafer良率 | wafer量率、wafer涼率 |
| 5nm製程 | 5nm制程、5nm製成 |
翻譯字典格式(translation_dict)
直接使用條目陣列:
[
{
"source": "語者分離",
"translations": {
"en-US": "Speaker Diarization",
"ja-JP": "話者分離"
}
}
]
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
source | string | 是 | 來源詞彙(使用 STT 語言) |
translations | object | 是 | 翻譯對照 { "語言代碼": "翻譯" } |
限制:建議不超過 50 條目(避免處理效能下降)。
請求範例(推薦:只設定術語庫)
{
"type": "voice-translation",
"data": {
"action": "config",
"terminology": {
"zh-TW": [
{ "term": "語者分離", "boost": 1.5 },
{ "term": "CVD製程", "boost": 1.5 },
{ "term": "wafer良率", "boost": 1.5 }
]
}
}
}
請求範例(完整設定,含手動校正規則)
{
"type": "voice-translation",
"data": {
"action": "config",
"terminology": {
"zh-TW": [
{ "term": "語者分離", "boost": 1.5 },
{ "term": "即時轉錄", "boost": 1.5 }
]
},
"fuzzy_correction": {
"zh-TW": [
{ "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] }
]
},
"translation_dict": [
{ "source": "語者分離", "translations": { "en-US": "Speaker Diarization" } }
]
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "config_updated",
"updated": ["terminology", "fuzzy_correction", "translation_dict"],
"message": "設定已更新"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
updated | string | 已更新的設定類型 |
message | string | 狀態訊息 |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
config_empty | 400 | 未提供任何設定 | 至少提供一個設定項目 |
config_term_too_long | 400 | 術語超過 100 字元 | 縮短術語長度 |
config_too_many_entries | 400 | 術語數量超過 500 個 | 減少術語數量 |
config_too_many_dict_entries | 400 | 翻譯字典超過 50 條目 | 減少字典條目 |
Voice Translation - audio(傳送音訊)
功能說明
傳送音訊資料給伺服器進行語音辨識。音訊需經過 Base64 編碼後傳送。
使用場景
- 持續傳送麥克風音訊
- 傳送錄製的音訊片段
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 audio |
payload | string | 是 | Base64 編碼的音訊資料 |
音訊格式要求
PCM 格式(預設):
| 項目 | 規格 |
|---|---|
| 格式 | PCM(原始音訊) |
| 取樣率 | 16000 Hz |
| 位元深度 | 16-bit |
| 聲道 | Mono(單聲道) |
| 位元組順序 | Little-endian |
| 傳輸編碼 | Base64 |
WebM/Opus 格式:
| 項目 | 規格 |
|---|---|
| 格式 | WebM 容器 + Opus 編碼 |
| 取樣率 | 任意(伺服器自動轉換) |
| 聲道 | Mono 或 Stereo(伺服器自動轉換) |
| 傳輸編碼 | Base64 |
請求範例
{
"type": "voice-translation",
"data": {
"action": "audio",
"payload": "Base64 編碼的 PCM 音訊資料"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start action |
audio_invalid_format | 400 | 音訊資料格式錯誤 | 確認 Base64 編碼正確 |
audio_format_unsupported | 400 | 不支援的音訊格式 | 使用 pcm 或 webm 格式 |
audio_decode_failed | 400 | 音訊解碼失敗 | 確認音訊格式正確 |
Voice Translation - pause(暫停翻譯)
功能說明
暫停語音辨識處理。暫停期間收到的音訊會被快取,恢復後繼續處理。
使用場景
- 使用者暫時離開
- 需要暫停記錄
請求範例
{
"type": "voice-translation",
"data": {
"action": "pause"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "語音辨識已暫停"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
session_already_paused | 400 | 已經暫停 | 可忽略此錯誤 |
Voice Translation - resume(恢復翻譯)
功能說明
恢復已暫停的語音辨識處理。
使用場景
- 使用者回來繼續
- 需要繼續記錄
請求範例
{
"type": "voice-translation",
"data": {
"action": "resume"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "語音辨識已恢復"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
session_not_paused | 400 | 未暫停 | 可忽略此錯誤 |
Voice Translation - stop(停止翻譯)
功能說明
停止語音辨識並結束會話。系統會自動上傳音檔和逐字稿,並生成摘要(若有設定)。
使用場景
- 會議結束
- 完成錄音
請求範例
{
"type": "voice-translation",
"data": {
"action": "stop"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "語音辨識已停止"
}
}
任務完成事件
當音檔和逐字稿上傳完成後,會發送此事件:
{
"type": "voice-translation",
"data": {
"action": "task_complete",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "任務處理完成"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
task_id | string | Recording UUID,可用於後續 API 查詢 |
Voice Translation - retranslate(重新翻譯)
功能說明
對指定句子重新翻譯,適用於修正原文後需要更新翻譯的情況。
使用場景
- 用戶編輯原文後需要更新翻譯
- 更正辨識錯誤
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 retranslate |
sid | int | 是 | 要重翻的句子編號 |
translation_languages | string | 是 | 翻譯語言代碼陣列 |
text | string | 是 | 要翻譯的原文(用戶修正後的文字) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "retranslate",
"sid": 1,
"translation_languages": ["en-US"],
"text": "用戶修正後的原文"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "result",
"translations": {
"en-US": {
"sid": 1,
"text": "新的翻譯結果",
"is_final": true,
"is_retranslation": true
}
}
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
retranslate_sid_not_found | 400 | 找不到指定的 SID | 確認 SID 存在 |
retranslate_session_not_active | 400 | 工作階段未啟動或已結束 | 確認工作階段狀態 |
retranslate_no_target_lang | 400 | 未提供目標語言 | 提供 translation_languages |
retranslate_no_text | 400 | 未提供要翻譯的文字 | 提供 text 參數 |
retranslate_llm_failed | 500 | 翻譯服務失敗 | 稍後重試 |
Voice Translation - switch_language(切換語言)
功能說明
在即時翻譯進行中切換語言。行為依錄音類型而異:
- 一般模式(transcribe 等):切換翻譯目標語言,並自動批次重翻所有已翻譯句子
- 互譯模式(conversation):切換 STT 來源語言(說話語言),翻譯目標自動切換為另一語言
使用場景
- 切換翻譯目標語言
- 會議中途更換語言需求
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 switch_language |
translation_languages | string | 條件 | 翻譯語言代碼陣列(一般模式必填) |
transcription_languages | string | 條件 | 切換目標語言(互譯模式;不帶則自動 toggle 到另一語言) |
請求範例(一般模式)
{
"type": "voice-translation",
"data": {
"action": "switch_language",
"translation_languages": ["ja-JP"]
}
}
請求範例(互譯模式)
指定切換目標:
{
"type": "voice-translation",
"data": {
"action": "switch_language",
"transcription_languages": ["en-US"]
}
}
自動 toggle(不帶參數):
{
"type": "voice-translation",
"data": {
"action": "switch_language"
}
}
互譯模式特殊行為:
- 互譯模式使用自動語言偵測,通常不需要手動切換語言
switch_language僅更新內部偏好狀態- 切換成功後回傳
language_switched事件(非 language_switch_start/done 序列) - 切換到相同語言會回傳
conversation_same_language警告
回應序列(一般模式)
切換語言後會依序收到以下事件:
- language_switch_start:通知開始切換
{
"type": "voice-translation",
"data": {
"action": "language_switch_start",
"translation_language": "ja-JP",
"total_segments": 15,
"message": "開始切換語言並重新翻譯"
}
}
- batch_retranslation(多個):逐句回傳重翻結果
{
"type": "voice-translation",
"data": {
"action": "batch_retranslation",
"sid": 3,
"translations": {
"ja-JP": {
"sid": 3,
"text": "今日はプロジェクトの進捗について話し合いましょう",
"is_final": true,
"is_retranslation": true
}
}
}
}
- language_switch_done:通知切換完成
{
"type": "voice-translation",
"data": {
"action": "language_switch_done",
"translation_language": "ja-JP",
"success_count": 15,
"failed_count": 0,
"message": "語言切換完成"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
switch_language_no_target | 400 | 未提供目標語言 | 提供 translation_languages |
switch_language_in_progress | 400 | 前一次切換尚未完成 | 等待切換完成 |
switch_language_same_target | 400 | 目標語言與當前相同 | 可忽略此錯誤 |
conversation_requires_two_languages | 400 | 互譯模式需恰好兩個語言 | 確認 transcription_languages 為 2 個 |
conversation_languages_identical | 400 | 互譯的兩個語言不可相同 | 提供兩個不同的語言 |
conversation_invalid_language | 400 | 無效的互譯語言 | 確認語言在 transcription_languages 中 |
conversation_same_language | 400 | 已是當前語言 | 可忽略此警告 |
Voice Translation - set_name(設定錄音名稱)
功能說明
在錄音進行中設定名稱。設定後,錄音結束時將使用此名稱,不會自動生成。
提示:也可在
start時透過name參數設定初始預設名稱,但該名稱在 Session 結束時仍可能被系統覆蓋。若需固定名稱,請使用set_name。
使用場景
- 錄音開始後自訂錄音標題
- 覆蓋自動生成的名稱或先前設定的名稱
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 set_name |
name | string | 是 | 錄音名稱(最大 60 字) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "set_name",
"name": "產品規劃會議"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "錄音名稱已更新"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
name_too_long | 400 | 錄音名稱超過限制 | 縮短名稱長度 |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
Voice Translation - rename_speaker(全域重命名說話者)
功能說明
在多人語者分離模式(multi_speaker)下,全域重命名某個說話者。所有使用該說話者 ID 的句子都會同步更新。
使用場景
- 將系統自動分配的說話者 ID(如
Guest-1)改為有意義的名稱(如王經理) - 會議中辨識出新的說話者後進行命名
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 rename_speaker |
speaker_id | string | 是 | 原始語者 ID(如 Guest-1),可同時接受目前的顯示標籤做連續改名;最大 100 字元 |
new_label | string | 是 | 新顯示標籤;最大 100 字元,不得含控制字元(\x00-\x1F、\x7F)或換行 |
請求範例
{
"type": "voice-translation",
"data": {
"action": "rename_speaker",
"speaker_id": "Guest-1",
"new_label": "王經理"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "speaker_renamed",
"speaker_id": "Guest-1",
"new_label": "王經理",
"affected_sids": [1, 3, 5, 8]
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
speaker_id | string | 解析後的原始語者 ID(即使輸入是顯示標籤,事件回傳仍是原始 ID) |
new_label | string | 新顯示標籤 |
affected_sids | int | 受影響的句子編號列表 |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
speaker_not_found | 400 | 找不到指定的說話者 | 確認 speaker_id 或顯示標籤存在 |
speaker_name_empty | 400 | new_label 為空 | 提供有效的標籤 |
speaker_name_duplicate | 422 | 顯示標籤已被使用 | 使用其他標籤,或先修改衝突的說話者 |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
Voice Translation - reassign_speaker(修改單句語者身份)
功能說明
修改特定句子的語者身份(OriginalSpeakerID),將句子指派給既有語者。
使用場景
- 更正系統辨識錯誤的語者身份
- 將某句話重新指派給另一位已知語者
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 reassign_speaker |
sid | int | 是 | 要修改的句子編號 |
target_speaker_id | string | 是 | 目標語者原始 ID(取自 init_sentence.speaker_id;reassign 不接受顯示標籤) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "reassign_speaker",
"sid": 5,
"target_speaker_id": "Guest-2"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "speaker_reassigned",
"sid": 5,
"old_speaker_id": "Guest-1",
"new_speaker_id": "Guest-2",
"new_speaker_label": "李小華"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 修改的句子編號 |
old_speaker_id | string | 原始語者 ID |
new_speaker_id | string | 新的原始語者 ID |
new_speaker_label | string | 新語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於 new_speaker_id) |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
speaker_sid_not_found | 400 | 找不到指定的句子 | 確認 SID 存在 |
speaker_not_found | 400 | 目標語者不存在 | 使用已存在的語者 ID |
speaker_name_empty | 400 | 目標語者 ID 不能為空 | 提供有效的語者 ID |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
invalid_parameter | 400 | 不支援建立新語者 | 使用已存在的語者 ID |
Voice Translation - merge_speakers(合併語者)
功能說明
將一個語者的所有句子合併到另一個語者。合併後,該語者未來產生的辨識結果也會自動轉換為目標語者。
使用場景
- 語音辨識引擎有時會將同一人的聲音誤識為多個語者(如 Guest-1 和 Guest-2 其實是同一人)
- 使用此功能可將 Guest-2 的所有句子合併到 Guest-1
- 合併後,未來辨識出的 Guest-2 結果會自動顯示為 Guest-1
與 reassign_speaker 的差異
| 功能 | 作用範圍 | 未來影響 |
|---|---|---|
reassign_speaker | 單句(1 個 SID) | 無 |
merge_speakers | 該語者的所有句子 | 未來出現的 source 也自動轉為 target |
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 merge_speakers |
source_speaker_id | string | 是 | 要被合併的語者 ID(如 Guest-2) |
target_speaker_id | string | 是 | 合併目標語者 ID(如 Guest-1) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "merge_speakers",
"source_speaker_id": "Guest-2",
"target_speaker_id": "Guest-1"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "speakers_merged",
"source_speaker_id": "Guest-2",
"target_speaker_id": "Guest-1",
"target_speaker_label": "王經理",
"affected_sids": [3, 5, 7]
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
source_speaker_id | string | 被合併的原始語者 ID |
target_speaker_id | string | 合併目標的原始語者 ID |
target_speaker_label | string | 目標語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於原始 ID) |
affected_sids | number | 受影響的句子 ID 列表 |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
speaker_not_found | 400 | 語者不存在 | 確認語者 ID 存在 |
merge_speakers_same_id | 400 | 來源和目標語者相同 | 使用不同的語者 ID |
speaker_name_empty | 400 | 語者 ID 不能為空 | 提供有效的語者 ID |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
Voice Translation - tts_play(播放 TTS)
功能說明
在 async 模式下,手動播放指定句子的 TTS 語音。
使用場景
- 用戶選擇特定句子進行 TTS 播放
- 播放多個連續句子
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 tts_play |
sid | int | 是 | 起始句子 ID |
length | int | 否 | 播放句子數量(預設 1,最大 20) |
注意:
length最大值由後端環境變數TTS_SSE_MAX_LENGTH控制(預設 20)。
請求範例(單句播放)
{
"type": "voice-translation",
"data": {
"action": "tts_play",
"sid": 5
}
}
請求範例(多句播放)
{
"type": "voice-translation",
"data": {
"action": "tts_play",
"sid": 5,
"length": 3
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
tts_not_enabled | 400 | TTS 未啟用 | 確認 start 時啟用 TTS |
tts_sid_not_found | 400 | 找不到指定的句子 | 確認 SID 存在 |
tts_translation_not_found | 400 | 該句子沒有指定語言的翻譯 | 確認翻譯存在 |
Voice Translation - tts_stop(停止 TTS)
功能說明
停止當前正在播放的 TTS 語音。
使用場景
- 用戶手動停止 TTS 播放
- 切換到其他句子前停止當前播放
請求範例
{
"type": "voice-translation",
"data": {
"action": "tts_stop"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "TTS 播放已停止"
}
}
Voice Translation - tts_mode(切換 TTS 模式)
功能說明
在錄音進行中切換 TTS 播放模式(同步/非同步)。
使用場景
- 從自動播放切換為手動控制
- 從手動控制切換為自動播放
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 tts_mode |
tts_mode | string | 是 | 模式:sync(同步)或 async(非同步) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "tts_mode",
"tts_mode": "async"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "tts_mode_changed",
"tts_mode": "async"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
tts_not_enabled | 400 | TTS 未啟用 | 確認 start 時啟用 TTS |
tts_invalid_mode | 400 | 無效的模式 | 使用 sync 或 async |
Voice Translation - set_tts(互譯 TTS 設定)
功能說明
在互譯模式(conversation)錄音進行中,動態切換 TTS 開關或更新 TTS 語音設定。僅限互譯模式使用。
使用場景
- 互譯對話中途關閉/開啟 TTS 語音回傳
- 更換特定語言的 TTS 語音或語速
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 set_tts |
tts_enabled | boolean | 否 | 是否啟用互譯 TTS(true / false) |
tts_config | object | 否 | 各語言 TTS 設定,key 為語言代碼,value 為 {voice, speaking_rate} |
注意:
tts_enabled和tts_config至少需提供一個。tts_config僅更新指定語言的設定,未指定的語言保持不變。
請求範例(關閉 TTS)
{
"type": "voice-translation",
"data": {
"action": "set_tts",
"tts_enabled": false
}
}
請求範例(更新語音設定)
{
"type": "voice-translation",
"data": {
"action": "set_tts",
"tts_enabled": true,
"tts_config": {
"en-US": {
"voice": "en-US-GuyNeural",
"speaking_rate": 1.2
}
}
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "tts_updated",
"tts_enabled": true,
"tts_config": {
"zh-TW": { "voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0 },
"en-US": { "voice": "en-US-GuyNeural", "speaking_rate": 1.2 }
}
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
tts_enabled | boolean | 當前 TTS 啟用狀態 |
tts_config | object | 當前完整 TTS 設定(所有語言) |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
invalid_action | 400 | 非互譯模式 | 此 action 僅限 conversation 模式 |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
Voice Translation - start_speaking(開始說話/手動模式)
功能說明
在互譯手動模式(conversation_mode: "manual")下,通知系統用戶開始說話。從此刻起,音訊會被傳送至 STT 進行辨識,所有辨識結果會累積為同一句話(不自動斷句)。
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 start_speaking |
speaker | int | 是 | 用戶編號(1 或 2) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "start_speaking",
"speaker": 1
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "開始說話"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
invalid_action | 400 | 非互譯模式 | 僅在 conversation 類型下使用 |
conversation_not_manual_mode | 400 | 非手動模式 | 僅在 manual 模式下使用 |
conversation_speaking | 400 | 已在說話中 | 先呼叫 stop_speaking |
conversation_invalid_speaker | 400 | 無效的用戶編號 | 使用 1 或 2 |
Voice Translation - stop_speaking(結束說話/手動模式)
功能說明
在互譯手動模式下,通知系統用戶結束說話。系統會將期間累積的辨識結果合併為一個完整句子,進行翻譯和 TTS 合成。
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 stop_speaking |
請求範例
{
"type": "voice-translation",
"data": {
"action": "stop_speaking"
}
}
成功回應
結束說話後,系統會送出完整的 result 事件(包含 origin 和 translations):
{
"type": "voice-translation",
"data": {
"action": "result",
"origin": {
"sid": 1,
"language": "zh-TW",
"text": "這段期間所有辨識內容合併的完整句子",
"is_final": true,
"speaker_id": "Speaker-1",
"start_time": "00:05"
},
"translations": {
"en-US": {
"sid": 1,
"text": "The complete merged sentence from this speaking period",
"is_final": true
}
}
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
invalid_action | 400 | 非互譯模式 | 僅在 conversation 類型下使用 |
conversation_not_speaking | 400 | 未在說話狀態 | 先呼叫 start_speaking |
Voice Translation - switch_conversation_mode(切換對話模式)
功能說明
在互譯模式進行中,切換自動偵測模式(auto)與手動模式(manual)。切換時若正在說話中會自動結束說話。
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 switch_conversation_mode |
conversation_mode | string | 是 | 目標模式:auto 或 manual |
請求範例
{
"type": "voice-translation",
"data": {
"action": "switch_conversation_mode",
"conversation_mode": "manual"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "conversation_mode_changed",
"conversation_mode": "manual"
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
invalid_action | 400 | 非互譯模式 | 僅在 conversation 類型下使用 |
conversation_invalid_mode | 400 | 無效的對話模式 | 使用 auto 或 manual |
Voice Translation - set_speaker_language(設定用戶語言)
功能說明
在互譯模式進行中,即時變更指定用戶的語言。系統會重建 STT 連線以適應新語言,翻譯目標也會自動更新。變更前的逐字稿內容維持原語言不變,時間戳持續計算不歸零。
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 set_speaker_language |
speaker | int | 是 | 用戶編號(1 或 2) |
language | string | 是 | 新的語言代碼(如 ja-JP) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "set_speaker_language",
"speaker": 1,
"language": "ja-JP"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "speaker_language_changed",
"speaker_language_map": {
"1": "ja-JP",
"2": "en-US"
}
}
}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
invalid_action | 400 | 非互譯模式 | 僅在 conversation 類型下使用 |
conversation_invalid_speaker | 400 | 無效的用戶編號 | 使用 1 或 2 |
conversation_invalid_language | 400 | 無效的語言代碼 | 使用有效的 BCP 47 語言代碼 |
conversation_same_language | 400 | 與當前語言相同 | 可忽略此警告 |
conversation_language_same_as_peer | 400 | 新語言與另一位用戶相同 | 兩位用戶語言不可相同 |
conversation_speaking | 400 | 正在說話中,無法變更語言 | 先結束說話再變更 |
conversation_language_change_failed | 500 | 語言變更失敗(STT 重建失敗) | 稍後重試 |
Voice Translation - broadcast_go_live(切換到正式階段)
功能說明
在廣播預備階段(standby)切換到正式階段(live)。切換後,STT/翻譯結果開始廣播給觀眾,並開始寫入逐字稿。
使用場景
- 主講者確認設備正常後開始正式廣播
- 從熱機階段切換到正式直播
請求範例
{
"type": "voice-translation",
"data": {
"action": "broadcast_go_live"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "broadcast_phase_changed",
"phase": "live",
"message": "廣播已開始"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
phase | string | 新的階段(live) |
message | string | 狀態描述訊息 |
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
broadcast_not_enabled | 400 | 非廣播模式 | 確認 type: "broadcast" |
session_not_started | 400 | 語音辨識尚未開始 | 先呼叫 start |
注意:若已在正式階段(live),會回傳狀態訊息「廣播已經在進行中」,不視為錯誤。
Voice Translation - broadcast_announcement(發送公告)
功能說明
主講者發送自訂訊息公告給所有觀眾。觀眾會透過 SSE 收到 announcement 事件。公告訊息會自動翻譯成所有翻譯語言,觀眾收到的 SSE 事件會包含 translations 欄位。
使用場景
- 通知觀眾會議即將結束
- 發送重要提醒或公告
- 與觀眾進行單向溝通
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 broadcast_announcement |
message | string | 是 | 公告訊息內容 |
請求範例
{
"type": "voice-translation",
"data": {
"action": "broadcast_announcement",
"message": "會議將在 5 分鐘後結束"
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "公告已發送"
}
}
觀眾端收到的 SSE 事件(含翻譯):
event: announcement
data: {"message":"會議將在 5 分鐘後結束","translations":{"en-US":"The meeting will end in 5 minutes","ja-JP":"会議は5分後に終了します"}}
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
broadcast_not_enabled | 400 | 非廣播模式 | 確認 type: "broadcast" |
invalid_parameter | 400 | 訊息為空 | 提供有效的 message 參數 |
Voice Translation - set_standby_message(設定預備階段文字)
功能說明
在廣播預備階段(standby)動態設定顯示給觀眾的訊息。允許主講者進入預備模式後再設定等待訊息,而非在 start 時就必須提供。
訊息會自動翻譯成所有翻譯語言,觀眾收到的 SSE 事件會包含 translations 欄位。
使用場景
- 進入預備模式後,動態設定顯示給觀眾的等待訊息
- 在正式開播前更新預備畫面的文字
- 減少開始廣播前的必填欄位
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
action | string | 是 | 固定為 set_standby_message |
message | string | 是 | 預備階段顯示文字(將透過現有翻譯流程翻譯給各語言觀眾) |
請求範例
{
"type": "voice-translation",
"data": {
"action": "set_standby_message",
"message": "演講即將開始,請稍候..."
}
}
成功回應
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "預備階段文字已更新"
}
}
觀眾端收到的事件
設定成功後,所有在預備階段的觀眾會透過 SSE 收到更新後的 standby 事件:
event: standby
data: {"message":"演講即將開始,請稍候...","translations":{"en-US":"The presentation is about to begin, please wait...","ja-JP":"プレゼンテーションがまもなく始まります。お待ちください..."}}
注意:
translations欄位包含所有翻譯語言的翻譯結果。前端可根據觀眾選擇的語言顯示對應翻譯。
錯誤回應
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
broadcast_not_enabled | 400 | 非廣播模式 | 確認 type: "broadcast" |
broadcast_not_in_standby | 400 | 不在預備階段 | 只能在 standby 階段使用 |
注意:此 action 只能在預備階段(standby)使用。若已進入正式階段(live),會回傳錯誤。
回應事件
以下為所有 WebSocket 可能收到的回應事件。
session_started - Session 啟動成功
當 start action 成功後,伺服器回傳包含完整 Session 初始資訊的事件。前端可透過 recording_type 區分錄音類型。
一般錄音(transcribe / conversation / record):
{
"type": "voice-translation",
"data": {
"action": "session_started",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"recording_type": "transcribe",
"recognition_mode": "single",
"message": "語音辨識已開始"
}
}
廣播模式(broadcast):
{
"type": "voice-translation",
"data": {
"action": "session_started",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"recording_type": "broadcast",
"recognition_mode": "multi_speaker",
"phase": "standby",
"viewer_count": 0,
"queue_count": 0,
"peak_viewers": 0,
"total_viewers": 0,
"message": "語音辨識已開始"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
session_id | string | 會話 ID |
recording_id | string | 錄音 ID(可用於後續 API 查詢) |
recording_type | string | 錄音類型:transcribe、conversation、record、broadcast |
recognition_mode | string | 辨識模式:single、multi_speaker |
message | string | 狀態描述訊息 |
phase | string | 廣播階段:standby 或 live(僅廣播模式) |
viewer_count | int | 目前在線觀眾數(僅廣播模式) |
queue_count | int | 排隊等待中的觀眾數(僅廣播模式) |
peak_viewers | int | 本次廣播峰值觀眾數(僅廣播模式) |
total_viewers | int | 累計曾連線的觀眾總數(僅廣播模式) |
result - 辨識/翻譯結果
語音辨識與翻譯結果。一個 result 事件可能包含 origin(辨識結果)和/或 translations(翻譯結果)。
origin(語音辨識結果):
{
"type": "voice-translation",
"data": {
"action": "result",
"origin": {
"sid": 1,
"language": "zh-TW",
"text": "你好,很高興認識你",
"is_final": true,
"speaker_id": "0",
"detected_language": "zh-TW",
"start_time": "00:05"
}
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 句子編號,從 1 開始 |
language | string | 來源語言代碼。互譯模式下為自動偵測的語言 |
text | string | 辨識出的文字 |
is_final | boolean | 是否為最終結果 |
speaker_id | string | 說話者 ID |
detected_language | string | 偵測到的語言。互譯模式下由系統自動判定 |
start_time | string | 句子開始時間(mm:ss);廣播 standby 階段不送此欄位,進 live 後從 00:00 起算 |
translations(翻譯結果):
{
"type": "voice-translation",
"data": {
"action": "result",
"translations": {
"en-US": {
"sid": 1,
"text": "Hello, nice to meet you",
"is_final": true
}
}
}
}
翻譯結果以語言代碼為 key,每個語言的翻譯物件包含:
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 句子編號 |
text | string | 翻譯後的文字 |
is_final | boolean | 是否為最終結果 |
is_retranslation | boolean | 是否為重新翻譯結果(僅 retranslate 時) |
status - 通用狀態回應
用於 pause、resume、stop、set_name 等操作的確認。
{
"type": "voice-translation",
"data": {
"action": "status",
"message": "語音辨識已暫停"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
message | string | 狀態描述 |
task_complete - 任務處理完成
當 stop 後音檔和逐字稿上傳完成時觸發。task_id 可用於後續 REST API 查詢任務詳情。
{
"type": "voice-translation",
"data": {
"action": "task_complete",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "任務處理完成"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
task_id | string | Recording UUID,可用於後續 API 查詢 |
message | string | 狀態描述 |
config_updated - 設定更新完成
在 config action 成功後觸發。
{
"type": "voice-translation",
"data": {
"action": "config_updated",
"updated": ["terminology", "fuzzy_correction", "translation_dict"],
"message": "設定已更新"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
updated | string | 已更新的設定類型(terminology、fuzzy_correction、translation_dict) |
message | string | 狀態訊息 |
tts_ready - TTS 語音就緒
TTS 語音合成完成事件。包含音訊資料和 Word Boundary 資訊(可用於卡拉 OK 效果)。
{
"type": "voice-translation",
"data": {
"action": "tts_ready",
"sid": 1,
"language": "en-US",
"transcript": "你好,很高興認識你",
"text": "Hello, nice to meet you",
"audio": "Base64EncodedMP3...",
"format": "mp3",
"duration_ms": 2500,
"boundaries": [
{"offset_ms": 0, "duration_ms": 350, "text_offset": 0, "word_length": 5, "text": "Hello"},
{"offset_ms": 350, "duration_ms": 100, "text_offset": 5, "word_length": 1, "text": ","},
{"offset_ms": 500, "duration_ms": 250, "text_offset": 7, "word_length": 4, "text": "nice"},
{"offset_ms": 750, "duration_ms": 200, "text_offset": 12, "word_length": 2, "text": "to"},
{"offset_ms": 950, "duration_ms": 350, "text_offset": 15, "word_length": 4, "text": "meet"},
{"offset_ms": 1300, "duration_ms": 300, "text_offset": 20, "word_length": 3, "text": "you"}
]
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 句子編號 |
language | string | TTS 語言 |
transcript | string | 原始逐字稿(STT 識別結果) |
text | string | 翻譯文字(TTS 合成來源) |
audio | string | Base64 編碼的 MP3 音訊 |
format | string | 音訊格式(固定為 mp3) |
duration_ms | int | 音訊總時長(毫秒) |
boundaries | array | Word Boundary 陣列 |
Word Boundary 欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
offset_ms | int | 該字詞在音訊中的起始時間(毫秒) |
duration_ms | int | 該字詞持續時間(毫秒) |
text_offset | int | 在原文字串中的位置(字元索引) |
word_length | int | 字詞長度(字元數) |
text | string | 字詞內容 |
tts_error - TTS 合成失敗
TTS 合成失敗事件。
{
"type": "voice-translation",
"data": {
"action": "tts_error",
"sid": 1,
"language": "en-US",
"error": "translation_not_found",
"message": "No translation available for language: en-US"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 句子編號 |
language | string | TTS 語言 |
error | string | 錯誤碼 |
message | string | 錯誤訊息 |
TTS 錯誤碼
| 錯誤碼 | 說明 |
|---|---|
translation_not_found | 找不到該語言的翻譯 |
tts_synthesis_failed | TTS 合成失敗 |
tts_quota_exceeded | TTS 使用量已達上限 |
viewer_count - 觀眾人數更新
廣播模式專用
廣播進行中,系統每 3 秒檢查一次觀眾人數,若有變動則推送此事件給主講者。
{
"type": "voice-translation",
"data": {
"action": "viewer_count",
"viewer_count": 45,
"queue_count": 8,
"peak_viewers": 50,
"total_viewers": 123
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
viewer_count | int | 目前在線觀眾數 |
queue_count | int | 排隊等待中的觀眾數 |
peak_viewers | int | 本次廣播峰值觀眾數 |
total_viewers | int | 累計曾連線的觀眾總數 |
注意:此事件僅在觀眾人數或排隊人數有變動時才會推送,避免不必要的訊息傳輸。
viewer_joined - 觀眾加入
廣播模式專用
當觀眾加入廣播時,主講者會收到此事件。
{
"type": "voice-translation",
"data": {
"action": "viewer_joined",
"viewer_count": 5,
"queue_count": 2
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
viewer_count | number | 目前觀眾人數 |
queue_count | number | 排隊中的人數 |
viewer_left - 觀眾離開
廣播模式專用
當觀眾離開廣播時,主講者會收到此事件。
{
"type": "voice-translation",
"data": {
"action": "viewer_left",
"viewer_count": 4,
"queue_count": 1
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
viewer_count | number | 目前觀眾人數 |
queue_count | number | 排隊中的人數 |
broadcast_phase_changed - 廣播階段變更
當廣播階段從預備(standby)切換到正式(live)時觸發。
{
"type": "voice-translation",
"data": {
"action": "broadcast_phase_changed",
"phase": "live",
"message": "廣播已開始"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
phase | string | 新的階段:standby 或 live |
message | string | 狀態描述訊息 |
speaker_renamed - 說話者重命名
全域重命名說話者完成事件。
{
"type": "voice-translation",
"data": {
"action": "speaker_renamed",
"speaker_id": "Guest-1",
"new_label": "王經理",
"affected_sids": [1, 3, 5, 8]
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
speaker_id | string | 解析後的原始語者 ID(即使輸入是顯示標籤,事件回傳仍是原始 ID) |
new_label | string | 新顯示標籤 |
affected_sids | int | 受影響的句子編號列表 |
speaker_reassigned - 語者身份修改
修改單句語者身份完成事件。
{
"type": "voice-translation",
"data": {
"action": "speaker_reassigned",
"sid": 5,
"old_speaker_id": "Guest-1",
"new_speaker_id": "Guest-2",
"new_speaker_label": "李小華"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 修改的句子編號 |
old_speaker_id | string | 原始語者 ID |
new_speaker_id | string | 新的原始語者 ID |
new_speaker_label | string | 新語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於 new_speaker_id) |
speakers_merged - 語者合併
語者合併完成事件。合併後,該 source 語者未來產生的辨識結果也會自動轉換為 target 語者。
{
"type": "voice-translation",
"data": {
"action": "speakers_merged",
"source_speaker_id": "Guest-2",
"target_speaker_id": "Guest-1",
"target_speaker_label": "王經理",
"affected_sids": [3, 5, 7]
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
source_speaker_id | string | 被合併的原始語者 ID |
target_speaker_id | string | 合併目標的原始語者 ID |
target_speaker_label | string | 目標語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於原始 ID) |
affected_sids | number | 受影響的句子 ID 列表 |
language_switch_start - 語言切換開始
語言切換開始事件,在 switch_language action 觸發後送出。
{
"type": "voice-translation",
"data": {
"action": "language_switch_start",
"translation_language": "ja-JP",
"total_segments": 15,
"message": "開始切換語言並重新翻譯"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
translation_language | string | 新的翻譯目標語言 |
total_segments | int | 需要重新翻譯的句子數 |
message | string | 狀態描述 |
batch_retranslation - 批次重翻結果
批次重翻結果事件,在語言切換過程中逐句送出。
{
"type": "voice-translation",
"data": {
"action": "batch_retranslation",
"sid": 3,
"translations": {
"ja-JP": {
"sid": 3,
"text": "今日はプロジェクトの進捗について話し合いましょう",
"is_final": true,
"is_retranslation": true
}
}
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
sid | int | 句子編號 |
translations | object | 翻譯結果(格式同 result 的 translations) |
language_switch_done - 語言切換完成
語言切換完成事件。
{
"type": "voice-translation",
"data": {
"action": "language_switch_done",
"translation_language": "ja-JP",
"success_count": 15,
"failed_count": 0,
"message": "語言切換完成"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
translation_language | string | 翻譯目標語言 |
success_count | int | 成功翻譯的句子數 |
failed_count | int | 翻譯失敗的句子數 |
message | string | 狀態描述 |
tts_mode_changed - TTS 模式變更
TTS 播放模式變更事件。
{
"type": "voice-translation",
"data": {
"action": "tts_mode_changed",
"tts_mode": "async"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
tts_mode | string | 新的模式:sync 或 async |
language_switched - 互譯語言切換完成
互譯模式(conversation)語言切換完成事件。當 switch_language 在互譯模式下成功切換 STT 來源語言後觸發。
{
"type": "voice-translation",
"data": {
"action": "language_switched",
"language": "en-US",
"translation_language": "zh-TW",
"message": "語言已切換"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
language | string | 新的 active 語言(STT 來源) |
translation_language | string | 新的翻譯目標語言 |
message | string | 狀態訊息 |
tts_updated - 互譯 TTS 設定更新
互譯模式(conversation)TTS 設定更新事件。當 set_tts 成功更新 TTS 開關或語音設定後觸發。
{
"type": "voice-translation",
"data": {
"action": "tts_updated",
"tts_enabled": true,
"tts_config": {
"zh-TW": { "voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0 },
"en-US": { "voice": "en-US-GuyNeural", "speaking_rate": 1.2 }
}
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
tts_enabled | boolean | TTS 是否啟用 |
tts_config | object | 各語言的 TTS 設定(voice、speaking_rate) |
conversation_mode_changed - 對話模式變更
互譯模式(conversation)對話模式變更事件。當 switch_conversation_mode 成功切換自動/手動模式後觸發。
{
"type": "voice-translation",
"data": {
"action": "conversation_mode_changed",
"conversation_mode": "manual"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
conversation_mode | string | 新的對話模式:auto 或 manual |
speaker_language_changed - 用戶語言變更
互譯模式(conversation)用戶語言變更事件。當 set_speaker_language 成功變更用戶語言後觸發,包含變更後的完整語言映射。
{
"type": "voice-translation",
"data": {
"action": "speaker_language_changed",
"speaker_language_map": {
"1": "ja-JP",
"2": "en-US"
}
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
speaker_language_map | object | 變更後的用戶語言映射(key 為用戶編號字串) |
segment_uploaded - 音訊分段上傳完成
音訊分段上傳完成事件。每當一個音訊片段成功上傳至雲端儲存時觸發,可用於前端顯示上傳進度。
{
"type": "voice-translation",
"data": {
"action": "segment_uploaded",
"segment_index": 0,
"duration_sec": 30.5
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
segment_index | number | 分段索引(從 0 開始) |
duration_sec | number | 該分段的時長(秒) |
stt_event - STT 連線狀態事件
STT 連線狀態事件。當語音辨識服務的連線狀態發生變化時觸發,可用於前端顯示 STT 服務狀態。
{
"type": "voice-translation",
"data": {
"action": "stt_event",
"event": "connected",
"message": "STT 服務已連線"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
event | string | 事件類型:connected / disconnected / error |
message | string | 事件描述訊息 |
error - 錯誤事件
當操作失敗或系統異常時觸發。
{
"type": "error",
"data": {
"error_code": "session_not_started",
"severity": "error",
"message": "語音辨識尚未開始",
"context": "voice-translation",
"request_id": "req_abc123xyz789",
"timestamp": "2026-01-15T10:30:45.123Z"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
error_code | string | 錯誤碼(程式化處理用) |
severity | string | 嚴重程度:fatal / error / warning |
message | string | 人類可讀的錯誤訊息 |
context | string | 錯誤來源分類 |
request_id | string | 請求追蹤 ID |
timestamp | string | 錯誤發生時間(ISO 8601) |
嚴重程度說明
| severity | 說明 | 處理建議 |
|---|---|---|
fatal | 致命錯誤 | 停止服務,要求重新連線 |
error | 操作失敗 | 顯示錯誤提示,允許重試 |
warning | 警告 | 顯示警告,不阻斷操作 |
完整錯誤碼列表請參考 錯誤碼參考。
版本:V1.5.7 最後更新:2026-05-20