API 文件

Websocket Api

注意:此為合併版文件。詳細規格請參考 reference/websocket/ 下的獨立文件。

注意:本文件中的網址(vas-poc.vurbo.ai)為預計部署網址,正式上線後將另行通知。


目錄

  1. 連線資訊
  2. 認證方式
  3. 訊息格式
  4. Health - 心跳服務
  5. Voice Translation - start
  6. Voice Translation - config
  7. Voice Translation - audio
  8. Voice Translation - pause
  9. Voice Translation - resume
  10. Voice Translation - stop
  11. Voice Translation - retranslate
  12. Voice Translation - switch_language
  13. Voice Translation - set_name
  14. Voice Translation - rename_speaker
  15. Voice Translation - reassign_speaker
  16. Voice Translation - merge_speakers
  17. Voice Translation - tts_play
  18. Voice Translation - tts_stop
  19. Voice Translation - tts_mode
  20. Voice Translation - set_tts
  21. Voice Translation - start_speaking
  22. Voice Translation - stop_speaking
  23. Voice Translation - switch_conversation_mode
  24. Voice Translation - set_speaker_language
  25. Voice Translation - broadcast_go_live
  26. Voice Translation - broadcast_announcement
  27. Voice Translation - set_standby_message
  28. 回應事件

連線資訊

項目
端點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
}
欄位類型說明
ticketstring一次性 Ticket(32 字元)
expires_inint有效期(秒)

步驟 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_invalid401Ticket 無效或已過期
ticket_expired401Ticket 已過期
ticket_already_used401Ticket 已被使用
ticket_validation_failed500Ticket 驗證失敗

完整 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"
  }
}

句子級錯誤(如某句的某個語言翻譯失敗)會額外帶上 siddetails

