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 - set_speaking_speed
  26. Voice Translation - add_channel
  27. Voice Translation - remove_channel
  28. Voice Translation - set_channel_language
  29. Voice Translation - broadcast_go_live
  30. Voice Translation - broadcast_announcement
  31. Voice Translation - set_standby_message
  32. 回應事件

連線資訊

項目值
端點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"
  }
}

句子級錯誤(如某句的某個語言翻譯失敗)會額外帶上 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": "llm_service",
      "translation_language": "ja-JP"
    }
  }
}

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": "llm_service",
      "last_error_code": "llm_provider_error",
      "fail_count": 5
    }
  }
}

完整觸發規則(連續失敗閾值、錯誤碼分類)請參考 錯誤碼參考 中的 translation_service_unavailable 區塊。

方案限制錯誤(吃到飽方案,v1.9.0)

使用「吃到飽方案」的 API Key 可能收到下列錯誤訊息(點數制不適用)。可透過 GET /api/v1/me/plan 查詢方案內容、用量與限制何時恢復:

錯誤碼severity說明客戶端處理
plan_feature_not_allowedfatal方案不含使用中的功能改用方案內功能或升級方案;可用 GET /api/v1/me/plan 查方案內容
concurrency_limit_reachederror同一把 API Key 的併發錄音達上限連線不會關閉;待其他錄音結束後重新 start
daily_limit_disconnecterror已達方案用量門檻,本場錄音中止可立即開始新的錄音(同一條連線上重新開始時,上一場處理完成後才會收到 session_started)
daily_limit_reachedfatal用量已達方案上限依方案規則重置(每日上限隔日重置)後恢復

plan_feature_not_allowed 有兩個發生時點:

  1. start 被拒:方案不含請求中啟用的功能時直接拒絕;連線不會關閉,可調整參數後重新 start。
  2. 錄音中檢查發現:例如中途開啟方案沒有的功能,下一分鐘開始前檢查發現後該場錄音中止。

即時錄音的用量上限在每一分鐘開始前判斷,達到時下一分鐘不會開始、也不計入用量。同一把 API Key 同時進行多場錄音時,達到定期中斷的門檻後,每一場都會在各自的下一分鐘開始前中斷。

另外,too_many_languages 的 details.max 除了系統上限(轉錄語言 10 種),也可能來自方案的「同時識別語言數上限」,details 帶 max 與 received。詳見 錯誤碼參考 – 方案限制錯誤。

單一訊息錯誤(單則訊息處理失敗、連線保持)

