音檔匯入指南
目錄
概述
音檔匯入功能讓您上傳預錄的音檔,由系統在背景進行語音辨識、翻譯和摘要處理。與即時語音翻譯(WebSocket)不同,音檔匯入使用 REST API,適合離線批次處理場景。
整體流程
點數檢查 → 上傳音檔 → 追蹤處理進度 → 取得結果
| 步驟 | API | 說明 |
|---|---|---|
| 1. 點數檢查 | POST /api/v1/imports/check-quota | 確認剩餘點數是否足夠 |
| 2. 上傳音檔 | POST /api/v1/imports | 以 multipart/form-data 上傳 |
| 3. 查詢狀態 | GET /api/v1/imports/{importId} | 輪詢處理進度 |
| 3b. 即時進度 | GET /api/v1/sse/imports/{importId}/progress | SSE 即時進度推送(替代輪詢) |
| 4. 查看結果 | Tasks API / SSE API | 取得逐字稿、翻譯、摘要 |
認證方式
所有音檔匯入 API 透過 Header X-API-Key 認證。詳見 認證機制。
支援的音檔格式
| 格式 | MIME Type | 說明 |
|---|---|---|
| MP3 | audio/mpeg | 最常見的壓縮格式 |
| WAV | audio/wav | 無損格式,檔案較大 |
| M4A | audio/mp4 | Apple 常用格式 |
格式依檔案的實際內容判斷,不看副檔名;副檔名與內容不符時(例如檔名是 .mp3、內容是 WAV)依內容處理。
檔案限制:
| 項目 | 限制 | 何時被擋下 |
|---|---|---|
| 最大檔案大小 | 500 MB | 上傳當下(HTTP 413 import_file_too_large) |
| 最大時長 | 10 小時 | 開始轉錄之前(匯入進度的 failed 事件,error_code 為 import_duration_out_of_range) |
| 最小時長 | 1 秒 | 同上 |
時長是在音檔上傳完成、系統分析出實際長度之後才檢查的,因此超長音檔會先上傳成功、再以
failed事件結束。若要在上傳前就知道,請先呼叫匯入預檢端點——它接受您自行量測的時長並即時回覆。
點數檢查
上傳前建議先檢查點數是否足夠,避免上傳大檔案後才發現點數不足。
請求
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports/check-quota" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"duration_ms": 3600000}'
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
duration_ms | integer | 是 | 音檔預估時長(毫秒),範圍 1,000 ~ 36,000,000 |
回應
{
"data": {
"allowed": true,
"reason": null,
"is_unlimited": false,
"remain_quota": 480.0,
"duration_minutes": 60,
"estimated_points": 18.0
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
allowed | boolean | true 表示可以上傳 |
reason | string | null | 不允許的原因,見 匯入 API 參考。allowed 為 true 時是 null |
is_unlimited | boolean | 是否為吃到飽(不限點數) |
remain_quota | float | null | 剩餘點數,吃到飽時為 null |
duration_minutes | integer | 音檔預估時長(分鐘,無條件進位) |
estimated_points | float | 預估扣點(以 STT 基準估算;實際另含翻譯/語者等功能,於上傳時精算) |
注意:
allowed為false時,請依reason給不同的提示 —— 儲值不是所有情況的解法:
reason該告訴使用者什麼 insufficient_credit儲值點數後再使用 plan_not_allowed目前方案不含匯入,需升級方案 plan_daily_limit_reached今日用量已滿,明日重置後可再上傳(儲值無法解決),或改傳短一點的檔案 可利用
duration_minutes和estimated_points顯示「需扣 X 點」的提示。
上傳音檔
使用 multipart/form-data 格式上傳音檔及處理參數。
基本請求
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports" \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@meeting.mp3" \
-F 'transcription_languages=["zh-TW"]' \
-F 'translation_languages=["en-US"]' \
-F "recognition_mode=multi_speaker"
含摘要與文字處理的請求
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports" \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@meeting.mp3" \
-F 'transcription_languages=["zh-TW"]' \
-F 'translation_languages=["en-US"]' \
-F "recognition_mode=multi_speaker" \
-F "summary_template=meeting" \
-F 'terminology={"zh-TW": [{"term": "語者分離"}]}' \
-F 'translation_dict={"en-US": [{"source": "語者分離", "target": "Speaker Diarization"}]}'
成功回應(HTTP 202)
{
"data": {
"import_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"stage": null,
"progress": 0,
"message": null,
"original_filename": "meeting.mp3",
"file_size": "15.2 MB",
"task_id": null,
"created_at": "2026-01-15T10:00:00.000Z"
}
}
注意:回應碼為 202 Accepted,表示伺服器已接受上傳但處理尚未完成。保存
import_id用於後續查詢進度。
常見錯誤
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理方式 |
|---|---|---|---|
import_file_too_large | 413 | 檔案超過 500 MB | 壓縮或分割檔案 |
import_invalid_format | 415 | 不支援的音檔格式 | 使用 mp3/wav/m4a |
import_recognition_mode_unsupported | 422 | 匯入不支援此辨識模式 | recognition_mode 改用 single 或 multi_speaker |
auth_insufficient_credit | 402 | 點數不足 | 儲值點數後再使用 |
參數說明
必填參數
| 參數 | 類型 | 說明 |
|---|---|---|
file | file | 音檔(multipart/form-data) |
transcription_languages | string (JSON) | 轉錄語言,JSON 陣列格式(如 ["zh-TW"]) |
recognition_mode | string | single(單人)或 multi_speaker(多人語者分離) |
選填參數
| 參數 | 類型 | 說明 |
|---|---|---|
translation_languages | string (JSON) | 翻譯目標語言,JSON 陣列格式(如 ["en-US", "ja-JP"]) |
summary_template | string | 摘要模板識別碼(如 meeting、interview、speech) |
summary_mode | string | 摘要模式:builtin(預設)或 custom |
summary_prompt | string | custom 模式的自訂 prompt 全文(最大 3000 字元) |
summary_prompt_slug | string | custom 模式的自訂識別碼(最大 64 字元) |
terminology | string (JSON) | 術語庫(提升辨識準確度) |
fuzzy_correction | string (JSON) | 模糊詞校正規則(通常不需手動設定) |
translation_dict | string (JSON) | 翻譯字典(確保專有名詞翻譯一致) |
callback_url | string | Webhook 回呼 URL(處理完成/失敗時通知) |
辨識模式
| 模式 | 說明 | 適用場景 |
|---|---|---|
single | 單人辨識 | 單一講者的語音備忘、演講錄音 |
multi_speaker | 多人語者分離 | 會議錄音、訪談、多人對話 |
已知限制:檔案匯入不支援多聲道語者分離——
recognition_mode僅接受上表兩種模式,指定multi_language或multi_channel會回 422import_recognition_mode_unsupported;channel_mode、channels等聲道相關參數也不適用於檔案匯入。多聲道僅提供於即時語音(WebSocket)。
摘要模板
可用的摘要模板可透過 GET /api/v1/summary-templates 查詢:
| 模板 | 適用場景 |
|---|---|
general | 通用摘要 |
meeting | 會議記錄 |
meeting_minutes | 詳細會議紀要 |
speech | 演講內容 |
interview | 訪談內容 |
course | 課程內容 |
查詢匯入狀態
上傳成功後,使用 import_id 輪詢處理進度。
請求
curl -X GET "https://vas-poc.vurbo.ai/api/v1/imports/{importId}" \
-H "X-API-Key: YOUR_API_KEY"
回應
{
"data": {
"import_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"stage": "transcribing",
"progress": 45,
"message": "正在辨識語音...",
"task_id": null,
"error_code": null,
"error_message": null
}
}
狀態流轉
pending → processing → completed
└→ failed
| 狀態 | 說明 |
|---|---|
pending | 已排入佇列,等待處理 |
processing | 正在處理中 |
completed | 處理完成(task_id 有值) |
failed | 處理失敗(error_code 和 error_message 有值) |
completed與failed是最終狀態,之後不會再改變:已標為failed的匯入不會再變成completed,也不會扣點。- 處理中遇到暫時性的錯誤會自動重試,重試期間維持
processing;重試用盡才標為failed,import.failedWebhook 只會送出一次。 - 長時間沒有開始處理的匯入(停在
pending)會標為failed,error_code為PROCESSING_TIMEOUT。 error_message是依錯誤碼提供的一般說明,不含內部細節;需要排查時請提供import_id。錯誤碼一覽見 錯誤碼參考。
處理階段(Stage)
在 processing 狀態下,stage 欄位表示目前的處理階段:
| 階段 | 說明 | 大約進度 |
|---|---|---|
converting | 音檔格式轉換 | 0% ~ 10% |
transcribing | 語音辨識中 | 10% ~ 60% |
translating | 翻譯中 | 60% ~ 85% |
summarizing | 生成摘要中 | 85% ~ 100% |
輪詢建議
async function pollImportStatus(importId, apiKey) {
const interval = setInterval(async () => {
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/imports/${importId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const result = await response.json();
const { status, stage, progress, task_id } = result.data;
console.log(`狀態: ${status}, 階段: ${stage}, 進度: ${progress}%`);
if (status === 'completed') {
clearInterval(interval);
console.log(`處理完成!Task ID: ${task_id}`);
// 使用 task_id 載入結果...
} else if (status === 'failed') {
clearInterval(interval);
console.error(`處理失敗: ${result.data.error_message}`);
}
}, 5000); // 每 5 秒查詢一次
}
建議:輪詢間隔設為 3~5 秒即可。過於頻繁的輪詢不會加速處理。
音檔無法辨識時的行為(v1.3.5)
若音檔因為「整段靜音 / 音量過小 / 全程雜訊 / 辨識語言與音檔實際語言不符」等原因,導致語音辨識結果為空,系統仍會以 completed 狀態結束(不是 failed),但逐字稿將為空陣列。
行為定義
| 項目 | 值 |
|---|---|
最終 status | completed(不是 failed) |
| SSE 最終事件 | completed(task_id 有值) |
| Webhook 事件 | recording.completed + import.completed |
| 逐字稿 entries | [](空陣列) |
segments_count | 0 |
| 點數扣除 | 依音檔實際時長扣除,不會退還 |
為什麼不是 failed?
failed 代表處理流程本身出錯(如格式錯誤、點數不足、音檔解析失敗)。音檔處理流程完整跑完、只是辨識不出內容,屬於合法的完成狀態。這讓客戶端能以相同的成功分支處理結果,並透過 entries.length === 0 判斷需要顯示「無語音內容」提示。
客戶端處理建議
載入逐字稿(GET /api/v1/sse/history/transcribe/{taskId})時,若累積的句子數為 0,建議顯示空狀態:
const sentences = [];
// ... 處理 SSE 事件收集 init_sentence
if (sentences.length === 0) {
// 顯示空狀態
showEmptyState({
title: '此音檔未辨識出語音內容',
hint: '可能原因:音量過小、全程靜音、或辨識語言與音檔不符。建議確認音檔品質或調整辨識語言後重新上傳。',
});
} else {
renderTranscript(sentences);
}
如何預防
- 檢查辨識語言設定:確認
transcription_languages與音檔實際語言一致(例如英文音檔選en-US,不要選zh-TW) - 檢查音檔品質:確認音檔有清晰人聲、音量足夠(建議峰值 -12 dBFS 以上)
- 多語言音檔:若音檔為多語言內容,建議拆分後分別上傳
小提示:點數會依音檔時長扣除,無法辨識的音檔也不例外。上傳前建議先試聽確認。
匯入完成後
當狀態變為 completed,回應中的 task_id 就是該匯入任務對應的 Task ID。透過此 ID 可以:
1. 查看任務列表
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks" \
-H "X-API-Key: YOUR_API_KEY"
2. 載入逐字稿(SSE 串流)
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/sse/history/transcribe/${taskId}`,
{ headers: { 'X-API-Key': apiKey } }
);
// 處理 SSE 事件:init_metadata → init_sentence × N → init_summary → init_done
3. 播放音訊
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/sse/audio/${taskId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const blob = await response.blob();
const audio = new Audio(URL.createObjectURL(blob));
audio.play();
4. 重新翻譯為其他語言
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/sse/retranslate/${taskId}?targetLang=ja-JP`,
{ headers: { 'X-API-Key': apiKey } }
);
// 處理 SSE 事件:translation × N → done
完整的歷史紀錄操作,請參考 歷史紀錄與回放指南。
文字處理參數
上傳時可附帶文字處理參數,提升辨識與翻譯品質。
術語庫(terminology)
以 JSON 物件格式,以語言代碼為 key:
{
"zh-TW": [
{ "term": "語者分離" },
{ "term": "CVD製程" }
]
}
| 欄位 | 必填 | 說明 |
|---|---|---|
term | 是 | 術語文字(最大 100 字元) |
每種語言最多 500 個術語,且所有語言合計也不得超過 500 筆(兩個上限都會驗證,超過回 422)。模糊詞校正規則同樣有兩個上限:每種語言最多 4000 條、所有語言合計也不得超過 4000 條。術語庫本身也會驅動同音校正,讀音相同的錯字只設術語就能修正。
這些數字是預設值:實際生效的上限可依環境調整,一律以 422 回應裡的訊息為準,不要把數字寫死在整合裡。
術語只會套用在與其語言代碼相符的辨識語言上——音檔匯入是單一語言,因此只有本次辨識語言底下的術語會生效,其餘語言的術語不生效但仍計入合計。
模糊詞校正(fuzzy_correction)
通常不需手動設定 —— 同音錯字由 terminology 直接涵蓋。僅在錯字與正確詞讀音不同時需要:
{
"zh-TW": [
{ "correct": "語者分離", "incorrect": ["語這分離", "語者分力"] },
{ "correct": "IPEVO", "incorrect": ["ltfo"], "case_insensitive": true }
]
}
case_insensitive 為選填、預設 false(嚴格比對,區分大小寫)。設為 true 時,該條規則的所有 incorrect 變體都會忽略大小寫。旗標是逐條的,同一個 correct 可拆成多條規則各自設定。對中文規則無作用。
同一個錯誤變體出現在多條規則時:碰撞以
incorrect為準(不是correct),大小寫旗標取嚴格優先。因此拆成多條規則是安全的,只要各條的incorrect不重複。
翻譯字典(translation_dict)
確保專有名詞翻譯一致。以語言代碼分組,每個語言各自一份字典:
{
"en-US": [
{ "source": "語者分離", "target": "Speaker Diarization" },
{ "source": "IPEVO", "target": "IPEVO", "case_sensitive": true }
],
"ja-JP": [
{ "source": "語者分離", "target": "話者分離" }
]
}
case_sensitive 為選填、預設 false(不分大小寫);設為 true 時僅在大小寫完全相符時套用。
舊格式仍然支援:先前的條目陣列格式繼續接受,內容與行為完全不變。
注意:與
fuzzy_correction的case_insensitive欄名互為反義、預設行為也相反(前者預設嚴格、後者預設寬鬆),請勿共用同一個變數。設錯不會有錯誤訊息,只會做出相反的比對行為。
每個語言最多 3000 條目。
Webhook 通知
設定 callback_url 後,處理完成或失敗時 VAS 會主動發送 HTTP POST 通知到您的伺服器,免除輪詢的需要。
設定方式
在上傳時加入 callback_url 參數:
curl -X POST "https://vas-poc.vurbo.ai/api/v1/imports" \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@meeting.mp3" \
-F 'transcription_languages=["zh-TW"]' \
-F "recognition_mode=multi_speaker" \
-F "callback_url=https://your-server.com/webhooks/vas"
收到的事件
| 結果 | 事件 | 說明 |
|---|---|---|
| 成功 | recording.completed + import.completed | 收到兩個事件 |
| 失敗 | import.failed | 匯入階段失敗 |
完整的 Webhook 格式、簽名驗證和範例程式碼,請參考 Webhook 回呼指南。
完整流程圖
┌────────────────────┐
│ check-quota │ 檢查點數是否足夠
│ POST /imports/ │
│ check-quota │
└────────┬───────────┘
│
allowed: true?
╱ ╲
是 否 → 依 reason 給提示
│ (儲值/升級方案/明日再試)
│
┌─────────▼──────────┐
│ POST /imports │ 上傳音檔
│ multipart/form-data│ (transcription_languages,
│ │ translation_languages,
│ │ recognition_mode, ...)
└─────────┬──────────┘
│
HTTP 202
import_id
│
┌─────────▼──────────┐
│ GET /imports/{id} │ 輪詢處理狀態
│ 每 3~5 秒 │ (每 3~5 秒查詢一次)
└─────────┬──────────┘
│
status 判斷
╱ │ ╲
pending processing completed / failed
│ │
stage: task_id ←── 處理完成
converting │
transcribing ┌────▼─────────────┐
translating │ Tasks API │ 查看任務列表
summarizing │ SSE History API │ 載入逐字稿
│ SSE Audio API │ 播放音訊
│ SSE Retranslate │ 重新翻譯
└──────────────────┘
相關文件
| 文件 | 說明 |
|---|---|
| 認證機制 | API Key 認證詳細說明 |
| Imports API Reference | 音檔匯入 API 完整規格 |
| 匯入進度 SSE | 即時進度追蹤 SSE 串流規格 |
| Tasks API Reference | 任務管理 API 完整規格 |
| Summary Templates Reference | 摘要模板查詢 |
| 歷史紀錄與回放 | 匯入完成後如何載入與回放紀錄 |
版本:V1.24.1 最後更新:2026-09-28