{
  "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_nameswitch_languagetts_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_typestring服務類型:voice-translation / health
actionstring(可選)失敗的具體操作,如 set_nameswitch_languagetts_playtts_moderetranslateconfigspeaker.rename 等。當訊息 payload 無 action 欄位(如純 init 訊息)時不會出現此欄位。
前端應做什麼
  1. 保持 WebSocket 連線不要因為收到此錯誤而呼叫 ws.close()、跳轉頁面、或回到歷史頁。錄音仍在進行中。
  2. 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、無法回推具體操作。前端可依「使用者最近送出的訊息」反推;或顯示通用錯誤訊息「操作失敗,請重試」。
  3. 使用者體驗:建議顯示 transient toast / inline error,不要用 modal 或 redirect 中斷使用者流程。
  4. 遙測 / 上報:建議把 request_id + details 上報到前端 error tracking(Sentry / Datadog 等),方便對應後端 log 排查。
不會發生的事(保證項)
  • ✅ 錄音不會中斷:segment_uploadedresultorigin 等訊息會持續送達
  • ✅ 連線不會被伺服器主動關閉
  • ✅ 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_codestring錯誤碼(程式化處理用)
severitystring嚴重程度:fatal / error / warning
messagestring人類可讀的錯誤訊息
contextstring錯誤來源分類
sidint可選。句子級錯誤的句子編號(如翻譯失敗);非句子級錯誤不帶
request_idstring請求追蹤 ID
timestampstring錯誤發生時間(ISO 8601)
detailsobject可選。錯誤上下文,常見 key:providertranslation_languagesource_lang

完整錯誤碼列表請參考 錯誤碼參考


Health(心跳服務)

功能說明

用於確認 WebSocket 連線是否正常。建議每 30 秒發送一次 ping,若未收到 pong 則視為斷線並重連。

使用場景

  • 維持長時間連線
  • 檢測連線狀態
  • 防止連線逾時

請求 - Ping

{
  "type": "health",
  "data": {
    "action": "ping"
  }
}

回應 - Pong

{
  "type": "health",
  "data": {
    "action": "pong"
  }
}

Voice Translation - start(開始語音翻譯)

功能說明

開始一個新的語音翻譯工作階段,並根據設定的參數開始處理音訊。

使用場景

  • 開始會議記錄
  • 開始即時翻譯
  • 開始語音備忘錄

請求參數

參數類型必填說明
actionstring固定為 start
transcription_languagesstring語音辨識語言(最多 2 個)
translation_languagesstring翻譯目標語言(空=不翻譯)
realtime_translationboolean即時翻譯模式(預設 false
recognition_modestring辨識模式:single(單人,預設)、multi_speaker(多人);multi_speakertranscription_languages 必須恰好 1 個,否則回傳 diarization_multilang_conflict 錯誤並拒絕開始
typestring錄音類型:transcribeconversationrecordbroadcast
audio_formatstring音訊格式:pcm(預設)、webm
summary_templatestring條件摘要模板。transcribesummary_mode=builtin 時必填;summary_mode=custom 禁帶conversation/broadcast 可選
optionsobject語音辨識選項
tts_enabledboolean是否啟用 TTS 語音合成(預設 false
tts_languagestringTTS 輸出語言(需在 translation_languages 中)
tts_voicestringTTS 語音名稱(如 en-US-JennyNeural
tts_modestringTTS 播放模式:sync(同步,預設)、async(非同步)
broadcast_tokenstring條件廣播 Token(broadcast 類型必填,從 REST API 取得)
active_languagestring互譯模式初始 active 語言(預設 transcription_languages[0]
speakersarray條件互譯模式用戶語言映射(互譯模式必填,恰好 2 位)
conversation_modestring互譯對話模式:auto(自動偵測,預設)、manual(手動 PTT)
speaker_diarizationboolean語者分離(互譯模式下強制忽略)
tts_configobject多語言 TTS 設定(廣播模式及互譯模式皆適用)
broadcast_phasestring廣播初始階段:standby(預備)、live(正式,預設)
standby_messagestring預備階段觀眾看到的訊息(預設:「準備中,請稍候...」)
namestring初始預設錄音名稱(最大 60 字,系統仍可覆蓋;未提供則自動生成如 Transcription #1
summary_languagestring摘要輸出語言(不指定時預設使用辨識語言;廣播模式自動從頻道設定讀取)
summary_modestring摘要模式 enum:builtin(預設)/ custom。缺值時自動推斷 builtin
summary_promptstringcustom mode 必填、builtin mode 為補充指示。≤2000 字元
summary_prompt_slugstringcustom mode 必填、builtin mode 禁帶。客戶自家識別碼(≤64 字元,Unicode、禁控制字元;pass-through 保存於後端記錄,供歷史查詢)
summary_plain_textboolean摘要要求純文字輸出(預設 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系統會覆蓋?
startname 參數初始預設名稱default
start 未帶 name自動生成(如 Transcription #1Broadcast #3default
使用 set_name 設定用戶明確設定的名稱user
Session 結束後系統自動生成根據逐字稿內容生成摘要名稱llm

注意startname 為初始預設名稱,Session 結束時系統仍可能覆蓋。若需固定名稱,請使用 set_name

預設名稱格式(固定英文):

錄音類型預設名稱格式
transcribeTranscription #N
conversationConversation #N
recordRecording #N
broadcastBroadcast #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 取得:

  1. 收到 summary_done event 後,呼叫 GET /api/v1/sse/history/transcribe/{taskId} 取得摘要(init_summary event 帶 top-level summary 純字串 + summary_mode / summary_template / summary_plain_text / summary_prompt_snapshot + v1.5.5 新增的 summary_fallback_level / summary_dropped_segments 兩個內容過濾 fallback 審計欄位)
  2. 或查 REST API recordings 表的 summary_mode / summary_template / summary_prompt_slug 三欄

v1.5.5 內容過濾自動降級:若客戶 prompt 或逐字稿內容觸發 LLM 服務的內容過濾,系統會自動降級(標準模式 → 中性模式 → 段落省略模式)。summary_done event 的 summary_fallback_level 欄位(值 23,標準模式直接成功則 omit)告知客戶端實際走的路徑,前端可據此顯示「使用中性模式」/「省略 N 段」提示。詳見 reference/websocket/events.md – summary_doneV1.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 欄位說明:

欄位類型必填說明
idint用戶編號(1 或 2)
languagestring該用戶的語言代碼(須在 transcription_languages 中)

conversation_mode 說明:

模式說明
auto(預設)系統自動偵測說話語言,自動斷句
manual用戶透過 start_speaking / stop_speaking 控制說話時段,期間音訊合併為單一句子

廣播模式說明(type: "broadcast")

廣播模式時,語言設定會自動從廣播頻道設定取得,無需在 WebSocket 訊息中傳送。

必填參數:

參數類型說明
typestring必須為 "broadcast"
broadcast_tokenstring廣播 Token(透過 REST API 建立廣播後取得)
audio_formatstring音訊格式(pcmwebm

可選參數(覆蓋廣播頻道設定):

參數類型說明
tts_configobject多語言 TTS 設定(覆蓋建立時的設定)
summary_templatestring摘要模板 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 欄位類型說明
voicestringTTS 語音名稱
speaking_ratenumber語速(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_idstring會話 ID
recording_idstring錄音 ID(可用於後續 API 查詢)
recording_typestring錄音類型:transcribeconversationrecordbroadcast
recognition_modestring辨識模式:singlemulti_speaker
phasestring廣播階段:standbylive(僅廣播模式)
viewer_countint目前在線觀眾數(僅廣播模式)
queue_countint排隊等待中的觀眾數(僅廣播模式)
peak_viewersint本次廣播峰值觀眾數(僅廣播模式)
total_viewersint累計曾連線的觀眾總數(僅廣播模式)
messagestring狀態描述訊息

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
missing_transcription_languages400未提供語言參數確認請求包含 transcription_languages
invalid_transcription_language400無效的語言代碼確認語言代碼格式正確(如 zh-TW
too_many_languages400語言數量超過上限最多只能指定 2 個語言
invalid_recording_type400錄音類型無效使用有效的類型值
invalid_summary_template400摘要模板無效確認模板識別碼正確
stt_init_failed503服務初始化失敗稍後重試
auth_budget_exceeded402月度預算已超額等待下月預算重置或調整預算
tts_init_failed503TTS 服務初始化失敗稍後重試
tts_invalid_language400TTS 語言不在翻譯語言中確認 tts_languagetranslation_languages
broadcast_token_required400廣播模式需要 Tokenbroadcast 類型必須提供 broadcast_token
broadcast_token_invalid400廣播 Token 無效確認 Token 正確且未過期
broadcast_not_ready503廣播服務尚未啟動稍後重試
summary_invalid_mode400summary_mode 不是 builtin / custom改為合法 mode
summary_mode_field_mismatch400mode 與欄位組合不符(必填缺漏 / 禁帶被帶入)依 mode 規則調整欄位
summary_prompt_too_long400summary_prompt 超過 2000 字元縮短自訂 prompt
summary_prompt_slug_too_long400summary_prompt_slug 超過 64 字元縮短識別碼
summary_prompt_slug_invalid400summary_prompt_slug 含控制字元(\n / \r / \t / \0 等)移除控制字元

Voice Translation - config(設定術語庫/校正規則)

功能說明

在錄音開始前或進行中傳入術語庫、模糊詞校正規則和翻譯字典設定。這些設定可提升 STT 識別率、修正同音字錯誤、確保翻譯一致性。

自動生成校正規則:當傳入 terminology 時,系統會自動為每個術語生成模糊詞校正規則(同音字、近音字、繁簡體變體)。前端無需手動定義 fuzzy_correction,大幅簡化設定流程。

使用場景

  • 錄音開始前傳入專業術語(Phrase List)
  • 設定模糊詞校正規則(同音字修正)- 可選,系統會自動生成
  • 設定翻譯字典(確保術語翻譯一致)

傳送時機

設定類型建議時機錄製中更新
術語庫(terminology)start 之前或進行中支援(下一回合生效)
模糊詞校正start 之前或進行中支援
翻譯字典start 之前或進行中支援

注意:錄製中更新術語庫時,新的術語將在下一個辨識回合邊界自動生效,無需重新連線。回應中會包含 terminology_effective: "next_turn" 欄位提示。

請求參數

參數類型必填說明
actionstring固定為 config
terminologyobject術語庫設定
fuzzy_correctionobject模糊詞校正規則
translation_dictobject翻譯字典

注意:至少需要提供一個設定項目。

術語庫格式(terminology)

以語言代碼為 key,術語陣列為 value:

{
  "zh-TW": [
    { "term": "語者分離", "boost": 1.5 },
    { "term": "WebSocket", "boost": 2.0 }
  ],
  "en-US": [
    { "term": "diarization", "boost": 1.5 }
  ]
}
欄位類型必填說明
termstring術語(最大 100 字元)
boostnumber權重(預設 1.0,範圍 0.5-5.0)

限制:每種語言最多 500 個術語。

模糊詞校正格式(fuzzy_correction)

注意:此欄位通常不需要手動設定。系統會根據 terminology 自動生成校正規則。僅在需要自訂特殊規則時使用。

以語言代碼為 key,校正規則陣列為 value:

{
  "zh-TW": [
    { "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] }
  ]
}
欄位類型必填說明
correctstring正確詞彙
incorrectstring錯誤變體列表

自動生成校正規則說明

當傳入 terminology 時,系統會自動為每個術語生成模糊詞校正規則:

生成類型說明範例
同音字拼音相同的替代字語者 → 語這、語折
近音字聲調相近的替代字媽 → 麻、馬
繁簡體繁體/簡體轉換製程 → 制程

中英混合術語支援:對於「CVD製程」這類混合術語,系統只對中文部分生成變體,英文保持不變。

原術語自動生成的變體
CVD製程CVD制程、CVD之程、CVD製城
wafer良率wafer量率、wafer涼率
5nm製程5nm制程、5nm製成

翻譯字典格式(translation_dict)

直接使用條目陣列:

[
  {
    "source": "語者分離",
    "translations": {
      "en-US": "Speaker Diarization",
      "ja-JP": "話者分離"
    }
  }
]
欄位類型必填說明
sourcestring來源詞彙(使用 STT 語言)
translationsobject翻譯對照 { "語言代碼": "翻譯" }

限制:建議不超過 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": "設定已更新"
  }
}
欄位類型說明
updatedstring已更新的設定類型
messagestring狀態訊息

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
config_empty400未提供任何設定至少提供一個設定項目
config_term_too_long400術語超過 100 字元縮短術語長度
config_too_many_entries400術語數量超過 500 個減少術語數量
config_too_many_dict_entries400翻譯字典超過 50 條目減少字典條目

Voice Translation - audio(傳送音訊)

功能說明

傳送音訊資料給伺服器進行語音辨識。音訊需經過 Base64 編碼後傳送。

使用場景

  • 持續傳送麥克風音訊
  • 傳送錄製的音訊片段

請求參數

參數類型必填說明
actionstring固定為 audio
payloadstringBase64 編碼的音訊資料

音訊格式要求

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_started400語音辨識尚未開始先呼叫 start action
audio_invalid_format400音訊資料格式錯誤確認 Base64 編碼正確
audio_format_unsupported400不支援的音訊格式使用 pcmwebm 格式
audio_decode_failed400音訊解碼失敗確認音訊格式正確

Voice Translation - pause(暫停翻譯)

功能說明

暫停語音辨識處理。暫停期間收到的音訊會被快取,恢復後繼續處理。

使用場景

  • 使用者暫時離開
  • 需要暫停記錄

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "pause"
  }
}

成功回應

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "語音辨識已暫停"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
session_not_started400語音辨識尚未開始先呼叫 start
session_already_paused400已經暫停可忽略此錯誤

Voice Translation - resume(恢復翻譯)

功能說明

恢復已暫停的語音辨識處理。

使用場景

  • 使用者回來繼續
  • 需要繼續記錄

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "resume"
  }
}

成功回應

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "語音辨識已恢復"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
session_not_started400語音辨識尚未開始先呼叫 start
session_not_paused400未暫停可忽略此錯誤

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_idstringRecording UUID,可用於後續 API 查詢

Voice Translation - retranslate(重新翻譯)

功能說明

對指定句子重新翻譯,適用於修正原文後需要更新翻譯的情況。

使用場景

  • 用戶編輯原文後需要更新翻譯
  • 更正辨識錯誤

請求參數

參數類型必填說明
actionstring固定為 retranslate
sidint要重翻的句子編號
translation_languagesstring翻譯語言代碼陣列
textstring要翻譯的原文(用戶修正後的文字)

請求範例

{
  "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_found400找不到指定的 SID確認 SID 存在
retranslate_session_not_active400工作階段未啟動或已結束確認工作階段狀態
retranslate_no_target_lang400未提供目標語言提供 translation_languages
retranslate_no_text400未提供要翻譯的文字提供 text 參數
retranslate_llm_failed500翻譯服務失敗稍後重試

Voice Translation - switch_language(切換語言)

功能說明

在即時翻譯進行中切換語言。行為依錄音類型而異:

  • 一般模式(transcribe 等):切換翻譯目標語言,並自動批次重翻所有已翻譯句子
  • 互譯模式(conversation):切換 STT 來源語言(說話語言),翻譯目標自動切換為另一語言

使用場景

  • 切換翻譯目標語言
  • 會議中途更換語言需求

請求參數

參數類型必填說明
actionstring固定為 switch_language
translation_languagesstring條件翻譯語言代碼陣列(一般模式必填)
transcription_languagesstring條件切換目標語言(互譯模式;不帶則自動 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 警告

回應序列(一般模式)

切換語言後會依序收到以下事件:

  1. language_switch_start:通知開始切換
{
  "type": "voice-translation",
  "data": {
    "action": "language_switch_start",
    "translation_language": "ja-JP",
    "total_segments": 15,
    "message": "開始切換語言並重新翻譯"
  }
}
  1. batch_retranslation(多個):逐句回傳重翻結果
{
  "type": "voice-translation",
  "data": {
    "action": "batch_retranslation",
    "sid": 3,
    "translations": {
      "ja-JP": {
        "sid": 3,
        "text": "今日はプロジェクトの進捗について話し合いましょう",
        "is_final": true,
        "is_retranslation": true
      }
    }
  }
}
  1. 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_target400未提供目標語言提供 translation_languages
switch_language_in_progress400前一次切換尚未完成等待切換完成
switch_language_same_target400目標語言與當前相同可忽略此錯誤
conversation_requires_two_languages400互譯模式需恰好兩個語言確認 transcription_languages 為 2 個
conversation_languages_identical400互譯的兩個語言不可相同提供兩個不同的語言
conversation_invalid_language400無效的互譯語言確認語言在 transcription_languages 中
conversation_same_language400已是當前語言可忽略此警告

Voice Translation - set_name(設定錄音名稱)

功能說明

在錄音進行中設定名稱。設定後,錄音結束時將使用此名稱,不會自動生成。

提示:也可在 start 時透過 name 參數設定初始預設名稱,但該名稱在 Session 結束時仍可能被系統覆蓋。若需固定名稱,請使用 set_name

使用場景

  • 錄音開始後自訂錄音標題
  • 覆蓋自動生成的名稱或先前設定的名稱

請求參數

參數類型必填說明
actionstring固定為 set_name
namestring錄音名稱(最大 60 字)

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "set_name",
    "name": "產品規劃會議"
  }
}

成功回應

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "錄音名稱已更新"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
name_too_long400錄音名稱超過限制縮短名稱長度
session_not_started400語音辨識尚未開始先呼叫 start

Voice Translation - rename_speaker(全域重命名說話者)

功能說明

在多人語者分離模式(multi_speaker)下,全域重命名某個說話者。所有使用該說話者 ID 的句子都會同步更新。

使用場景

  • 將系統自動分配的說話者 ID(如 Guest-1)改為有意義的名稱(如 王經理
  • 會議中辨識出新的說話者後進行命名

請求參數

參數類型必填說明
actionstring固定為 rename_speaker
speaker_idstring原始語者 ID(如 Guest-1),可同時接受目前的顯示標籤做連續改名;最大 100 字元
new_labelstring新顯示標籤;最大 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_idstring解析後的原始語者 ID(即使輸入是顯示標籤,事件回傳仍是原始 ID)
new_labelstring新顯示標籤
affected_sidsint受影響的句子編號列表

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
speaker_not_found400找不到指定的說話者確認 speaker_id 或顯示標籤存在
speaker_name_empty400new_label 為空提供有效的標籤
speaker_name_duplicate422顯示標籤已被使用使用其他標籤,或先修改衝突的說話者
session_not_started400語音辨識尚未開始先呼叫 start

Voice Translation - reassign_speaker(修改單句語者身份)

功能說明

修改特定句子的語者身份(OriginalSpeakerID),將句子指派給既有語者。

使用場景

  • 更正系統辨識錯誤的語者身份
  • 將某句話重新指派給另一位已知語者

請求參數

參數類型必填說明
actionstring固定為 reassign_speaker
sidint要修改的句子編號
target_speaker_idstring目標語者原始 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": "李小華"
  }
}
欄位類型說明
sidint修改的句子編號
old_speaker_idstring原始語者 ID
new_speaker_idstring新的原始語者 ID
new_speaker_labelstring新語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於 new_speaker_id

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
speaker_sid_not_found400找不到指定的句子確認 SID 存在
speaker_not_found400目標語者不存在使用已存在的語者 ID
speaker_name_empty400目標語者 ID 不能為空提供有效的語者 ID
session_not_started400語音辨識尚未開始先呼叫 start
invalid_parameter400不支援建立新語者使用已存在的語者 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

請求參數

參數類型必填說明
actionstring固定為 merge_speakers
source_speaker_idstring要被合併的語者 ID(如 Guest-2
target_speaker_idstring合併目標語者 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_idstring被合併的原始語者 ID
target_speaker_idstring合併目標的原始語者 ID
target_speaker_labelstring目標語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於原始 ID)
affected_sidsnumber受影響的句子 ID 列表

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
speaker_not_found400語者不存在確認語者 ID 存在
merge_speakers_same_id400來源和目標語者相同使用不同的語者 ID
speaker_name_empty400語者 ID 不能為空提供有效的語者 ID
session_not_started400語音辨識尚未開始先呼叫 start

Voice Translation - tts_play(播放 TTS)

功能說明

async 模式下,手動播放指定句子的 TTS 語音。

使用場景

  • 用戶選擇特定句子進行 TTS 播放
  • 播放多個連續句子

請求參數

參數類型必填說明
actionstring固定為 tts_play
sidint起始句子 ID
lengthint播放句子數量(預設 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_enabled400TTS 未啟用確認 start 時啟用 TTS
tts_sid_not_found400找不到指定的句子確認 SID 存在
tts_translation_not_found400該句子沒有指定語言的翻譯確認翻譯存在

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 播放模式(同步/非同步)。

使用場景

  • 從自動播放切換為手動控制
  • 從手動控制切換為自動播放

請求參數

參數類型必填說明
actionstring固定為 tts_mode
tts_modestring模式: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_enabled400TTS 未啟用確認 start 時啟用 TTS
tts_invalid_mode400無效的模式使用 syncasync

Voice Translation - set_tts(互譯 TTS 設定)

功能說明

在互譯模式(conversation)錄音進行中,動態切換 TTS 開關或更新 TTS 語音設定。僅限互譯模式使用。

使用場景

  • 互譯對話中途關閉/開啟 TTS 語音回傳
  • 更換特定語言的 TTS 語音或語速

請求參數

參數類型必填說明
actionstring固定為 set_tts
tts_enabledboolean是否啟用互譯 TTS(true / false
tts_configobject各語言 TTS 設定,key 為語言代碼,value 為 {voice, speaking_rate}

注意tts_enabledtts_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_enabledboolean當前 TTS 啟用狀態
tts_configobject當前完整 TTS 設定(所有語言)

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
invalid_action400非互譯模式此 action 僅限 conversation 模式
session_not_started400語音辨識尚未開始先呼叫 start

Voice Translation - start_speaking(開始說話/手動模式)

功能說明

在互譯手動模式(conversation_mode: "manual")下,通知系統用戶開始說話。從此刻起,音訊會被傳送至 STT 進行辨識,所有辨識結果會累積為同一句話(不自動斷句)。

請求參數

參數類型必填說明
actionstring固定為 start_speaking
speakerint用戶編號(1 或 2)

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "start_speaking",
    "speaker": 1
  }
}

成功回應

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "開始說話"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
invalid_action400非互譯模式僅在 conversation 類型下使用
conversation_not_manual_mode400非手動模式僅在 manual 模式下使用
conversation_speaking400已在說話中先呼叫 stop_speaking
conversation_invalid_speaker400無效的用戶編號使用 1 或 2

Voice Translation - stop_speaking(結束說話/手動模式)

功能說明

在互譯手動模式下,通知系統用戶結束說話。系統會將期間累積的辨識結果合併為一個完整句子,進行翻譯和 TTS 合成。

請求參數

參數類型必填說明
actionstring固定為 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_action400非互譯模式僅在 conversation 類型下使用
conversation_not_speaking400未在說話狀態先呼叫 start_speaking

Voice Translation - switch_conversation_mode(切換對話模式)

功能說明

在互譯模式進行中,切換自動偵測模式(auto)與手動模式(manual)。切換時若正在說話中會自動結束說話。

請求參數

參數類型必填說明
actionstring固定為 switch_conversation_mode
conversation_modestring目標模式:automanual

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "switch_conversation_mode",
    "conversation_mode": "manual"
  }
}

成功回應

{
  "type": "voice-translation",
  "data": {
    "action": "conversation_mode_changed",
    "conversation_mode": "manual"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
invalid_action400非互譯模式僅在 conversation 類型下使用
conversation_invalid_mode400無效的對話模式使用 automanual

Voice Translation - set_speaker_language(設定用戶語言)

功能說明

在互譯模式進行中,即時變更指定用戶的語言。系統會重建 STT 連線以適應新語言,翻譯目標也會自動更新。變更前的逐字稿內容維持原語言不變,時間戳持續計算不歸零。

請求參數

參數類型必填說明
actionstring固定為 set_speaker_language
speakerint用戶編號(1 或 2)
languagestring新的語言代碼(如 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_action400非互譯模式僅在 conversation 類型下使用
conversation_invalid_speaker400無效的用戶編號使用 1 或 2
conversation_invalid_language400無效的語言代碼使用有效的 BCP 47 語言代碼
conversation_same_language400與當前語言相同可忽略此警告
conversation_language_same_as_peer400新語言與另一位用戶相同兩位用戶語言不可相同
conversation_speaking400正在說話中,無法變更語言先結束說話再變更
conversation_language_change_failed500語言變更失敗(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": "廣播已開始"
  }
}
欄位類型說明
phasestring新的階段(live
messagestring狀態描述訊息

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
broadcast_not_enabled400非廣播模式確認 type: "broadcast"
session_not_started400語音辨識尚未開始先呼叫 start

注意:若已在正式階段(live),會回傳狀態訊息「廣播已經在進行中」,不視為錯誤。


Voice Translation - broadcast_announcement(發送公告)

功能說明

主講者發送自訂訊息公告給所有觀眾。觀眾會透過 SSE 收到 announcement 事件。公告訊息會自動翻譯成所有翻譯語言,觀眾收到的 SSE 事件會包含 translations 欄位。

使用場景

  • 通知觀眾會議即將結束
  • 發送重要提醒或公告
  • 與觀眾進行單向溝通

請求參數

參數類型必填說明
actionstring固定為 broadcast_announcement
messagestring公告訊息內容

請求範例

{
  "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_enabled400非廣播模式確認 type: "broadcast"
invalid_parameter400訊息為空提供有效的 message 參數

Voice Translation - set_standby_message(設定預備階段文字)

功能說明

在廣播預備階段(standby)動態設定顯示給觀眾的訊息。允許主講者進入預備模式後再設定等待訊息,而非在 start 時就必須提供。

訊息會自動翻譯成所有翻譯語言,觀眾收到的 SSE 事件會包含 translations 欄位。

使用場景

  • 進入預備模式後,動態設定顯示給觀眾的等待訊息
  • 在正式開播前更新預備畫面的文字
  • 減少開始廣播前的必填欄位

請求參數

參數類型必填說明
actionstring固定為 set_standby_message
messagestring預備階段顯示文字(將透過現有翻譯流程翻譯給各語言觀眾)

請求範例

{
  "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_enabled400非廣播模式確認 type: "broadcast"
broadcast_not_in_standby400不在預備階段只能在 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_idstring會話 ID
recording_idstring錄音 ID(可用於後續 API 查詢)
recording_typestring錄音類型:transcribeconversationrecordbroadcast
recognition_modestring辨識模式:singlemulti_speaker
messagestring狀態描述訊息
phasestring廣播階段:standbylive(僅廣播模式)
viewer_countint目前在線觀眾數(僅廣播模式)
queue_countint排隊等待中的觀眾數(僅廣播模式)
peak_viewersint本次廣播峰值觀眾數(僅廣播模式)
total_viewersint累計曾連線的觀眾總數(僅廣播模式)

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"
    }
  }
}
欄位類型說明
sidint句子編號,從 1 開始
languagestring來源語言代碼。互譯模式下為自動偵測的語言
textstring辨識出的文字
is_finalboolean是否為最終結果
speaker_idstring說話者 ID
detected_languagestring偵測到的語言。互譯模式下由系統自動判定
start_timestring句子開始時間(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,每個語言的翻譯物件包含:

欄位類型說明
sidint句子編號
textstring翻譯後的文字
is_finalboolean是否為最終結果
is_retranslationboolean是否為重新翻譯結果(僅 retranslate 時)

status - 通用狀態回應

用於 pause、resume、stop、set_name 等操作的確認。

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "語音辨識已暫停"
  }
}
欄位類型說明
messagestring狀態描述

task_complete - 任務處理完成

stop 後音檔和逐字稿上傳完成時觸發。task_id 可用於後續 REST API 查詢任務詳情。

{
  "type": "voice-translation",
  "data": {
    "action": "task_complete",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "message": "任務處理完成"
  }
}
欄位類型說明
task_idstringRecording UUID,可用於後續 API 查詢
messagestring狀態描述

config_updated - 設定更新完成

config action 成功後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "config_updated",
    "updated": ["terminology", "fuzzy_correction", "translation_dict"],
    "message": "設定已更新"
  }
}
欄位類型說明
updatedstring已更新的設定類型(terminologyfuzzy_correctiontranslation_dict
messagestring狀態訊息

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"}
    ]
  }
}
欄位類型說明
sidint句子編號
languagestringTTS 語言
transcriptstring原始逐字稿(STT 識別結果)
textstring翻譯文字(TTS 合成來源)
audiostringBase64 編碼的 MP3 音訊
formatstring音訊格式(固定為 mp3
duration_msint音訊總時長(毫秒)
boundariesarrayWord Boundary 陣列

Word Boundary 欄位說明

欄位類型說明
offset_msint該字詞在音訊中的起始時間(毫秒)
duration_msint該字詞持續時間(毫秒)
text_offsetint在原文字串中的位置(字元索引)
word_lengthint字詞長度(字元數)
textstring字詞內容

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"
  }
}
欄位類型說明
sidint句子編號
languagestringTTS 語言
errorstring錯誤碼
messagestring錯誤訊息