當伺服器在處理單一 WebSocket 訊息(如 set_name、switch_language、tts_play 等)時發生未預期的內部錯誤,會回傳 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_name、switch_language、tts_play、tts_mode、retranslate、config、speaker.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 不存在表示錯誤發生在訊息內容解析之後,系統無法回推是哪一個操作。前端可依「使用者最近送出的訊息」反推;或顯示通用錯誤訊息「操作失敗,請重試」。
  3. 使用者體驗:建議顯示 transient toast / inline error,不要用 modal 或 redirect 中斷使用者流程。
  4. 遙測 / 上報:建議把 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;

  // 單則訊息處理失敗:保持連線、視 action 決定是否重試
  if (error_code === 'internal_error') {
    console.warn('[ws] message handler internal error', {
      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:provider、translation_language、source_lang 等

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


Health(心跳服務)

功能說明

用於確認 WebSocket 連線是否正常。建議每 30 秒發送一次 ping,若未收到 pong 則視為斷線並重連。上一場錄音結束後仍在處理中時(例如正在產生摘要),pong 可能延後數秒到數十秒;請保留足夠的等待時間,不要只因暫時沒有收到 pong 就判定斷線。

使用場景

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

請求 - Ping

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

回應 - Pong

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

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

功能說明

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

使用場景

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

請求參數

參數類型必填說明
actionstring是固定為 start
transcription_languagesstring[]是語音辨識語言(最多 10 個)
translation_languagesstring[]否翻譯目標語言,可多個(最多 12 個;空=不翻譯)。transcribe / broadcast 自 v1.6.7 起會即時翻譯全部指定語言,每個語言各回一則 result 事件(同一 sid、translations 內單一語言 key),客戶端需以語言代碼累積、不可互相覆蓋。互譯(conversation)不適用:此欄位由伺服器覆寫為對方語言、恆為單一語言。record 自 v1.7.0 起不支援翻譯,帶此欄位會回 400 record_translation_not_allowed。詳見 WebSocket 參考
realtime_translationboolean否即時翻譯模式(預設 false)。true:句子辨識過程中(interim)即逐字翻譯;false:整句完成才翻譯。多語言翻譯的即時程度同樣由本旗標決定。廣播(broadcast)一律視為 true;互譯(conversation)不受此欄位影響,只翻整句
recognition_modestring否辨識模式:single(單人,預設)、multi_speaker(多人)、multi_channel(多聲道,v1.10.0:一場錄音接多支實體麥克風、語者由聲道決定,詳見下方「多聲道模式說明」);multi_speaker 下 transcription_languages 必須恰好 1 個,否則回傳 diarization_multilang_conflict 錯誤並拒絕開始(type=conversation 除外:互譯強制單人模式,自 v1.7.2 起豁免此檢查)
typestring是錄音類型:transcribe、conversation、record、broadcast
audio_formatstring否音訊格式:pcm(預設)、webm
summary_templatestring條件摘要模板。transcribe 在 summary_mode=builtin 時必填;summary_mode=custom 禁帶;conversation/broadcast 可選
optionsobject否語音辨識選項
tts_enabledboolean否是否啟用 TTS 語音合成(預設 false)
tts_languagestring否TTS 輸出語言(需在 translation_languages 中)
tts_voicestring否TTS 語音名稱(如 en-US-JennyNeural)
tts_modestring否TTS 播放模式:sync(同步,預設)、async(非同步)。只接受小寫的這兩個值,空字串視同未帶(sync);其他值(例如 "Async")會被拒絕(invalid_parameter,details.field 為 tts_mode),錄音不會開始。不論錄音類型、是否開啟 TTS 都會檢查
broadcast_tokenstring條件廣播 Token(broadcast 類型必填,從 REST API 取得)。只能搭配 broadcast 類型:其他類型帶了會被拒絕(invalid_parameter,details.field 為 broadcast_token),錄音不會開始
active_languagestring否互譯模式初始 active 語言(預設 transcription_languages[0])
speakersarray否互譯模式用戶語言映射(有帶時須恰好 2 位)。沒帶時,用戶 1 對應 transcription_languages[0]、用戶 2 對應 transcription_languages[1]
conversation_modestring否互譯對話模式:auto(自動偵測,預設)、manual(手動 PTT)。只接受小寫的這兩個值,空字串視同未帶(auto);其他值會被拒絕(invalid_parameter,details.field 為 conversation_mode),錄音不會開始。非互譯類型帶了也會檢查
speaker_diarizationboolean否語者分離(互譯模式下強制忽略)
tts_configobject否多語言 TTS 設定(廣播模式及互譯模式皆適用)
broadcast_phasestring否廣播初始階段:standby(預備)、live(正式,預設)。只接受小寫的這兩個值,空字串視同未帶(live);其他值(例如 "Live")會被拒絕(invalid_parameter,details.field 為 broadcast_phase),錄音不會開始
standby_messagestring否預備階段觀眾看到的訊息(預設:「準備中,請稍候...」)
namestring否初始預設錄音名稱(去掉前後空白後最多 60 字元,系統仍可覆蓋;未提供則自動生成如 Transcription #1)。超過上限會被拒絕(invalid_parameter,details.field 為 name),錄音不會開始
summary_languagestring否摘要輸出語言(不指定時預設使用辨識語言;廣播模式自動從頻道設定讀取)。最多 20 字元,超過會被拒絕(invalid_parameter,details.field 為 summary_language),錄音不會開始
summary_modestring否摘要模式 enum:builtin(預設)/ custom。缺值時自動推斷 builtin
summary_promptstring否custom mode 必填(只含空白字元視同未填)、builtin mode 為補充指示。≤3000 字元
summary_prompt_slugstring否custom mode 必填(只含空白字元視同未填)、builtin mode 禁帶。客戶自家識別碼(≤64 字元,Unicode、禁控制字元;pass-through 保存於後端記錄,供歷史查詢)
summary_plain_textboolean否摘要要求純文字輸出(預設 false;開啟後後端做 Markdown 後處理)
channel_modestring條件多聲道子模式(recognition_mode=multi_channel 必填):per_channel(每路聲道獨立辨識)或 shared(各路輪流發言、共用一條辨識)。其他值回 invalid_channel_mode
channelsarray條件多聲道聲道清單(recognition_mode=multi_channel 必填,含主講者,慣例 channel_id: 1)。詳見下方「多聲道模式說明」
silenceTimeoutSecondsinteger否連續多少秒沒有偵測到語音就自動結束錄音:不帶或 null 使用預設值(900 秒);0 表示這一場不會因為沒有語音而結束;其餘須為 60~86400 的整數,其他值會被拒絕。詳見下方 長時間沒有語音時自動結束

options 子欄位

options 為語音辨識選項物件,皆為選用;省略時用各自預設值。

欄位類型預設說明
speaking_speedstringnormal說話速度,影響斷句的靜音判斷門檻:very_slow / slow / normal / fast / very_fast。預設 normal(對應 800ms 靜音門檻;各等級的門檻見 speaking_speed 等級)。講者較慢時調慢(門檻拉長,避免句中停頓被誤切);較快時調快(更早斷句)。可於錄音中透過 set_speaking_speed 動態調整。只接受小寫的這五個值,空字串視同未帶(normal);其他值會被拒絕(invalid_parameter,details.field 為 options.speaking_speed),錄音不會開始
profanity_handlingstringmask敏感詞處理:mask(以 *** 遮蔽)/ remove(移除)/ show(顯示原文)。只接受小寫的這三個值,空字串視同未帶(mask);其他值會被拒絕(invalid_parameter,details.field 為 options.profanity_handling),錄音不會開始

註:以上選項作用於 STT 斷句;多人模式(multi_speaker)目前不套用 speaking_speed。

錄音類型說明

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",
      "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。

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

錄音類型預設名稱格式
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",
    "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",
    "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 查詢任務,讀取回應中的 summary_mode / summary_template / summary_prompt_slug 三個欄位

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

互譯模式特殊規則:

項目說明
transcription_languages必須恰好 2 個,且不可相同
translation_languages不需提供(自動推導為非 active 的語言)
realtime_translation互譯模式下沒有作用:翻譯只在整句辨識完成後才會送出,不論此欄位設為 true 或 false 結果相同
active_language可選,預設 transcription_languages[0]
recognition_mode強制 single(忽略 speaker_diarization)
tts_enabled預設 true;設為 false 僅回傳文字翻譯
tts_config可選,為兩個語言各自設定 TTS 語音;留空自動使用預設語音
summary_template可選,提供時停止後自動生成摘要
speakers可選,指定每位用戶的語言(有帶時恰好 2 位);沒帶時,用戶 1、2 依序對應 transcription_languages 的兩個語言
conversation_mode可選,auto(自動偵測,預設)或 manual(手動 PTT)

speakers 欄位說明:

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

conversation_mode 說明:

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

多聲道模式說明(recognition_mode: "multi_channel")

一場錄音同時接多支實體麥克風,語者身分由聲道決定(非 AI 推斷),逐字稿的語者歸屬即為各路 channel_id 對應的講者。有兩種子模式:

  • per_channel:每支麥克風各自獨立進行語音辨識,各路可同時說話、可各自綁定不同語言。
  • shared:各路輪流發言、共用一條辨識,全場共用同一組語言。適合同一時間只有一個人說話的場合,詳見下方 shared 模式。

適用範圍與限制:

項目說明
錄音類型僅 transcribe 與 record;conversation 回 invalid_parameter、broadcast 回 multichannel_broadcast_not_allowed
功能開通多聲道需開通後才能使用;未開通的環境 start 回 invalid_recognition_mode
channel_mode必填,未帶回 channel_mode_required。可用值為 per_channel 與 shared,其他值回 invalid_channel_mode
channels必填(未帶回 channels_required),1–8 路(含主講者,慣例 channel_id: 1);channel_id 值域 1–8、不可重複
每路語言per_channel 下每路必須指定恰好 1 個轉錄語言(一路綁一種語言);各路語言的聯集(去重後)必須與 session 級 transcription_languages 完全一致,否則回 channel_language_mismatch。shared 下各路不可帶 transcription_languages(回 channel_language_not_allowed),全場使用 session 級 transcription_languages
audio_format僅支援 pcm(16kHz / 16bit / mono / little-endian);其他值回 multichannel_requires_pcm
TTS首版不支援:tts_enabled: true 回 multichannel_tts_not_allowed
speaker_diarization不可同時指定(多聲道本身即為語者分離的一種),同時帶回 invalid_parameter
方案限制吃到飽方案需含多聲道功能;方案可另設同時辨識路數上限,超過在 start 當場回 plan_feature_not_allowed(details.field="max_stt_streams")。shared 固定以 1 路辨識採計
音檔長度上限一場多聲道錄音保存的音訊有總量上限,開著的聲道越多越早碰到(8 路約 70 分鐘)。碰到上限後,音檔與錄音時長(duration_ms)停在上限當下,逐字稿與扣點照常繼續

channels 欄位說明:

欄位類型必填說明
channel_idint是聲道編號,值域 1–8、不可重複;含主講者,慣例主講者為 1
speaker_namestring否該路講者顯示名稱(最大 100 字元、不可含控制字元,否則回 invalid_parameter);未提供時以語者 ID(channel_{N})顯示
transcription_languagesstring[]條件該路轉錄語言。per_channel 必填、恰好 1 個(缺漏或多個回 channel_language_required);shared 不可帶(回 channel_language_not_allowed)

多聲道模式請求範例:

{
  "type": "voice-translation",
  "data": {
    "action": "start",
    "type": "transcribe",
    "recognition_mode": "multi_channel",
    "channel_mode": "per_channel",
    "transcription_languages": ["zh-TW", "en-US"],
    "translation_languages": ["ja-JP"],
    "audio_format": "pcm",
    "channels": [
      { "channel_id": 1, "speaker_name": "王經理", "transcription_languages": ["zh-TW"] },
      { "channel_id": 2, "speaker_name": "Alex", "transcription_languages": ["en-US"] },
      { "channel_id": 3, "speaker_name": "李小華", "transcription_languages": ["zh-TW"] }
    ]
  }
}

成功回應(session_started,多聲道):

data 頂層額外帶 channel_mode 與 channels[](每路含 channel_id、speaker_name、transcription_languages、status;shared 模式不帶 transcription_languages)。前端應以此確認伺服器確實進入多聲道模式:

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "transcribe",
    "recognition_mode": "multi_channel",
    "channel_mode": "per_channel",
    "channels": [
      { "channel_id": 1, "speaker_name": "王經理", "transcription_languages": ["zh-TW"], "status": "preparing" },
      { "channel_id": 2, "speaker_name": "Alex", "transcription_languages": ["en-US"], "status": "preparing" },
      { "channel_id": 3, "speaker_name": "李小華", "transcription_languages": ["zh-TW"], "status": "preparing" }
    ],
    "resume_token": "L0VBAwIy...(43 字元)",
    "resume_grace_seconds": 45,
    "server_time": 1749550000000,
    "message": "語音辨識已開始"
  }
}

多聲道模式行為摘要:

  • 每個 audio 幀必帶 channel_id(見 audio 章節);建議每 100ms 一幀,每路即使靜音也要持續送。單一聲道沒有聲音不會結束錄音,見 長時間沒有語音時自動結束
  • result 事件的 origin 帶 channel_id 與 speaker_id(格式 channel_{N})、speaker_label(=speaker_name,經 rename_speaker 改名後為新標籤);translations 不帶 channel_id,以 sid 對回 origin
  • 錄音中可用 add_channel / remove_channel / set_channel_language 動態增減聲道與換語言;switch_language 一律回 multichannel_switch_language_not_allowed
  • rename_speaker 可用(可在該路尚未發言前先改名);reassign_speaker 與 merge_speakers 不適用於多聲道(語者身分由實體聲道決定)
  • 聲道狀態變化透過 channel_status 事件通知

shared 模式(輪流發言)

channel_mode: "shared":各路麥克風輪流發言、共用一條辨識。語者依「那段聲音是從哪一路送進來的」標記,在輪流發言的場合準確度高;計費固定以 1 路採計(見 計費說明)。

請求範例:

{
  "type": "voice-translation",
  "data": {
    "action": "start",
    "type": "transcribe",
    "recognition_mode": "multi_channel",
    "channel_mode": "shared",
    "transcription_languages": ["zh-TW", "en-US"],
    "audio_format": "pcm",
    "channels": [
      { "channel_id": 1, "speaker_name": "主持人" },
      { "channel_id": 2, "speaker_name": "來賓 A" },
      { "channel_id": 3, "speaker_name": "來賓 B" }
    ]
  }
}

session_started 帶回 channel_mode: "shared";channels[] 每路不帶 transcription_languages。

客戶端必須遵守:

項目說明
同一時刻只送一路同一時間只送目前發言者那一路的 audio。同時送多路時,各路聲音會依收到的順序排進同一條辨識,逐字稿會錯亂(計費不受影響)
持續送靜音沒有人說話時,目前那一路也要持續送靜音(建議每 100ms 一幀),不要停送
音訊格式僅 pcm(同多聲道共通規則)
語言全場共用 session 級 transcription_languages;各路不可指定語言,錄音中也不能變更(set_channel_language 回 channel_language_not_allowed)
第一路不可移除channels[] 的第一路承載全場的辨識,remove_channel 不可移除它(回 channel_remove_not_allowed);其他路可移除

聲道狀態:

  • 其他聲道的 status 跟著第一路:第一路轉 ready 時全部一起轉 ready;第一路重新準備辨識(暫停恢復、斷線續接、自動重連)時全部一起回到 preparing。每一路都會各自收到一則 channel_status 事件,reason 與第一路相同。斷線續接時的 preparing 由 resume_ok 的快照帶回,不另送事件。
  • 錄音中 add_channel 新增的聲道,直接套用第一路當下的狀態。
  • removed 依各路自己的狀態;已移除的聲道不會再收到事件。
  • 第一路變成 error 時,其他聲道也一起變成 error(reason 相同);第一路恢復時一起恢復。
  • session_started 與 resume_ok 的 channels[] 快照依同一規則。

已知限制:

  • 換人的間隔小於約 0.8 秒時,前後兩人的話可能被併成一句,整句只標一個語者。
  • 語者依聲道標記決定,語者 API 的合併、改派不適用(同多聲道共通規則),無法事後修正。
  • 暫停恢復後的補轉錄是整條最後 60 秒,所有聲道一起補、語者照標(見 pause)。

多聲道 start 專屬錯誤:

錯誤碼HTTP 狀態碼說明處理建議
invalid_recognition_mode400多聲道功能未在此環境開通聯繫平台開通多聲道功能
channel_mode_required400未指定 channel_mode帶 channel_mode(per_channel 或 shared)
invalid_channel_mode400channel_mode 不是 per_channel 或 shared;shared 在此環境未開通時也回此錯(details.message 說明)改用 per_channel 或 shared;未開通時改用 per_channel
channel_language_not_allowed400shared 模式的聲道帶了 transcription_languages(details 帶 channel_id)移除各路的 transcription_languages,改用 session 級設定
channels_required400未提供 channels提供 1–8 路聲道設定(含主講者)
too_many_channels400聲道數超過上限(details 帶 max 與 received)減少聲道數
invalid_channel_id400channel_id 超出值域(1–8)或重複使用 1–8 且不重複的編號
channel_language_required400某路未指定恰好一種轉錄語言(details 帶 channel_id)每路 transcription_languages 帶恰好 1 個語言
channel_language_mismatch400各路語言聯集與 transcription_languages 不一致(details 帶兩邊清單)對齊兩邊的語言清單
multichannel_requires_pcm400audio_format 不是 pcm改用 pcm(16kHz / 16bit / mono)
multichannel_tts_not_allowed400多聲道首版不支援語音合成關閉 tts_enabled
multichannel_broadcast_not_allowed400廣播不支援多聲道模式廣播請改用其他辨識模式
invalid_parameter400與 speaker_diarization 同時指定、type=conversation、或 speaker_name 格式錯誤(details.field 標明欄位)依 details 修正參數

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

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

必填參數:

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

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

參數類型說明
tts_configobject多語言 TTS 設定(覆蓋建立時的設定)
summary_templatestring摘要模板 slug(覆蓋建立時的設定,不提供則使用廣播頻道預設值)

自動設定的參數(可省略):

  • transcription_languages:自動從廣播設定讀取
  • translation_languages:自動從廣播設定讀取
  • realtime_translation:廣播模式一律啟用,帶 false 也視為 true;翻譯一律以即時翻譯計費
  • summary_template:自動從廣播設定讀取(WebSocket 傳入值優先)
  • summary_language:自動從廣播設定讀取(WebSocket 傳入值優先)

主講端與觀眾端都會收到翻譯的中間結果:同一句翻譯先送出 is_final: false,最後才送出 is_final: true 的定稿。請以 sid 加 language 覆蓋顯示;只想顯示定稿,略過 is_final: false 即可。

錄音名稱不會沿用頻道名稱。start 未帶 name 時,自動生成如 Broadcast #1;命名方式與其他類型相同,見錄音名稱規則。

廣播階段說明:

broadcast_phase說明行為
live(預設)正式階段STT/翻譯結果廣播給觀眾,寫入逐字稿
standby預備階段STT/翻譯結果只給主講者,觀眾看到 standby_message

預備階段用途:讓主講者在正式開始前進行 STT/翻譯熱機測試,確認設備正常後再切換到正式階段。

預備階段有時間上限(預設 30 分鐘):累計達上限,這一場會自動結束;到期前約 2 分鐘先送出預警。詳見 預備階段的時間上限。

broadcast_phase 只接受小寫的 standby、live:空字串視同 live,其他值會被拒絕(invalid_parameter)。

廣播模式請求範例:

{
  "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",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "transcribe",
    "recognition_mode": "single",
    "resume_token": "L0VBAwIy...(43 字元)",
    "resume_grace_seconds": 45,
    "server_time": 1749550000000,
    "message": "語音辨識已開始"
  }
}

廣播模式(broadcast):

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_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,
    "resume_token": "L0VBAwIy...(43 字元)",
    "resume_grace_seconds": 45,
    "server_time": 1749550000000,
    "message": "語音辨識已開始"
  }
}
欄位類型說明
session_idstring會話 ID
task_idstring任務 ID(可用於後續 API 查詢)
recording_typestring錄音類型:transcribe、conversation、record、broadcast
recognition_modestring辨識模式:single、multi_speaker
phasestring廣播階段:standby 或 live(僅廣播模式)
viewer_countint目前在線觀眾數(僅廣播模式)
queue_countint排隊等待中的觀眾數(僅廣播模式)
peak_viewersint本次廣播峰值觀眾數(僅廣播模式)
total_viewersint累計曾連線的觀眾總數(僅廣播模式)
messagestring狀態描述訊息

