Speaker Management
目錄
概述
VAS 的 Speaker Diarization(說話者分離)功能可自動辨識多人對話中的不同說話者,並為每句話標記說話者身份。系統支援 31 種語言的語者辨識。
核心功能
| 功能 | 說明 | API 類型 |
|---|---|---|
| 語者辨識 | 自動識別並區分不同說話者 | WebSocket |
| 重命名說話者 | 將 Guest-1 改為真實姓名 | WebSocket / REST |
| 重新指派 | 修正單句的說話者身份 | WebSocket / REST |
| 合併說話者 | 將誤識為多人的同一說話者合併 | WebSocket / REST |
適用場景
- 會議記錄:自動區分與會者發言
- 訪談轉錄:標記主持人與受訪者
- 對話記錄:識別雙方或多方對話
認證方式
所有說話者管理的 REST API 需透過 API Key 認證。詳見 認證說明。
啟用說話者辨識
要使用說話者辨識功能,需在 WebSocket start action 中設定以下參數:
{
"type": "voice-translation",
"data": {
"action": "start",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"type": "conversation",
"recognition_mode": "multi_speaker",
"audio_format": "pcm"
}
}
關鍵參數
| 參數 | 值 | 說明 |
|---|---|---|
type | conversation | 使用對話記錄類型 |
recognition_mode | multi_speaker | 啟用多人語者辨識 |
注意:
type也可以設為transcribe或broadcast,只要recognition_mode設為multi_speaker即可啟用語者辨識。限制:
multi_speaker模式下transcription_languages必須恰好 1 個。若提供多個語言會收到diarization_multilang_conflict錯誤並拒絕開始,必須改為單一語言或關閉語者分離。
成功回應
啟動成功後會收到 session_started 事件,確認辨識模式為 multi_speaker:
{
"type": "voice-translation",
"data": {
"action": "session_started",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"recording_type": "conversation",
"recognition_mode": "multi_speaker",
"message": "語音辨識已開始"
}
}
接收說話者資訊
啟用多人語者辨識後,每個辨識結果(result 事件)都會包含說話者資訊。
辨識結果格式
{
"type": "voice-translation",
"data": {
"action": "result",
"origin": {
"sid": 1,
"language": "zh-TW",
"text": "今天的會議主要討論專案進度",
"is_final": true,
"speaker_id": "Guest-1",
"detected_language": "zh-TW",
"start_time": "00:05"
}
}
}
說話者相關欄位
| 欄位 | 類型 | 說明 |
|---|---|---|
speaker_id | string | 說話者 ID(系統自動分配,如 Guest-1) |
sid | int | 句子編號,每句唯一 |
is_final | boolean | 是否為最終結果 |
說話者 ID 命名規則
- 系統自動分配格式為
Guest-{N}(N 從 1 開始遞增) - 同一說話者在整個 Session 中使用相同的 ID
- 重命名後,後續辨識結果會使用新名稱
重命名說話者
將系統自動分配的說話者 ID(如 Guest-1)改為有意義的名稱(如 王經理)。重命名是全域操作,所有使用該說話者 ID 的句子都會同步更新。
方式一:WebSocket(即時模式)
適用於錄音進行中的即時重命名。
{
"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]
}
}
affected_sids 列出所有受影響的句子編號,前端可根據此資訊更新 UI。
方式二:REST API(離線模式)
適用於錄音結束後的離線編輯。
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/speakers/rename" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"speaker_id": "Guest-1",
"new_label": "王經理"
}'
成功回應(HTTP 200):
{
"data": {
"speaker_id": "Guest-1",
"new_label": "王經理",
"affected_sids": [1, 3, 5, 8, 12]
}
}
重命名限制
speaker_id必須是當前存在於該錄音的原始語者 ID 或當前顯示標籤;解析後仍找不到會回speaker_not_foundnew_label不能為空、最大 100 字元、不得含控制字元(\x00-\x1F、\x7F)或換行- 新標籤不能與現有其他語者的標籤重複(會回傳
speaker_name_duplicate錯誤) - REST API 僅適用於
multi_speaker模式的錄音
重新指派說話者
修改單一句子的說話者身份,將句子指派給另一位已存在的說話者。適用於修正語者辨識錯誤。
方式一:WebSocket(即時模式)
{
"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": "李小華"
}
}
方式二:REST API(離線模式)
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/speakers/reassign" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sid": 5,
"target_speaker_id": "Guest-2"
}'
重新指派限制
target_speaker_id必須是已存在語者的原始 ID(不支援建立新語者,也不接受顯示標籤)- 如果該語者已被重命名,
new_speaker_label會反映套用speaker_aliases後的顯示標籤
合併說話者
將一個說話者的所有句子合併到另一個說話者。適用於系統將同一人的聲音誤識為多個說話者的情況。
使用場景
語音辨識引擎有時會將同一人在不同時段的聲音識別為不同說話者(如 Guest-1 和 Guest-3 其實是同一人)。合併後:
- 所有
Guest-3的句子歸屬到Guest-1 - WebSocket 模式下:未來辨識出的
Guest-3結果也會自動轉換為Guest-1(持續攔截) - REST 模式下:歷史錄音已無新句子,僅一次性合併已存在的句子
方式一:WebSocket(即時模式)
{
"type": "voice-translation",
"data": {
"action": "merge_speakers",
"source_speaker_id": "Guest-3",
"target_speaker_id": "Guest-1"
}
}
成功回應:
{
"type": "voice-translation",
"data": {
"action": "speakers_merged",
"source_speaker_id": "Guest-3",
"target_speaker_id": "Guest-1",
"affected_sids": [3, 5, 7]
}
}
方式二:REST API(離線模式)
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/speakers/merge" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source_speaker_id": "Guest-3",
"target_speaker_id": "Guest-1"
}'
成功回應(HTTP 200):
{
"data": {
"source_speaker_id": "Guest-3",
"target_speaker_id": "Guest-1",
"target_speaker_label": "王經理",
"affected_sids": [3, 5, 7]
}
}
合併 vs. 重新指派 比較
| 功能 | 作用範圍 | 影響未來辨識結果(WS) |
|---|---|---|
reassign_speaker | 單一句子(1 個 SID) | 否 |
merge_speakers | 該說話者的所有句子 | 是(未來出現的 source 自動轉為 target) |
合併限制
source_speaker_id和target_speaker_id不能相同(會回傳merge_speakers_same_id錯誤)- 兩個說話者 ID 都必須存在於該錄音中
- REST 模式僅適用
recognition_mode: multi_speaker的錄音
即時模式 vs. 離線模式
說話者管理提供兩種使用模式,以下是完整對照:
| 操作 | 即時模式(WebSocket) | 離線模式(REST API) |
|---|---|---|
| 重命名說話者 | rename_speaker action | PATCH /api/v1/tasks/{taskId}/speakers/rename |
| 重新指派 | reassign_speaker action | PATCH /api/v1/tasks/{taskId}/speakers/reassign |
| 合併說話者 | merge_speakers action | PATCH /api/v1/tasks/{taskId}/speakers/merge |
| 適用時機 | 錄音進行中 | 錄音結束後 |
| 廣播同步 | 自動推送給 SSE 觀眾 | 不適用 |
REST 版 vs. WebSocket 版 merge 差異:兩者都會合併已存在句子;但 WebSocket 版額外建立「未來 source ID 自動轉 target」的持續映射,這在歷史錄音不適用(已無新句子)。
廣播模式中的說話者管理
在廣播模式下,說話者管理操作會自動同步給 SSE 觀眾:
| WebSocket 操作 | 觀眾收到的 SSE 事件 |
|---|---|
rename_speaker | speaker_renamed |
reassign_speaker | speaker_reassigned |
merge_speakers | speakers_merged |
觀眾端可根據這些事件即時更新 UI:
eventSource.addEventListener('speaker_renamed', (e) => {
const data = JSON.parse(e.data);
// 更新所有 affected_sids 的顯示標籤
data.affected_sids.forEach(sid => {
updateSpeakerLabel(sid, data.new_label);
});
});
eventSource.addEventListener('speaker_reassigned', (e) => {
const data = JSON.parse(e.data);
// 更新單一句子的語者(speaker_id 為原始 ID,speaker_label 為顯示標籤)
updateSpeakerForSentence(data.sid, data.new_speaker_id, data.new_speaker_label);
});
eventSource.addEventListener('speakers_merged', (e) => {
const data = JSON.parse(e.data);
// 更新所有受影響句子的顯示標籤
data.affected_sids.forEach(sid => {
updateSpeakerLabel(sid, data.target_speaker_label);
});
});
最佳實務
1. 先辨識再命名
讓系統先辨識出不同說話者(Guest-1、Guest-2...),確認辨識穩定後再進行重命名。
2. 善用合併功能
如果發現同一個人被識別為多個說話者(例如中途離席又回來),使用 merge_speakers 比逐句 reassign_speaker 更有效率,且能影響未來的辨識結果。
3. 離線編輯補正
錄音結束後,透過 REST API 對逐字稿進行最終校正,確保所有句子的說話者標記正確。
4. 錯誤處理
| 錯誤碼 | 說明 | 處理建議 |
|---|---|---|
speaker_not_found | 找不到指定的說話者 | 確認說話者 ID 存在 |
speaker_name_empty | 名稱不能為空 | 提供有效的名稱 |
speaker_name_duplicate | 名稱已被使用 | 使用其他名稱 |
speaker_sid_not_found | 找不到指定的句子 | 確認 SID 存在 |
speaker_diarization_required | 僅支援語者分離錄音 | 確認使用 multi_speaker 模式 |
merge_speakers_same_id | 來源和目標相同 | 使用不同的語者 ID |
相關 Reference 文件
- REST API - Recording Speaker 編輯
- WebSocket - Voice Translation(rename_speaker / reassign_speaker / merge_speakers)
- SSE - Broadcast Viewer(speaker_renamed / speaker_reassigned / speakers_merged 事件)
版本:V1.5.7 最後更新:2026-05-20