TTS 錯誤碼

錯誤碼說明
translation_not_found找不到該語言的翻譯
tts_synthesis_failedTTS 合成失敗
tts_quota_exceededTTS 使用量已達上限

viewer_count - 觀眾人數更新

廣播模式專用

廣播進行中,系統每 3 秒檢查一次觀眾人數,若有變動則推送此事件給主講者。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_count",
    "viewer_count": 45,
    "queue_count": 8,
    "peak_viewers": 50,
    "total_viewers": 123
  }
}
欄位類型說明
viewer_countint目前在線觀眾數
queue_countint排隊等待中的觀眾數
peak_viewersint本次廣播峰值觀眾數
total_viewersint累計曾連線的觀眾總數

注意:此事件僅在觀眾人數或排隊人數有變動時才會推送,避免不必要的訊息傳輸。


viewer_joined - 觀眾加入

廣播模式專用

當觀眾加入廣播時,主講者會收到此事件。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_joined",
    "viewer_count": 5,
    "queue_count": 2
  }
}
欄位類型說明
viewer_countnumber目前觀眾人數
queue_countnumber排隊中的人數

viewer_left - 觀眾離開

廣播模式專用

當觀眾離開廣播時,主講者會收到此事件。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_left",
    "viewer_count": 4,
    "queue_count": 1
  }
}
欄位類型說明
viewer_countnumber目前觀眾人數
queue_countnumber排隊中的人數