多聲道模式:data 頂層另帶 channel_mode 與 channels[],範例與欄位說明見上方「多聲道模式說明」。

長時間沒有語音時自動結束

錄音連續一段時間沒有辨識出任何文字(包含尚未定稿的中間結果),會自動結束,避免忘記停止的錄音持續計費。

  • 預設門檻為 900 秒(15 分鐘),可用 silenceTimeoutSeconds 逐場調整;結束前約 2 分鐘會先送出一次預警。
  • 辨識出文字就從 0 重新計時;resume 與 start_speaking 也會重新計時。
  • 以下情況不計時:
    • 暫停中:恢復後從 0 重新計時。暫停期間照常計費,要停止計費請結束錄音。
    • 斷線等待續接的期間:續接後接著原本的秒數計算。
    • 廣播(type: "broadcast"):整場都不會因為沒有語音而結束。預備階段另有時間上限,見 廣播功能指南。
  • 多聲道:所有聲道都沒有辨識出文字才算;單一聲道沒有聲音不會結束錄音。
  • 互譯手動模式:沒有按下說話時辨識到的聲音,也會重新計時。

silenceTimeoutSeconds 的值(start 的 data 頂層,選填)

值效果
不帶,或 null使用預設門檻
0這一場不會因為沒有語音而自動結束,適合長時間開著、可能長時間沒人說話的場合
60~86400 的整數這一場的門檻秒數
其他值start 被拒絕,錯誤碼 invalid_parameter(details.field 為 silenceTimeoutSeconds),錄音不會開始
  • 必須是 JSON 整數:字串(例如 "900")、小數寫法(例如 900.0、1e3)、布林值都會被拒絕。
  • 參數名稱是 silenceTimeoutSeconds;寫成 silence_timeout_seconds 會被拒絕(details.field 為 silence_timeout_seconds),不會被忽略。
  • 廣播帶合法的值不會生效,但不合法的值一樣會被拒絕。
  • 門檻在 120 秒以下時不會送出預警,時間到就直接結束。
  • 斷線續接會沿用原本的設定;開始新的一場錄音時要再帶一次。

會收到的事件

  1. stt_silence_warning(error 事件,severity: "warning"):預警,錄音照常進行。details.silenceSeconds 為已經持續的秒數,details.remainingSeconds 為剩下的秒數。不要當成錄音結束;辨識出文字、或恢復錄音,就會重新計時。
  2. stt_silence_timeout(severity: "fatal"):錄音已自動結束。details.silence_seconds 為判定的門檻秒數。
  3. 接著依序收到 status: "ended" 與 task_complete,和客戶端送出 stop 相同:錄音照常保存、產生摘要,計費算到結束為止。
{
  "type": "error",
  "data": {
    "error_code": "stt_silence_warning",
    "severity": "warning",
    "message": "No speech detected for a while; the recording will end automatically soon",
    "context": "stt",
    "request_id": "req_abc123xyz789",
    "timestamp": "2026-09-25T10:28:00.000Z",
    "details": {
      "silenceSeconds": 780,
      "remainingSeconds": 120
    }
  }
}

收到 stt_silence_timeout 後請停止送出音訊;之後送達的音訊會各回一則 session_not_started,可以忽略。

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
missing_transcription_languages400未提供語言參數確認請求包含 transcription_languages
invalid_transcription_language400無效的語言代碼確認語言代碼格式正確(如 zh-TW)
too_many_languages400語言數量超過上限(details.max 可能為系統上限或方案的同時識別語言數上限)轉錄語言最多 10 種、翻譯語言最多 12 種;吃到飽方案依 details.max 調整
invalid_recording_type400錄音類型無效使用有效的類型值
audio_format_unsupported400audio_format 不支援,details.supported_formats 列出可用值改用可用的音訊格式
invalid_summary_template400摘要模板無效確認模板識別碼正確
stt_init_failed503服務初始化失敗稍後重試
auth_insufficient_credit402點數不足儲值點數後再使用
auth_quota_exceeded402可用點數不足,錄音未開始(即時錄音為不足一分鐘;連線不關閉;details.remaining_budget 為最近一次結算時的可用點數,details.budget_scope 說明那是誰的額度)儲值後重新 start
daily_limit_reached—用量已達方案上限,錄音未開始依方案規則重置(每日上限隔日重置)後恢復
auth_service_error500服務暫時不可用,錄音未開始(連線不關閉)稍後重新 start
plan_feature_not_allowed403吃到飽方案不含請求中啟用的功能(連線不關閉)改用方案內功能或升級方案;可用 GET /api/v1/me/plan 查方案內容
concurrency_limit_reached—同一把 API Key 的併發錄音達上限(連線不關閉)待其他錄音結束後重新 start
service_shutdown—服務正在關閉,錄音未開始,之後連線會關閉稍後重新連線再 start
tts_init_failed503TTS 服務初始化失敗稍後重試
tts_invalid_language400TTS 語言不在翻譯語言中確認 tts_language 在 translation_languages 中
broadcast_token_required400廣播模式需要 Tokenbroadcast 類型必須提供 broadcast_token
broadcast_token_invalid401廣播 Token 無效確認 Token 正確且未過期
broadcast_not_ready503廣播服務尚未啟動稍後重試
summary_invalid_mode400summary_mode 不是 builtin / custom改為合法 mode
summary_mode_field_mismatch400mode 與欄位組合不符(必填缺漏 / 禁帶被帶入)依 mode 規則調整欄位
summary_prompt_too_long400summary_prompt 超過 3000 字元縮短自訂 prompt
summary_prompt_slug_too_long400summary_prompt_slug 超過 64 字元縮短識別碼
summary_prompt_slug_invalid400summary_prompt_slug 含控制字元(\n / \r / \t / \0 等)移除控制字元
invalid_parameter400參數不合法,例如 silenceTimeoutSeconds 的值或名稱不合法、broadcast_phase 的值不合法、非 broadcast 類型帶 broadcast_token、name 超過 60 字元、summary_language 超過 20 字元,或 options.speaking_speed、options.profanity_handling、conversation_mode、tts_mode 的值不在可用清單內(details.valid_values 列出可用的值)依 details.field 修正參數

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

功能說明

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

術語庫也會參與同音校正:傳入 terminology 時,術語會同時成為同音比對的依據 —— 逐字稿中讀音相同但用字不同的片段會被修正回術語的寫法。因此只設定 terminology 就能得到校正效果,不必手動列出可能的錯字。

數量限制

各區塊的筆數上限、長度上限與對應的錯誤碼,整理在 字庫使用指南 → 數量限制。

上限的數字是預設值,實際生效值可依環境調整 —— 一律以錯誤回應 details 裡的 max 為準, 不要把數字寫死在整合裡。

使用場景

  • 錄音開始前傳入專業術語(Phrase List)
  • 設定模糊詞校正規則(同音字修正)- 可選,術語庫本身已提供同音校正
  • 設定翻譯字典(確保術語翻譯一致)

傳送時機

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

注意:錄製中更新術語庫、模糊詞校正或翻譯字典時,新設定從送出後的下一句起生效,正在辨識的那一句不保證套用,無需重新連線。更新術語庫時,回應中會包含 terminology_effective: "next_turn" 欄位提示。

請求參數

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

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

注意:全有全無:三個區塊的驗證在任何一項套用之前一次做完。任一項驗證失敗即回錯,三個區塊都不會套用,設定維持原狀。

例如送出「合法的術語庫 + 超過 3000 條的翻譯字典」會收到 config_too_many_dict_entries,而術語庫也不會生效。修正後重送完整的 config 即可,三個區塊都是整批覆蓋,重送不會與先前的設定疊加。

術語庫格式(terminology)

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

{
  "zh-TW": [
    { "term": "語者分離" },
    { "term": "WebSocket" }
  ],
  "en-US": [
    { "term": "diarization" }
  ]
}
欄位類型必填說明
termstring是術語(最大 100 字元)

限制:一次 config 的所有語言合計最多 500 筆術語——不是每種語言各 500。超過時回 config_too_many_entries(details 帶 count 與 max)。

語言適用範圍:術語只會套用在語言代碼相符的辨識語言上。多聲道的每一路、多人語者分離、音檔匯入這幾種單一語言的情境,只會使用該語言的術語;多語轉錄與互譯則使用本次宣告語言的術語。登記在本次未使用語言底下的術語不會生效,但仍計入上述 500 筆合計。

這些數字是預設值:實際生效的上限可依環境調整,一律以錯誤回應 details 裡的 max 為準。

模糊詞校正格式(fuzzy_correction)

注意:此欄位通常不需要手動設定 —— 讀音相同或相近的錯字,terminology 就能修正。以下三種情況才需要用它:

  1. 錯字本身是常見詞(會被常見詞保護擋下),例如把「晶圓」聽成「金元」
  2. 錯字與正確詞讀音差距很大,例如外語品牌名被聽成音韻無關的詞
  3. 日文、韓文、英文的錯字(這些語言不參與同音比對)

correct 若為中文,同樣會成為同音比對的依據 —— 未列在 incorrect 的同音錯法也會被修正回 correct。case_insensitive 只作用於 incorrect 的字面比對,不影響同音比對。

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

{
  "zh-TW": [
    { "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] },
    { "correct": "IPEVO", "incorrect": ["ltfo"], "case_insensitive": true }
  ]
}
欄位類型必填說明
correctstring是正確詞彙
incorrectstring[]條件錯誤變體列表,每項最多 200 字元。中文術語可以省略(見下方說明);其他情況必填,空陣列會回 config_invalid_entry(reason: "empty")
case_insensitiveboolean否本條規則的變體是否忽略大小寫(預設 false = 嚴格比對)

只給正確詞、不列錯字:correct 是中文(含漢字)時,incorrect 可以整個省略 —— 系統會依讀音自動比對,逐字稿中讀音相同或相近的寫法會被修正回 correct。

{ "fuzzy_correction": { "zh-TW": [{ "correct": "艾思通" }] } }

上例不必列出任何錯字,「愛思通」「愛時通」「愛司東」「愛似通」都會被修正。 只有讀音差距較大的寫法(例如「愛自動」)或音節數不同的(例如「愛松」)才需要另外列進 incorrect。

注意:兩個條件缺一不可:語言要是中文(zh-TW / zh-CN / zh-HK 等),且 correct 要含漢字。 不滿足時 incorrect 仍為必填 —— 因為那些情況省略了不會有任何效果, 收下反而會讓你以為設定成功。日文、韓文、英文的錯字請明確列出。

大小寫:case_insensitive 為選填、預設 false(嚴格比對)。設為 true 時,該條規則的所有 incorrect 變體都會忽略大小寫。旗標是逐條的 —— 同一個 correct 可拆成多條規則各自設定,例如把不會與一般詞彙衝突的變體設為忽略大小寫、把可能撞到人名的變體維持嚴格。對中文規則無作用(中文無大小寫概念)。

注意:開啟後誤傷面會擴大:若 ivo 設為忽略大小寫,人名 Ivo 也會被替換。

同一個錯誤變體出現在多條規則時:碰撞以 incorrect(錯誤變體)為準判斷,不是 correct。

  • 多條規則指向不同正確詞時,實際生效的是哪一條不保證,請勿依賴任何順序(包含登記順序)
  • 大小寫旗標取嚴格優先——只要有任一條沒開 case_insensitive,該變體就以嚴格比對處理

「嚴格優先」是刻意的保守設計:避免字庫別處的寬鬆規則,把一條明確設為嚴格的品牌名規則悄悄放寬。

因此「同一個 correct 拆成多條規則」是安全的(各條的 incorrect 不重複即可);但若你的資料存在「同一個錯誤變體對應到不同正確詞」,後出現的那條會被忽略且不會有任何提示,建議送出前先檢查變體是否重複。

術語庫如何參與同音校正

傳入 terminology 後,術語會成為同音比對的依據。逐字稿中讀音相同或相近、但用字不同的片段會被修正回術語的寫法:

術語逐字稿出現修正為
紡拓會訪拓會紡拓會
語者分離語這分離、與者分離語者分離
晶圓晶園晶圓

不需要事先列出可能的錯字 —— 比對依據是讀音,涵蓋範圍不受你想得到幾種錯法限制。

中英混合術語:CVD製程 這類術語,比對只作用在中文部分,英文原樣保留。

適用語言:同音比對僅適用於中文(繁體與簡體皆可,兩者讀音相同因此互通)。日文、韓文、英文的術語不會參與同音比對 —— 這些語言的錯字請改用 fuzzy_correction 明確列出。

比對範圍:讀音相同與相近的寫法都涵蓋,包含前鼻音與後鼻音(jin/jing)、捲舌與不捲舌等口音差異。例如術語為「晶圓廠」時,逐字稿的「金圓廠」會被修正。

常見詞保護:若逐字稿中該片段本身就是常見詞(例如「金元」「反案」),即使讀音與術語相同也不會被改動 —— 這是為了避免正常語句被誤改。要強制修正這類錯字,請用 fuzzy_correction 明確列出:明確列出的錯字不受常見詞保護限制。

限制:一次 config 的所有語言合計最多 4000 條規則,超過回 config_too_many_entries(details 帶 field: "fuzzy_correction"、count、max)。

這個數字是預設值:實際生效的上限可依環境調整,一律以錯誤回應 details 裡的 max 為準。 請不要把數字寫死在你的整合裡 —— 送出前若要自行檢查,讀 max 回填; 收到超限錯誤時,details 同時帶著 count(你送了幾個)與 max(實際上限)。

語言適用範圍:校正規則只會套用在語言代碼相符的句子上——登記在 zh-TW 底下的規則不會動到英文句子。系統判不出句子語言時,會退回套用全部規則(寧可多套也不整句不套)。術語庫參與的同音比對同樣依術語登記的語言。

翻譯字典格式(translation_dict)

以語言代碼分組,每個語言各自一份字典:

{
  "en-US": [
    { "source": "語者分離", "target": "Speaker Diarization" },
    { "source": "晶圓", "target": "wafer", "case_sensitive": true }
  ],
  "ja-JP": [
    { "source": "語者分離", "target": "話者分離" }
  ]
}
欄位類型必填說明
(頂層鍵)string是目標語言代碼
sourcestring是來源詞彙(使用 STT 語言),最多 200 字元
targetstring是該語言的指定譯法,最多 200 字元
case_sensitiveboolean否是否只在大小寫完全相符時才套用(預設 false = 不分大小寫)

限制:每個語言最多 3000 條目。超過時回 config_too_many_dict_entries,回應中的 details 會指出是哪一個語言。

注意:條目數直接反映在翻譯的處理量與費用上。單次翻譯實際帶入的只有來源詞真的出現在該段文字裡的條目,最多 100 條;超過時依來源詞長度優先保留。另外,條目愈多,能穩定遵守的比例愈低——這是本質限制,不會因為上限放寬而改變。

舊格式仍然支援:先前的條目陣列格式([{ "source": ..., "translations": { "語言代碼": ... } }])繼續接受,內容與行為完全不變,既有介接不需要任何改動。兩種格式送出同一份字典,結果完全相同。

續接時(resume_ok)回傳的 translation_dict 會與你最後一次送出的格式相同——送舊格式回舊格式、送新格式回新格式。

注意:不支援「清空整份字典」:送空物件會被視為沒有帶這個設定項目。清空單一語言則可以,送該語言的空陣列即可(例如 {"en-US": []})。

大小寫:case_sensitive 為選填、預設 false(不分大小寫)。設為 true 時,僅當原文的大小寫與 source 完全相符才套用該條翻譯。旗標是逐條的。

注意:翻譯字典是以提示詞引導模型翻譯,屬盡力而為而非字面替換——大小寫旗標同樣是提示,不保證絕對遵守。需要確定性替換請改用 fuzzy_correction。

大小寫旗標對照

fuzzy_correction 與 translation_dict 各有一個大小寫開關,欄位名互為反義、預設值代表的行為也相反:

區塊欄位預設值預設行為
fuzzy_correctioncase_insensitivefalse嚴格(區分大小寫)
translation_dictcase_sensitivefalse寬鬆(不分大小寫)

兩者都預設 false,但一個代表嚴格、另一個代表寬鬆。實作時請勿共用同一個變數,也不要直接把某一邊的值鏡射過去——設錯不會產生任何錯誤訊息,只會做出與預期相反的比對行為。

請求範例(推薦:只設定術語庫)

{
  "type": "voice-translation",
  "data": {
    "action": "config",
    "terminology": {
      "zh-TW": [
        { "term": "語者分離" },
        { "term": "CVD製程" },
        { "term": "wafer良率" }
      ]
    }
  }
}

請求範例(完整設定,含手動校正規則)

{
  "type": "voice-translation",
  "data": {
    "action": "config",
    "terminology": {
      "zh-TW": [
        { "term": "語者分離" },
        { "term": "即時轉錄" }
      ]
    },
    "fuzzy_correction": {
      "zh-TW": [
        { "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] }
      ]
    },
    "translation_dict": {
      "en-US": [{ "source": "語者分離", "target": "Speaker Diarization" }]
    }
  }
}

成功回應

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

錯誤回應

重要:客戶端必須同時監聽 type: "error" 訊息,不可只等待 config_updated。

設定被伺服器擋下時,回傳的是一則 type: "error" 而不是 config_updated。 只等 config_updated 的整合會一路等到自己逾時,看起來像「伺服器沒有回應」, 但實際上錯誤訊息已經送達、data.error_code 也指出了原因。

錯誤碼HTTP 狀態碼說明處理建議
config_empty400未提供任何設定。注意:空物件 {} 不算「有帶」 —— 送 {"terminology": {}, "fuzzy_correction": {}, "translation_dict": {}} 會命中此錯誤至少提供一個有內容的設定項目;若要清空某個語言的字庫,請送 {"語言代碼": []}(例如 {"zh-TW": []})
config_term_too_long400術語超過 100 字元縮短術語長度
config_too_many_entries400術語筆數超過 500,或模糊詞校正規則超過 4000(皆為所有語言合計)減少術語或校正規則
config_too_many_dict_entries400翻譯字典單一語言超過 3000 條目(details.language 指出是哪個語言)減少該語言的字典條目
config_invalid_entry400字庫條目的欄位不合法(details 帶 language、index、field、reason 供定位,視情況另帶 variant_index、max_length、count/max)依 details 指出的位置修正該條目

Voice Translation - audio(傳送音訊)

功能說明

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

使用場景

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

請求參數

參數類型必填說明
actionstring是固定為 audio
payloadstring是Base64 編碼的音訊資料
channel_idint條件多聲道模式(recognition_mode=multi_channel)下每一幀必帶:該幀音訊的來源聲道編號。未帶回 channel_id_required;未知或已移除的編號回 unknown_channel_id。非多聲道模式下此欄位一律忽略(向後相容)

音訊格式要求

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 音訊資料"
  }
}