broadcast_phase_changed - 廣播階段變更

當廣播階段從預備(standby)切換到正式(live)時觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_phase_changed",
    "phase": "live",
    "message": "廣播已開始"
  }
}
欄位類型說明
phasestring新的階段:standbylive
messagestring狀態描述訊息

speaker_renamed - 說話者重命名

全域重命名說話者完成事件。

{
  "type": "voice-translation",
  "data": {
    "action": "speaker_renamed",
    "speaker_id": "Guest-1",
    "new_label": "王經理",
    "affected_sids": [1, 3, 5, 8]
  }
}
欄位類型說明
speaker_idstring解析後的原始語者 ID(即使輸入是顯示標籤,事件回傳仍是原始 ID)
new_labelstring新顯示標籤
affected_sidsint受影響的句子編號列表

speaker_reassigned - 語者身份修改

修改單句語者身份完成事件。

{
  "type": "voice-translation",
  "data": {
    "action": "speaker_reassigned",
    "sid": 5,
    "old_speaker_id": "Guest-1",
    "new_speaker_id": "Guest-2",
    "new_speaker_label": "李小華"
  }
}
欄位類型說明
sidint修改的句子編號
old_speaker_idstring原始語者 ID
new_speaker_idstring新的原始語者 ID
new_speaker_labelstring新語者顯示標籤(套用 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_idstring被合併的原始語者 ID
target_speaker_idstring合併目標的原始語者 ID
target_speaker_labelstring目標語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於原始 ID)
affected_sidsnumber受影響的句子 ID 列表