請求範例(多聲道模式)

多聲道模式下每一幀都必須帶 channel_id:

{
  "type": "voice-translation",
  "data": {
    "action": "audio",
    "channel_id": 2,
    "payload": "Base64 編碼的 PCM 音訊資料"
  }
}

多聲道模式注意事項:建議每 100ms 送一幀;每路即使靜音也要持續送音訊。多聲道僅支援 pcm 格式(16kHz / 16bit / mono / little-endian)。

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
session_not_started400語音辨識尚未開始先呼叫 start action
audio_invalid_format400音訊資料格式錯誤確認 Base64 編碼正確
audio_decode_failed400音訊解碼失敗確認音訊格式正確。錄音不會結束;WebM 請重新送出全新容器(含檔頭)即可恢復,無法解碼的期間不計費
channel_id_required400多聲道模式音訊幀未帶 channel_id每一幀都帶上來源聲道編號
unknown_channel_id400未知或已移除的 channel_id使用 start 宣告或 add_channel 新增的有效編號

Voice Translation - pause(暫停翻譯)

功能說明

暫停語音辨識處理。暫停期間收到的音訊會被快取,恢復後繼續處理。互譯模式例外:暫停期間的音訊不會保留;暫停當下說到一半的句子會先等辨識服務處理完最後一段(通常約 1 秒,最多約 3 秒),以 is_final: true 送出後才回 status: "paused"。暫停期間照常計費,詳見計費說明。

使用場景

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

請求範例

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

成功回應

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

錯誤回應

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

多聲道模式:暫停期間各路錄音檔照常保存,但不出字(不產生逐字稿)。暫停中增減聲道、變更聲道語言或調整語速都會回 channel_action_while_paused,請先 resume 再操作。


Voice Translation - resume(恢復翻譯)

功能說明

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

使用場景

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

請求範例

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

成功回應

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

錯誤回應

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

多聲道模式:恢復後,暫停期間講的話會補轉錄(時間戳落在實際講話的時刻,不會被打到恢復之後)。補轉錄有上限:全場共 60 秒的尾段(per_channel 多路時平分到各路;shared 為整條最後 60 秒,所有聲道一起補、語者照標),更早的部分僅存於音檔、不進逐字稿。暫停瞬間講到一半的句子可能不會出現在逐字稿(與單路一致);若該句確實沒有留下,恢復時會另外收到 segment_discarded(reason: "resumed")指明是哪一句。恢復時各路會重新準備辨識,逐路送出 channel_status 事件(reason: "resumed")。


Voice Translation - stop(停止翻譯)

功能說明

停止語音辨識並結束會話。停止時會先等辨識服務把最後一句處理完(通常約 1 秒,最多約 3 秒),這一句才會進入逐字稿;等不到時,以畫面上最後的辨識結果作為該句內容。系統會自動上傳音檔和逐字稿,並生成摘要(若有設定;可用點數不足以支付摘要費用時不產生,改送 summary_error)。

使用場景

  • 會議結束
  • 完成錄音

請求範例

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

成功回應

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

任務完成事件

當音檔和逐字稿上傳完成後,會發送此事件:

{
  "type": "voice-translation",
  "data": {
    "action": "task_complete",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "message": "任務處理完成"
  }
}
欄位類型說明
task_idstringRecording UUID,可用於後續 API 查詢
noAudioboolean只在整場沒有收到任何音訊時出現,值一定是 true,見 task_complete

錯誤碼

錯誤碼HTTP 狀態碼說明處理建議
session_not_started400語音辨識尚未開始,或本次錄音已經結束(例如重複送出 stop)若尚未開始請先呼叫 start;若是重複送出可忽略

重複送出 stop 會收到此錯誤,而不是再一次的成功回應。task_complete 只會在 第一次成功停止後、音檔與逐字稿上傳完成時送出一次。


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 狀態碼說明處理建議
invalid_data422未提供 sid帶上 sid
record_translation_not_allowed400純錄音類型不支援翻譯改用 transcribe 類型
retranslate_session_not_active400工作階段未啟動或已結束確認工作階段狀態
retranslate_no_target_lang400未提供目標語言提供 translation_languages
retranslate_no_text400未提供要翻譯的文字提供 text 參數
retranslate_llm_not_ready503翻譯服務尚未就緒稍後重試
retranslate_llm_failed500翻譯服務失敗稍後重試

翻譯服務若回傳明確的失敗代碼(例如內容被判定無法翻譯的 llm_content_filtered),會直接以該代碼回傳,不會再包成 retranslate_llm_failed。


Voice Translation - switch_language(切換語言)

功能說明

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

  • 一般模式・單語言(translation_languages 為 1 個):置換翻譯目標語言,並自動批次重翻所有已翻譯句子
  • 一般模式・多語言(2 個以上,v1.6.7):改為「新增或移除單一語言」語意,必須帶 op 參數(add / remove);不帶 op 回 switch_language_op_required 錯誤。add 會自動補譯既有句子(回應序列同單語言置換);remove 回 translation_language_removed 事件、歷史譯文保留。詳見 WebSocket 參考
  • 互譯模式(conversation):切換 STT 來源語言(說話語言),翻譯目標自動切換為另一語言
  • 多聲道模式(multi_channel,v1.10.0):不支援,一律回 multichannel_switch_language_not_allowed(含 op: add / op: remove)。語言綁定在聲道上,請改用 set_channel_language

使用場景

  • 切換翻譯目標語言
  • 會議中途更換語言需求
  • 多語言場次中途新增/移除翻譯語言(v1.6.7)

請求參數

參數類型必填說明
actionstring是固定為 switch_language
translation_languagesstring[]條件翻譯語言代碼陣列(一般模式必填;只取第一個元素作為操作目標)
opstring條件v1.6.7 多語言操作:add(新增)、remove(移除)。多語言場次必填
transcription_languagesstring[]條件切換目標語言(互譯模式;不帶則自動 toggle 到另一語言)

請求範例(一般模式・單語言置換)

{
  "type": "voice-translation",
  "data": {
    "action": "switch_language",
    "translation_languages": ["ja-JP"]
  }
}

請求範例(多語言・新增/移除,v1.6.7)

{
  "type": "voice-translation",
  "data": {
    "action": "switch_language",
    "op": "add",
    "translation_languages": ["de-DE"]
  }
}
{
  "type": "voice-translation",
  "data": {
    "action": "switch_language",
    "op": "remove",
    "translation_languages": ["ko-KR"]
  }
}

請求範例(互譯模式)

指定切換目標:

{
  "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",
    "translation_languages": ["en-US", "ja-JP"],
    "total_segments": 15
  }
}
  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",
    "translation_languages": ["en-US", "ja-JP"],
    "success_count": 15,
    "failed_count": 0
  }
}

錯誤回應

錯誤碼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已是當前語言可忽略此警告
multichannel_switch_language_not_allowed400多聲道模式不支援 switch_language改用 set_channel_language 變更單路語言

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",
    "event": "name_set",
    "name": "產品規劃會議",
    "message": "錄音名稱已設定"
  }
}

相容性說明:為相容既有整合,set_name 成功回應的 action 維持 "status"(不變)。新客戶請改用 event: "name_set"(搭配 name 欄位)來辨識 set_name 成功。以 action: "status" 判斷 set_name 成功的舊方式已 deprecated(不建議),未來版本可能移除該相容行為。

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
set_name_empty400錄音名稱為空提供非空名稱
set_name_too_long400錄音名稱超過長度限制(>60 字元);回覆的 details 會帶 max_length縮短名稱長度(≤60 字元)

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

功能說明

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

多聲道模式(multi_channel)亦可使用:語者 ID 格式為 channel_{N}(如 channel_1),語者在 start / add_channel 時即已註冊,可在該路尚未發言前先改名。改名後 result 的 speaker_label 與逐字稿都會反映新標籤。

使用場景

  • 將系統自動分配的說話者 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_found422找不到指定的說話者確認 speaker_id 或顯示標籤存在
speaker_name_empty422new_label 為空提供有效的標籤
speaker_name_duplicate422顯示標籤已被使用使用其他標籤,或先修改衝突的說話者
session_not_started400語音辨識尚未開始先呼叫 start

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

功能說明

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

多聲道模式(multi_channel)不適用:語者身分由實體聲道決定(每句的 speaker_id 即其來源聲道),不支援改指派給其他聲道。

使用場景

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

請求參數

參數類型必填說明
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_found422找不到指定的句子確認 SID 存在
speaker_not_found422目標語者不存在使用已存在的語者 ID
speaker_name_empty422目標語者 ID 不能為空提供有效的語者 ID
session_not_started400語音辨識尚未開始先呼叫 start
invalid_parameter400不支援建立新語者使用已存在的語者 ID

Voice Translation - merge_speakers(合併語者)

功能說明

將一個語者的所有句子合併到另一個語者。合併後,該語者未來產生的辨識結果也會自動轉換為目標語者(僅限當前辨識工作:連線中斷後恢復會重新編號,屆時需重新合併)。

多聲道模式(multi_channel)不適用:語者身分由實體聲道決定,不支援合併不同聲道的語者。