language_switch_start - 語言切換開始

語言切換開始事件,在 switch_language action 觸發後送出。

{
  "type": "voice-translation",
  "data": {
    "action": "language_switch_start",
    "translation_language": "ja-JP",
    "total_segments": 15,
    "message": "開始切換語言並重新翻譯"
  }
}
欄位類型說明
translation_languagestring新的翻譯目標語言
total_segmentsint需要重新翻譯的句子數
messagestring狀態描述

batch_retranslation - 批次重翻結果

批次重翻結果事件,在語言切換過程中逐句送出。

{
  "type": "voice-translation",
  "data": {
    "action": "batch_retranslation",
    "sid": 3,
    "translations": {
      "ja-JP": {
        "sid": 3,
        "text": "今日はプロジェクトの進捗について話し合いましょう",
        "is_final": true,
        "is_retranslation": true
      }
    }
  }
}
欄位類型說明
sidint句子編號
translationsobject翻譯結果(格式同 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_languagestring翻譯目標語言
success_countint成功翻譯的句子數
failed_countint翻譯失敗的句子數
messagestring狀態描述

tts_mode_changed - TTS 模式變更

TTS 播放模式變更事件。

{
  "type": "voice-translation",
  "data": {
    "action": "tts_mode_changed",
    "tts_mode": "async"
  }
}
欄位類型說明
tts_modestring新的模式:syncasync

language_switched - 互譯語言切換完成

互譯模式(conversation)語言切換完成事件。當 switch_language 在互譯模式下成功切換 STT 來源語言後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "language_switched",
    "language": "en-US",
    "translation_language": "zh-TW",
    "message": "語言已切換"
  }
}
欄位類型說明
languagestring新的 active 語言(STT 來源)
translation_languagestring新的翻譯目標語言
messagestring狀態訊息

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_enabledbooleanTTS 是否啟用
tts_configobject各語言的 TTS 設定(voice、speaking_rate)