使用場景

  • 語音辨識引擎有時會將同一人的聲音誤識為多個語者(如 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",
    "affected_sids": [3, 5, 7]
  }
}
欄位類型說明
source_speaker_idstring被合併的原始語者 ID
target_speaker_idstring合併目標的原始語者 ID
affected_sidsnumber[]受影響的句子 ID 列表:原屬來源語者的句子,加上顯示名稱因合併而改變的目標語者原有句子(例如來源語者的自訂名稱轉給目標語者時)

若需取得 target 語者顯示標籤,請查詢 speaker_aliases 或下次 init_metadata 事件。

錯誤回應

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

Voice Translation - tts_play(播放 TTS)

功能說明

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

使用場景

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

請求參數

參數類型必填說明
actionstring是固定為 tts_play
sidint是起始句子 ID
lengthint否播放句子數量(預設 1,最大 20)

注意: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

找不到句子、或該句沒有翻譯時不回 error:起始 sid 不存在、或該句沒有目標語言的翻譯時,不會回傳 error 訊息,而是送出 tts_error 事件(見「回應事件」),error 欄位分別為 sentence_not_found 與 translation_not_found。多句播放時單句失敗只跳過該句,其餘句子照常播放。


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 狀態碼說明處理建議
invalid_data422未提供 tts_mode,或值不是 sync、async。後者 details.field 為 tts_mode、details.valid_values 列出可用的值;模式不會改變,也不會收到 tts_mode_changed帶上 sync 或 async

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_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_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": "開始說話"
  }
}

已在說話中再次呼叫時,上一句的定稿照常送出,之後同樣回這則 status。

錯誤回應

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

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

功能說明

在互譯手動模式下,通知系統用戶結束說話。系統會先等辨識服務把最後一段處理完(通常約 1 秒,最多約 3 秒),再將期間累積的辨識結果合併為一個完整句子,然後進行翻譯和 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是目標模式: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_action400非互譯模式僅在 conversation 類型下使用
conversation_invalid_mode400無效的對話模式使用 auto 或 manual

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未提供 language帶上 language
invalid_transcription_language400語言代碼無效使用有效的 BCP 47 語言代碼
session_not_started400錄音尚未開始先呼叫 start
conversation_same_language400與當前語言相同可忽略此警告
conversation_language_same_as_peer400新語言與另一位用戶相同兩位用戶語言不可相同
conversation_speaking400正在說話中,無法變更語言先結束說話再變更
conversation_language_change_failed500語言變更失敗(STT 重建失敗)稍後重試

Voice Translation - set_speaking_speed(錄音中調整語速)

功能說明

錄音進行中動態調整語速(影響斷句的靜音判斷門檻)。系統會重建 STT 連線以套用新設定,過程中辨識會短暫中斷(與錄音中切換語者語言相同)。非多人(multi_speaker)辨識模式皆支援(含廣播、多語 LID);多人模式不套用 speaking_speed。

多聲道模式(multi_channel,v1.10.0):支援。新的斷句門檻套用到全部聲道、逐路生效(每路各送 channel_status 事件、reason: "speaking_speed",套用期間該路短暫不出字)。全場共用 5 秒操作間隔限制,過快會回 channel_rebuild_too_frequent;暫停中回 channel_action_while_paused。

請求參數

參數類型必填說明
actionstring是固定為 set_speaking_speed
speaking_speedstring是very_slow / slow / normal / fast / very_fast(各等級的門檻見 speaking_speed 等級)

請求範例

{
  "type": "voice-translation",
  "data": { "action": "set_speaking_speed", "speaking_speed": "slow" }
}

成功回應

{
  "type": "voice-translation",
  "data": { "action": "speaking_speed_changed", "speaking_speed": "slow" }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
invalid_data422speaking_speed 值無效使用五個合法值之一
session_not_started400錄音尚未開始先呼叫 start
invalid_action400多人模式不支援多人模式勿呼叫
set_speaking_speed_failed400重建 STT 失敗稍後重試
channel_rebuild_too_frequent400多聲道:語速調整過於頻繁(5 秒內僅接受一次,details 帶 cooldown_seconds)稍後再試
channel_action_while_paused400多聲道:暫停中無法調整語速先 resume 再調整

若操作當下正有一句話說到一半,那一句無法保留,會另外收到 segment_discarded(reason: "speaking_speed")。回 set_speaking_speed_failed 時也可能已經收到。


Voice Translation - add_channel(多聲道新增聲道)

多聲道模式專用(v1.10.0)

功能說明

多聲道模式(recognition_mode: "multi_channel")錄音進行中,動態新增一路聲道。新的一路約 4 秒後開始出字;這段期間送入的音訊不會丟失,只是延遲出字。新增成功後,計費路數自下一分鐘起依實際聲道路數計算。

使用場景

  • 會議中途有新講者入座,接上新的麥克風
  • 依現場人數逐步開通聲道

請求參數

參數類型必填說明
actionstring是固定為 add_channel
channelsarray是恰好 1 個聲道設定元素(欄位與 start 的 channels[] 相同:channel_id、speaker_name、transcription_languages;shared 模式不帶 transcription_languages)

編號不可重用:channel_id 一經使用(含已被 remove_channel 移除的)即不可再次使用,重用會回 channel_id_in_use。語者身分在逐字稿是寫入當下就決定的,重用編號會使同一個語者 ID 對應到兩個不同的人。

shared 模式:新增的聲道共用全場的辨識,不增加計費路數;狀態直接套用第一路當下的狀態(見 shared 模式)。

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "add_channel",
    "channels": [
      { "channel_id": 4, "speaker_name": "林協理", "transcription_languages": ["ja-JP"] }
    ]
  }
}

成功回應

成功後回傳 channel_status 事件(reason: "added")。新路狀態為 preparing,該路首次出字後再收到一次 status: "ready" 的事件:

{
  "type": "voice-translation",
  "data": {
    "action": "channel_status",
    "channel": {
      "channel_id": 4,
      "speaker_name": "林協理",
      "transcription_languages": ["ja-JP"],
      "status": "preparing"
    },
    "active_channels": 4,
    "stt_stream_count": 4,
    "reason": "added"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
not_multi_channel_session400本場錄音不是多聲道模式僅 recognition_mode=multi_channel 可用
channels_required400channels 未帶或不是恰好 1 個元素帶恰好 1 個聲道設定
invalid_channel_id400channel_id 超出值域(1–8)使用 1–8 且未用過的編號
channel_id_in_use400編號使用中或已被移除過,不可重複使用換一個未用過的編號
too_many_channels400聲道數已達上限(details 帶 max 與 current)先移除其他聲道
channel_language_required400未指定恰好一種轉錄語言(per_channel)transcription_languages 帶恰好 1 個語言
channel_language_not_allowed400shared 模式帶了 transcription_languages移除該欄位
invalid_transcription_language400無效的語言代碼確認語言代碼格式正確(如 zh-TW)
plan_feature_not_allowed403超過方案的同時辨識路數上限(details.field="max_stt_streams")移除其他聲道或升級方案
too_many_languages400新路語言會使同時識別語言數超過上限(方案上限,details 帶 max 與 received)改用既有語言或升級方案
channel_action_while_paused400暫停中無法增減聲道先 resume 再操作
speaker_name_duplicate422speaker_name 與其他聲道目前的名稱重複改用其他名稱
invalid_parameter400speaker_name 超長(>100 字元)或含控制字元依 details.field 修正參數
session_not_started400錄音尚未開始先呼叫 start
stt_start_failed500該路語音辨識啟動失敗(本次新增未生效)稍後重試

Voice Translation - remove_channel(多聲道停用聲道)

多聲道模式專用(v1.10.0)

功能說明

多聲道模式錄音進行中,停用一路聲道。停用後該路不再收新音訊、不再列入辨識路數,計費路數自下一分鐘立即減少;該路已產生的逐字稿與音檔全部保留。停用時有約 3 秒的收尾窗,讓該路最後一句話有機會回到逐字稿。

注意:

  • 最後一路不可移除(回 channel_remove_not_allowed);要結束錄音請用 stop
  • shared 模式下 channels[] 的第一路承載全場的辨識,不可移除(回 channel_remove_not_allowed)
  • 移除後的 channel_id 不可重用(見 add_channel);要換語言請用 set_channel_language,不要用移除再新增
  • 移除後對該編號送音訊會回 unknown_channel_id

使用場景

  • 講者中途離席,釋放該路聲道以降低計費
  • 收回暫時開通的來賓麥克風

請求參數

參數類型必填說明
actionstring是固定為 remove_channel
channel_idint是要停用的聲道編號

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "remove_channel",
    "channel_id": 4
  }
}

成功回應

成功後回傳 channel_status 事件(reason: "removed"、status: "removed"):

{
  "type": "voice-translation",
  "data": {
    "action": "channel_status",
    "channel": {
      "channel_id": 4,
      "speaker_name": "林協理",
      "transcription_languages": ["ja-JP"],
      "status": "removed"
    },
    "active_channels": 3,
    "stt_stream_count": 3,
    "reason": "removed"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
not_multi_channel_session400本場錄音不是多聲道模式僅 recognition_mode=multi_channel 可用
channel_id_required400未帶 channel_id指定要停用的聲道編號
invalid_channel_id400channel_id 超出值域(1–8)使用有效的聲道編號
unknown_channel_id400未知的 channel_id(可能已被移除)確認編號存在且尚未移除
channel_remove_not_allowed400最後一路聲道不可移除;或 shared 模式的第一路要結束錄音請用 stop
channel_action_while_paused400暫停中無法增減聲道先 resume 再操作
session_not_started400錄音尚未開始先呼叫 start

Voice Translation - set_channel_language(多聲道變更聲道語言)

多聲道模式專用(v1.10.0)

功能說明

多聲道模式錄音進行中,變更單一聲道的轉錄語言。channel_id 與語者身分(speaker_id)維持不變,逐字稿保持連續;系統會將該路切換為新語言(約 4 秒生效,期間該路短暫不出字,會送 channel_status 事件、reason: "language_change")。若換入的語言是本場尚未使用的新語言,受平台上限(同時識別語言 10 種)與方案的同時識別語言數上限管制。

請勿用 remove_channel + add_channel 代替:編號不可重用,換編號會讓同一個人在逐字稿裡變成兩個語者,事後救不回來。

使用場景

  • 同一位講者中途改用另一種語言發言
  • 修正 start 時設錯的聲道語言

請求參數

參數類型必填說明
actionstring是固定為 set_channel_language
channel_idint是目標聲道編號
transcription_languagesstring[]條件新的轉錄語言(恰好 1 個,多於 1 個回 invalid_parameter)。與 language 擇一提供
languagestring條件新的轉錄語言(單值形態)。與 transcription_languages 擇一提供;兩欄同時提供且不一致回 invalid_parameter

請求範例

{
  "type": "voice-translation",
  "data": {
    "action": "set_channel_language",
    "channel_id": 2,
    "transcription_languages": ["ja-JP"]
  }
}

成功回應

成功後回傳 channel_status 事件(reason: "language_change"、status: "preparing"),該路切換完成、首次出字後再收到 status: "ready":

{
  "type": "voice-translation",
  "data": {
    "action": "channel_status",
    "channel": {
      "channel_id": 2,
      "speaker_name": "Alex",
      "transcription_languages": ["ja-JP"],
      "status": "preparing"
    },
    "active_channels": 3,
    "stt_stream_count": 3,
    "reason": "language_change"
  }
}

錯誤回應

錯誤碼HTTP 狀態碼說明處理建議
not_multi_channel_session400本場錄音不是多聲道模式僅 recognition_mode=multi_channel 可用
channel_id_required400未帶 channel_id指定目標聲道編號
invalid_channel_id400channel_id 超出值域(1–8)使用有效的聲道編號
unknown_channel_id400未知的 channel_id(可能已被移除)確認編號存在且尚未移除
channel_language_required400未提供新的轉錄語言帶 transcription_languages[0] 或 language
invalid_parameter400與當前語言相同、兩欄同帶且不一致、或多於一個語言依 details 修正參數
invalid_transcription_language400無效的語言代碼確認語言代碼格式正確(如 zh-TW)
channel_rebuild_too_frequent400同一路 5 秒內僅接受一次切換(details 帶 cooldown_seconds)稍後再試
too_many_languages400新語言會使同時識別語言數超過平台上限(10)或方案上限改用既有語言或升級方案
channel_action_while_paused400暫停中無法變更聲道語言先 resume 再操作
session_not_started400錄音尚未開始先呼叫 start
channel_language_not_allowed400shared 模式不支援變更聲道語言全場語言於 start 決定,錄音中不能變更
stt_start_failed500該路語音辨識以新語言重建失敗稍後重試(該路會等待重連恢復)

若操作當下正有一句話說到一半,那一句無法保留,會另外收到 segment_discarded(reason: "language_change")。事件帶 channel_id 指明是哪一路。


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),會回傳狀態訊息「廣播已經在進行中」,不視為錯誤。

若操作當下正有一句話說到一半,那一句無法保留,會另外收到 segment_discarded(reason: "broadcast_go_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 回應事件。

注意:這裡不是完整清單:translation_language_removed、summary_updated、summary_done、summary_error、upload_error、speakers_auto_merged 這 6 個事件未列於本頁。完整的 36 個事件見 事件參考。

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",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "transcribe",
    "recognition_mode": "single",
    "resume_token": "L0VBAwIy...(43 字元)",
    "resume_grace_seconds": 45,
    "server_time": 1749550000000,
    "message": "語音辨識已開始"
  }
}

廣播模式(broadcast):

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_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,
    "resume_token": "L0VBAwIy...(43 字元)",
    "resume_grace_seconds": 45,
    "server_time": 1749550000000,
    "message": "語音辨識已開始"
  }
}
欄位類型說明
session_idstring會話 ID
task_idstring任務 ID(可用於後續 API 查詢)
recording_typestring錄音類型:transcribe、conversation、record、broadcast
recognition_modestring辨識模式:single、multi_speaker
resume_tokenstring斷線續接權杖(43 字元)。斷線後於 resume_grace_seconds 寬限期內,重連時帶它即可接回原會話;於 session_started 預先發送,請保存到本次會話結束
resume_grace_secondsint重連寬限秒數(預設 45)。為 wall-clock 真實時間,斷線後持續倒數
server_timeint64伺服器當下 unix 毫秒。前端可用「(server_time, 收到當下的 client 時間)」估算時鐘偏差作為參考;但 grace 倒數仍以 client wall-clock 為準
messagestring狀態描述訊息
phasestring廣播階段:standby 或 live(僅廣播模式)
viewer_countint目前在線觀眾數(僅廣播模式)
queue_countint排隊等待中的觀眾數(僅廣播模式)
peak_viewersint本次廣播峰值觀眾數(僅廣播模式)
total_viewersint累計曾連線的觀眾總數(僅廣播模式)
channel_modestring多聲道子模式:per_channel 或 shared(僅多聲道模式帶)。這也是前端確認伺服器確實進入多聲道模式的依據
channelsarray多聲道聲道清單(僅多聲道模式帶)。每路含 channel_id、speaker_name、transcription_languages、status(preparing / ready / removed / error);shared 模式不帶 transcription_languages

resume_ok - 斷線續接成功

斷線後於 resume_grace_seconds 寬限期內,以 resume_token 重連成功時,伺服器回傳的事件。收到後請像 start 之後一樣重新開始送音訊流(WebM/Opus 須送全新容器、PCM 直接續送),並依 server_last_sid / server_last_offset_ms 對齊本地內容。若 is_paused 為 true,代表斷線前已暫停,請續接後維持暫停、不送音訊。完整續接握手流程請參考 連線與認證,欄位細節請參考 WebSocket 事件參考。

{
  "type": "voice-translation",
  "data": {
    "action": "resume_ok",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "transcribe",
    "recognition_mode": "single",
    "server_last_sid": 42,
    "server_last_offset_ms": 125000,
    "server_recording_ms": 127500,
    "is_paused": false,
    "settings": { ... },
    "message": "已續接原會話"
  }
}
欄位類型說明
session_idstring會話 ID(WS 連線層級,連線結束即失效)
task_idstring任務 ID(與原會話相同,續接後維持同一識別碼)
recording_typestring錄音類型:transcribe、conversation、record、broadcast
recognition_modestring辨識模式:single、multi_speaker
server_last_sidint伺服器目前最後一個句子編號(sid)。前端應忽略 sid ≤ 此值的重複訊息
server_last_offset_msint64斷點對應的逐字稿時間軸位置(毫秒),基於已處理的音訊長度(非 wall-clock;斷線期間音訊時間軸凍結)。前端用它把重連後的新內容接在正確的時間軸位置
server_recording_msint64續接後逐字稿時間軸實際接續的錄音頭時間(毫秒,含靜音)。前端用它把錄音秒數標頭對齊到逐字稿所用的同一條時間軸。與 server_last_offset_ms 的差值即為斷點前最後一句定稿之後、尚未產出逐字稿的尾端音訊(靜音或未斷句的語音)。省略時為 0
is_pausedbool續接後伺服器認定的暫停狀態:true=斷線前已暫停,前端應維持暫停(重開音訊流後立即暫停、不送音訊);false=正常錄音中。供斷網重連與整頁 refresh 後對齊暫停 UI。省略時視為 false(向下相容舊版伺服器)
settingsobjectsession 目前持有的本次錄音設定(state reconcile 用,v1.6.4 新增);詳見連線與認證
messagestring狀態描述訊息(固定為「已續接原會話」)

注意:兩種時間不可混用:逐字稿時間軸(server_last_offset_ms)基於音檔、斷線時凍結;grace 重連窗口(resume_grace_seconds)是 wall-clock 真實時間、斷線時持續倒數。判斷「還能不能重連」必須用 wall-clock,不能用音檔時間位置。

多聲道模式:resume_ok 的 settings 內含 channel_mode 與 channels[](每路含 channel_id、speaker_name、transcription_languages、status;shared 模式不帶 transcription_languages),供前端在斷線續接後確認伺服器仍在多聲道模式、各路的聲道↔語言綁定沒變。續接後各路先以快照中的 preparing 呈現,開始出字時逐路送出 channel_status(ready,reason: "reconnect")。shared 模式下,快照與事件中其他聲道的狀態跟著第一路(見 shared 模式)。


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。多聲道模式下由聲道決定,格式為 channel_{N}(如 channel_1)
speaker_labelstring說話者顯示標籤(可選)。多聲道模式下為 start / add_channel 帶入的 speaker_name(經 rename_speaker 改名後為新標籤;無名稱時等於 speaker_id)
detected_languagestring偵測到的語言。互譯模式下由系統自動判定
start_timestring句子開始時間(mm:ss);廣播 standby 階段不送此欄位,進 live 後從 00:00 起算
channel_idint多聲道模式專用:該句的來源聲道編號。非多聲道模式不帶此欄位

多聲道模式:各路獨立斷句,不同聲道的句子會交錯送達,sid 不保證依聲道連號;origin.language 為該路綁定的語言。

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 時)

多聲道模式:translations 不帶 channel_id,請以 sid 對回 origin 取得來源聲道。


status - 通用狀態回應

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

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "status": "paused",
    "message": "語音辨識已暫停"
  }
}
欄位類型說明
statusstring機器可讀的錄音生命週期狀態:live(恢復)/ paused(暫停)/ ended(停止)。僅 pause / resume / stop 帶此欄位;set_name 等不帶。ended 一定在 task_complete 之前送出。浮動字幕消費端應據此 paused → 凍結、ended → 關閉視窗、live → 恢復。
messagestring狀態顯示文字(不保證格式,請勿解析;以 status 欄位為準)

task_complete - 任務處理完成

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

  • 一定在 status: "ended" 之後送出。
  • 逐字稿含摘要,所以本事件要等標題與摘要生成完成。通常數秒到數十秒;摘要較長或服務較慢時會更久,最長約 8 分鐘。
  • 同時錄音名額在送出本事件的當下釋放:收到後即可開始下一場錄音。
  • 判斷錄音是否完成,建議同時支援 Webhook 或 REST 查詢,不要只依賴本事件。
  • 錄音因為長時間沒有語音而自動結束時,同樣會收到本事件。
{
  "type": "voice-translation",
  "data": {
    "action": "task_complete",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "message": "任務處理完成"
  }
}