conversation_mode_changed - 對話模式變更

互譯模式(conversation)對話模式變更事件。當 switch_conversation_mode 成功切換自動/手動模式後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "conversation_mode_changed",
    "conversation_mode": "manual"
  }
}
欄位類型說明
conversation_modestring新的對話模式:automanual

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_mapobject變更後的用戶語言映射(key 為用戶編號字串)

segment_uploaded - 音訊分段上傳完成

音訊分段上傳完成事件。每當一個音訊片段成功上傳至雲端儲存時觸發,可用於前端顯示上傳進度。

{
  "type": "voice-translation",
  "data": {
    "action": "segment_uploaded",
    "segment_index": 0,
    "duration_sec": 30.5
  }
}
欄位類型說明
segment_indexnumber分段索引(從 0 開始)
duration_secnumber該分段的時長(秒)

stt_event - STT 連線狀態事件

STT 連線狀態事件。當語音辨識服務的連線狀態發生變化時觸發,可用於前端顯示 STT 服務狀態。

{
  "type": "voice-translation",
  "data": {
    "action": "stt_event",
    "event": "connected",
    "message": "STT 服務已連線"
  }
}
欄位類型說明
eventstring事件類型:connected / disconnected / error
messagestring事件描述訊息

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_codestring錯誤碼(程式化處理用)
severitystring嚴重程度:fatal / error / warning
messagestring人類可讀的錯誤訊息
contextstring錯誤來源分類
request_idstring請求追蹤 ID
timestampstring錯誤發生時間(ISO 8601)

嚴重程度說明

severity說明處理建議
fatal致命錯誤停止服務,要求重新連線
error操作失敗顯示錯誤提示,允許重試
warning警告顯示警告,不阻斷操作

完整錯誤碼列表請參考 錯誤碼參考


版本:V1.5.7 最後更新:2026-05-20

Copyright © 2026