整場沒有收到音訊的錄音:不論是送出 stop、點數不足或自動結束,只要整場沒有收到任何音訊,仍會依序收到 status: "ended" 與本事件,並帶 noAudio: true。這筆錄音沒有逐字稿與音檔,狀態為 failed,同時送出 recording.failed Webhook(failure_source 為 no_audio);請不要再去讀取逐字稿,改提示使用者沒有收到聲音。已經過的分鐘照常計費。

{
  "type": "voice-translation",
  "data": {
    "action": "task_complete",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "noAudio": true,
    "message": "任務處理完成"
  }
}

廣播在預備階段就結束(還沒開播)時,只會收到 status: "ended",不會收到本事件:預備階段不建立錄音。

欄位類型說明
task_idstringRecording UUID,可用於後續 API 查詢
noAudioboolean只在整場沒有收到任何音訊時出現,值一定是 true;有錄到音訊時不帶這個欄位
messagestring狀態描述

config_updated - 設定更新完成

在 config action 成功後觸發。

注意:僅在設定被接受時觸發。設定被拒絕時回傳的是 type: "error",客戶端需一併監聽,否則會誤判為無回應。

{
  "type": "voice-translation",
  "data": {
    "action": "config_updated",
    "updated": ["terminology", "fuzzy_correction", "translation_dict"],
    "message": "設定已更新"
  }
}
欄位類型說明
updatedstring[]已更新的設定類型:terminology、fuzzy_correction、translation_dict
messagestring狀態訊息
terminology_effectivestring(可選)錄製中更新術語庫時出現,值為 "next_turn":新術語從下一句生效。初始 config 不會出現
unknown_languagesstring[](可選)無法辨識的字庫語言代碼(例如 zh、chinese)。這些字庫不會生效,但 config 仍算成功
inactive_languagesstring[](可選)代碼合法、但本場錄音沒有使用的語言。錄音尚未開始時不會出現(此時語言清單還沒定案)
inactive_dict_languagesstring[](可選)同上,但針對翻譯字典的目標語言
homophone_conflictsobject[](可選)字庫中讀音相同的術語組合,每筆含 languages 與 terms。錄音尚未開始時不會出現(此時語言清單還沒定案)

homophone_conflicts 怎麼看:兩個讀音相同的術語同時登記時(例如「公事包」與「公式包」), 逐字稿出現讀音相同的第三種寫法,系統只能改成其中一個,改成哪一個不保證。 兩個術語本身都仍然生效,不確定的只有「沒登記過的同音錯字歸誰」。

這是警告不是錯誤 —— 字庫照樣收下、config 照樣成功。 若這組術語對你很重要,建議用 fuzzy_correction 明確列出該錯字對應到哪一個術語。

languages 是共用同一份術語索引的所有語言。中文各地區代碼(zh-TW/zh-CN/zh-HK 等) 在字庫比對上視為同一群,所以它們共用一筆衝突,而不是各報一次。

"homophone_conflicts": [
  { "languages": ["zh-TW"], "terms": ["公事包", "公式包"] }
]

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錯誤訊息
transcriptstring對應原始逐字稿,便於前端定位失敗位置。此欄位一律存在,找不到句子時為空字串 ""

TTS 錯誤碼

錯誤碼說明
sentence_not_found找不到指定的句子(tts_play 帶的 sid 不存在)
translation_not_found找不到該語言的翻譯
tts_invalid_language不支援的 TTS 語言
tts_invalid_voice語音名稱無效
tts_connection_failed語音合成服務連線失敗
tts_timeout語音合成逾時
tts_synthesis_failed語音合成失敗

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新的階段:standby 或 live
messagestring狀態描述訊息

broadcast_recording_ready - 廣播錄音就緒

廣播正式開播(live)後觸發,帶回本場廣播定案後的 task_id。session_started 帶的是連線階段的初始值,不是本場廣播的最終 ID;不論是經預備階段(standby)轉正式開播、或 start 時直接指定正式開播(broadcast_phase: "live",預設),都會在開播後收到本事件。後續操作(如換浮動字幕 Feed Token)須以本事件的 task_id 為準,使用初始值會查無資料。

  • start 時直接指定正式開播時,本事件一定在 session_started 之後送達。
  • 主講者斷線後,在寬限期內用同一個 broadcast_token 重新 start(接管),新連線收到的本事件會帶新的 task_id。同一場廣播因此會有接管前、接管後兩筆錄音,各自完成、各自送出完成通知。
{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_recording_ready",
    "task_id": "3f9a1c2e-..."
  }
}
欄位類型說明
task_idstring本場廣播定案後的錄音 ID(正式開播後有效)

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",
    "affected_sids": [3, 5, 7]
  }
}
欄位類型說明
source_speaker_idstring被合併的原始語者 ID
target_speaker_idstring合併目標的原始語者 ID
affected_sidsnumber[]受影響的句子 ID 列表:原屬來源語者的句子,加上顯示名稱因合併而改變的目標語者原有句子(例如來源語者的自訂名稱轉給目標語者時)

若需取得 target 語者顯示標籤,請查詢 speaker_aliases 或下次 init_metadata 事件。


language_switch_start - 語言切換開始

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

{
  "type": "voice-translation",
  "data": {
    "action": "language_switch_start",
    "translation_language": "ja-JP",
    "translation_languages": ["en-US", "ja-JP"],
    "total_segments": 15
  }
}
欄位類型說明
translation_languagestring本次操作的單一語言(置換的新目標,或 op:add 新增的語言)
translation_languagesstring[]當前完整翻譯語言集的權威快照;消費端應直接以此覆寫本地語言集,勿從單一語言推測附加/置換
total_segmentsint需要重新翻譯的句子數

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",
    "translation_languages": ["en-US", "ja-JP"],
    "success_count": 15,
    "failed_count": 0
  }
}
欄位類型說明
translation_languagestring本次操作的單一語言
translation_languagesstring[]當前完整翻譯語言集的權威快照(同 language_switch_start,消費端覆寫)
success_countint成功翻譯的句子數
failed_countint翻譯失敗的句子數

tts_mode_changed - TTS 模式變更

TTS 播放模式變更事件。

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

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

speaking_speed_changed - 語速變更

錄音中語速變更事件。當 set_speaking_speed 成功套用新語速(重建 STT 完成)後觸發,帶回已套用的語速等級。

{
  "type": "voice-translation",
  "data": {
    "action": "speaking_speed_changed",
    "speaking_speed": "slow"
  }
}
欄位類型說明
speaking_speedstring已套用的語速:very_slow / slow / normal / fast / very_fast

channel_status - 聲道狀態變更

多聲道模式專用(v1.10.0)

多聲道模式(recognition_mode: "multi_channel")下,聲道狀態變更時觸發:add_channel / remove_channel 的成功回應、set_channel_language 與 set_speaking_speed 的設定切換、暫停恢復與斷線自動重連、以及聲道異常。

{
  "type": "voice-translation",
  "data": {
    "action": "channel_status",
    "channel": {
      "channel_id": 3,
      "speaker_name": "李小華",
      "transcription_languages": ["zh-TW"],
      "status": "preparing"
    },
    "active_channels": 3,
    "stt_stream_count": 3,
    "reason": "added"
  }
}
欄位類型說明
channelobject狀態變更的聲道,含 channel_id、speaker_name、transcription_languages、status
active_channelsint目前有效聲道數(語者人數)
stt_stream_countint目前採計的辨識路數(每一分鐘開始時依此計費);shared 模式固定為 1
reasonstring可選。本次狀態變更的原因,見下表

status 狀態機

每次該路開始或重新準備辨識,都會先進 preparing,首次出字後轉 ready:

status說明
preparing準備中(建立或套用新設定中)。該路講的話會延遲數秒才出字,不會丟失;唯獨套用當下說到一半的那一句無法保留(見 segment_discarded)
ready該路已收到第一個辨識結果
removed已被 remove_channel 停用
error該路語音辨識異常且無法自動恢復

shared 模式:其他聲道的 preparing/ready/error 跟著第一路,第一路狀態改變時每一路各收到一則事件;removed 依各路自己。詳見 shared 模式。

reason 值域

reason說明
addedadd_channel 新增
language_changeset_channel_language 切換語言
reconnect該路異常中斷後自動重連
resumed暫停後恢復
removedremove_channel 停用
speaking_speedset_speaking_speed 逐路套用新設定
stt_error語音辨識異常

segment_discarded - 句子作廢

告知某個 sid 已作廢,不會再有任何後續事件 —— 不會有該句 is_final: true 的原文,也不會有該句的翻譯。

有些操作會讓辨識中斷,若當下正好有一句話說到一半,那一句無法保留。前端可能已經收到過該句 is_final: false 的中間結果,收到本事件後請把該 sid 從「翻譯中」狀態移除。

互譯自動模式不會收到本事件 —— 該模式下說到一半的句子會直接以 is_final: true 收尾送出,內容保留在逐字稿中。

{
  "type": "voice-translation",
  "data": {
    "action": "segment_discarded",
    "sid": 7,
    "reason": "speaking_speed",
    "channel_id": 1
  }
}
欄位類型說明
sidint被作廢的句子編號
reasonstringspeaking_speed(set_speaking_speed)/language_change(set_channel_language)/reconnect(辨識連線異常後自動重連)/resumed(斷線續接或暫停後恢復)/broadcast_go_live(由預備進入直播)
channel_idint可選。來源聲道編號;僅多聲道模式帶

前四個 reason 與 channel_status 是同一組值,可據以把兩個事件對應到同一次操作。

set_speaking_speed 失敗(set_speaking_speed_failed)時仍可能已經收到本事件 —— 辨識在重建之前就已中斷,該句無論重建成敗都保不住。


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": "reconnected",
    "message": "STT 已重連"
  }
}
欄位類型說明
eventstring事件類型:session_started(辨識會話建立)/session_stopped(辨識會話結束)/canceled(辨識被中止,原因見 message)/reconnecting(連線異常,自動重連中)/reconnected(已重新連線)
messagestring事件描述訊息。內容不保證固定,請一律以 event 判斷狀態

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警告顯示警告,不阻斷操作

warning 等級的預警不代表錄音結束,例如 stt_silence_warning(即將因為沒有語音而自動結束)、broadcast_standby_warning(預備階段即將達到時間上限)。錄音照常進行,真正結束時會另外收到對應的 fatal 錯誤與 status: "ended"。

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


版本:V1.24.1 最後更新:2026-10-07

Copyright © 2026