本文檔僅適用於“中國內地(北京)”地區。如需使用模型,需使用“中國內地(北京)”地區的API Key。
本文介紹如何通過WebSocket串連訪問即時語音辨識服務。
DashScope SDK目前僅支援Java和Python。若想使用其他程式設計語言開發Paraformer即時語音辨識應用程式,可以通過WebSocket串連與服務進行通訊。
使用者指南:關於模型介紹和選型建議請參見即時語音辨識-Fun-ASR/Gummy/Paraformer。
WebSocket是一種支援全雙工系統通訊的網路通訊協定。用戶端和伺服器通過一次握手建立持久串連,雙方可以互相主動推送資料,因此在即時性和效率方面具有顯著優勢。
對於常用程式設計語言,有許多現成的WebSocket庫和樣本可供參考,例如:
Go:
gorilla/websocketPHP:
RatchetNode.js:
ws
建議您先瞭解WebSocket的基本原理和技術細節,再參照本文進行開發。
前提條件
已開通服務並擷取API Key。請配置API Key到環境變數(準備下線,併入配置 API Key),而非寫入程式碼在代碼中,防範因代碼泄露導致的安全風險。
當您需要為第三方應用或使用者提供臨時存取權限,或者希望嚴格控制敏感性資料訪問、刪除等高風險操作時,建議使用臨時鑒權Token。
與長期有效 API Key 相比,臨時鑒權 Token 具備時效性短(60秒)、安全性高的特點,適用於臨時調用情境,能有效降低API Key泄露的風險。
使用方式:在代碼中,將原本用於鑒權的 API Key 替換為擷取到的臨時鑒權 Token 即可。
模型列表
paraformer-realtime-v2 | paraformer-realtime-8k-v2 | |
適用情境 | 直播、會議等情境 | 電話客服、語音信箱等 8kHz 音訊識別情境 |
採樣率 | 任意 | 8kHz |
語種 | 中文(包含中文普通話和各種方言)、英文、日語、韓語、德語、法語、俄語 支援的中文方言:上海話、吳語、閩南語、東北話、甘肅話、貴州話、河南話、湖北話、湖南話、江西話、寧夏話、山西話、陝西話、山東話、四川話、天津話、雲南話、粵語 | 中文 |
標點符號預測 | ✅ 預設支援,無需配置 | ✅ 預設支援,無需配置 |
逆文本正則化(ITN) | ✅ 預設支援,無需配置 | ✅ 預設支援,無需配置 |
指定待識別語種 | ✅ 通過 | ❌ |
情感識別 | ❌ |
互動流程
用戶端發送給服務端的訊息有兩種:JSON格式的指令和二進位音頻(須為單聲道音頻);服務端返回給用戶端的訊息稱作事件。
按時間順序,用戶端與服務端的互動流程如下:
建立串連:用戶端與服務端建立WebSocket串連。
開啟任務:
用戶端發送run-task指令以開啟任務。
用戶端收到服務端返回的task-started事件,標誌著任務已成功開啟,可以進行後續步驟。
發送音頻流:
用戶端開始發送二進位音頻,並同時接收服務端持續返回的result-generated事件,該事件包含語音辨識結果。
通知服務端結束任務:
用戶端發送finish-task指令通知服務端結束任務,並繼續接收服務端返回的result-generated事件。
任務結束:
用戶端收到服務端返回的task-finished事件,標誌著任務結束。
關閉串連:用戶端關閉WebSocket串連。
URL
WebSocket URL固定如下:
wss://dashscope.aliyuncs.com/api-ws/v1/inferenceHeaders
參數 | 類型 | 是否必選 | 說明 |
Authorization | string | 是 | 鑒權令牌,格式為 |
user-agent | string | 否 | 用戶端標識,便於服務端追蹤來源。 |
X-DashScope-WorkSpace | string | 否 | 阿里雲百鍊業務空間ID。 |
X-DashScope-DataInspection | string | 否 | 是否啟用資料合規檢測功能。預設不傳或設為 |
指令(用戶端→服務端)
指令是用戶端發送給服務端的訊息,為JSON格式,以Text Frame方式發送,用於控制任務的起止和標識任務邊界。
用戶端發送給服務端的二進位音頻(須為單聲道音頻)不包含在任何指令中,需單獨發送。
發送指令需嚴格遵循以下時序,否則可能導致任務失敗:
用於啟動語音辨識任務。
返回的
task_id需在後續發送finish-task指令時使用,必須保持一致。
發送二進位音頻(單聲道)
用於發送待識別音頻。
必須在接收到服務端返回的task-started事件後發送音頻。
用於結束語音辨識任務。
在音頻發送完畢後發送此指令。
1. run-task指令:開啟任務
該指令用於開啟語音辨識任務。task_id在後續發送finish-task指令時也需要使用,必須保持一致。
發送時機:WebSocket串連建立後。
樣本:
{
"header": {
"action": "run-task",
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx", // 隨機uuid
"streaming": "duplex"
},
"payload": {
"task_group": "audio",
"task": "asr",
"function": "recognition",
"model": "paraformer-realtime-v2",
"parameters": {
"format": "pcm", // 音頻格式
"sample_rate": 16000, // 採樣率
"disfluency_removal_enabled": false, // 過濾語氣詞
"language_hints": [
"en"
] // 指定語言,僅支援paraformer-realtime-v2模型
}
"input": {}
}
}header參數說明:
參數 | 類型 | 是否必選 | 說明 |
header.action | string | 是 | 指令類型。 當前指令中,固定為"run-task"。 |
header.task_id | string | 是 | 當次任務ID。 為32位通用唯一識別碼(UUID),由32個隨機產生的字母和數字組成。可以帶橫線(如 在後續發送finish-task指令時,用到的task_id需要和發送run-task指令時使用的task_id保持一致。 |
header.streaming | string | 是 | 固定字串:"duplex" |
payload參數說明:
參數 | 類型 | 是否必選 | 說明 |
payload.task_group | string | 是 | 固定字串:"audio"。 |
payload.task | string | 是 | 固定字串:"asr"。 |
payload.function | string | 是 | 固定字串:"recognition"。 |
payload.model | string | 是 | 模型名稱,支援的模型請參見模型列表。 |
payload.input | object | 是 | 固定格式:{}。 |
payload.parameters | |||
format | string | 是 | 設定待識別音頻格式。 支援的音頻格式:pcm、wav、mp3、opus、speex、aac、amr。 重要 opus/speex:必須使用Ogg封裝; wav:必須為PCM編碼; amr:僅支援AMR-NB類型。 |
sample_rate | integer | 是 | 設定待識別音頻採樣率(單位Hz)。 因模型而異:
|
disfluency_removal_enabled | boolean | 否 | 設定是否過濾語氣詞:
|
language_hints | array[string] | 否 | 設定待識別語言代碼。如果無法提前確定語種,可不設定,模型會自動識別語種。 目前支援的語言代碼:
該參數僅對支援多語言的模型生效(參見模型列表)。 |
semantic_punctuation_enabled | boolean | 否 | 設定是否開啟語義斷句,預設關閉。
語義斷句準確性更高,適合會議轉寫情境;VAD(Voice Activity Detection,語音活動檢測)斷句延遲較低,適合互動情境。 通過調整 該參數僅在模型為v2及更高版本時生效。 |
max_sentence_silence | integer | 否 | 設定VAD(Voice Activity Detection,語音活動檢測)斷句的靜音時間長度閾值(單位為ms)。 當一段語音後的靜音時間長度超過該閾值時,系統會判定該句子已結束。 參數範圍為200ms至6000ms,預設值為800ms。 該參數僅在 |
multi_threshold_mode_enabled | boolean | 否 | 該開關開啟時(true)可以防止VAD斷句切割過長。預設關閉。 該參數僅在 |
punctuation_prediction_enabled | boolean | 否 | 設定是否在識別結果中自動添加標點:
該參數僅在模型為v2及更高版本時生效。 |
heartbeat | boolean | 否 | 當需要與服務端保持長串連時,可通過該開關進行控制:
該參數僅在模型為v2及更高版本時生效。 |
inverse_text_normalization_enabled | boolean | 否 | 設定是否開啟ITN(Inverse Text Normalization,逆文本正則化)。 預設開啟(true)。開啟後,中文數字將轉換為阿拉伯數字。 該參數僅在模型為v2及更高版本時生效。 |
2. finish-task指令:結束任務
該指令用於結束語音辨識任務。音頻發送完畢後,用戶端可以發送此指令以結束任務。
發送時機:音頻發送完成後。
樣本:
{
"header": {
"action": "finish-task",
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"streaming": "duplex"
},
"payload": {
"input": {}
}
}header參數說明:
參數 | 類型 | 是否必選 | 說明 |
header.action | string | 是 | 指令類型。 當前指令中,固定為"finish-task"。 |
header.task_id | string | 是 | 當次任務ID。 需要和發送run-task指令時使用的task_id保持一致。 |
header.streaming | string | 是 | 固定字串:"duplex" |
payload參數說明:
參數 | 類型 | 是否必選 | 說明 |
payload.input | object | 是 | 固定格式:{}。 |
二進位音頻(用戶端→服務端)
用戶端需在收到task-started事件後,再發送待識別的音頻流。
可以發送即時音頻流(比如從話筒中即時擷取到的)或者錄音檔案音頻流,音頻應是單聲道。
音頻通過WebSocket的二進位通道上傳。建議每次發送100ms的音頻,並間隔100ms。
事件(服務端→用戶端)
事件是服務端返回給用戶端的訊息,為JSON格式,代表不同的處理階段。
1. task-started事件:任務已開啟
當監聽到服務端返回的task-started事件時,標誌著任務已成功開啟。只有在接收到該事件後,才能向伺服器發送待識別音頻或finish-task指令;否則,任務將執行失敗。
task-started事件的payload沒有內容。
樣本:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "task-started",
"attributes": {}
},
"payload": {}
}header參數說明:
參數 | 類型 | 說明 |
header.event | string | 事件類型。 當前事件中,固定為"task-started"。 |
header.task_id | string | 用戶端產生的task_id |
2. result-generated事件:語音辨識結果
用戶端發送待識別音頻和finish-task指令的同時,服務端持續返回result-generated事件,該事件包含語音辨識的結果。
可以通過result-generated事件中的payload.sentence.endTime是否為空白來判斷該結果是中間結果還是最終結果。
樣本:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "result-generated",
"attributes": {}
},
"payload": {
"output": {
"sentence": {
"begin_time": 170,
"end_time": null,
"text": "好,我知道了",
"heartbeat": false,
"sentence_end": true,
"emo_tag": "neutral", //只有請求參數model為paraformer-realtime-8k-v2,且請求參數semantic_punctuation_enabled為false,並且result-generated事件的sentence_end為true時才顯示該欄位
"emo_confidence": 0.914, //只有請求參數model為paraformer-realtime-8k-v2,且請求參數semantic_punctuation_enabled為false,並且result-generated事件的sentence_end為true時才顯示該欄位
"words": [
{
"begin_time": 170,
"end_time": 295,
"text": "好",
"punctuation": ","
},
{
"begin_time": 295,
"end_time": 503,
"text": "我",
"punctuation": ""
},
{
"begin_time": 503,
"end_time": 711,
"text": "知道",
"punctuation": ""
},
{
"begin_time": 711,
"end_time": 920,
"text": "了",
"punctuation": ""
}
]
}
},
"usage": {
"duration": 3
}
}
}header參數說明:
參數 | 類型 | 說明 |
header.event | string | 事件類型。 當前事件中,固定為"result-generated"。 |
header.task_id | string | 用戶端產生的task_id。 |
payload參數說明:
參數 | 類型 | 說明 |
output | object | output.sentence為識別結果,詳細內容見下文。 |
usage | object | 當 當 |
payload.output.usage格式如下:
參數 | 類型 | 說明 |
duration | integer | 任務計費時間長度(單位為秒)。 |
payload.output.sentence格式如下:
參數 | 類型 | 說明 |
begin_time | integer | 句子開始時間,單位為ms。 |
end_time | integer | null | 句子結束時間,如果為中間識別結果則為null,單位為ms。 |
text | string | 識別文本。 |
words | array | 字時間戳記資訊。 |
heartbeat | boolean | null | 若該值為true,可跳過識別結果的處理。 |
sentence_end | boolean | 判斷給定句子是否已結束。 |
emo_tag | string | 當前句子的情感:
情感識別遵循如下約束:
|
emo_confidence | number | 當前句子識別情感的信賴度,取值範圍:[0.0,1.0],值越大表示信賴度越高。 情感識別遵循如下約束:
|
payload.output.sentence.words為字時間戳記列表,其中每一個word格式如下:
參數 | 類型 | 說明 |
begin_time | integer | 字開始時間,單位為ms。 |
end_time | integer | 字結束時間,單位為ms。 |
text | string | 字。 |
punctuation | string | 標點。 |
3. task-finished事件:任務已結束
當監聽到服務端返回的task-finished事件時,說明任務已結束。此時可以關閉WebSocket串連並結束程式。
樣本:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "task-finished",
"attributes": {}
},
"payload": {
"output": {},
"usage": null
}
}header參數說明:
參數 | 類型 | 說明 |
header.event | string | 事件類型。 當前事件中,固定為"task-finished"。 |
header.task_id | string | 用戶端產生的task_id。 |
4. task-failed事件:任務失敗
如果接收到task-failed事件,表示任務失敗。此時需要關閉WebSocket串連並處理錯誤。通過分析報錯資訊,如果是由於編程問題導致的任務失敗,您可以調整代碼進行修正。
樣本:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "task-failed",
"error_code": "CLIENT_ERROR",
"error_message": "request timeout after 23 seconds.",
"attributes": {}
},
"payload": {}
}header參數說明:
參數 | 類型 | 說明 |
header.event | string | 事件類型。 當前事件中,固定為"task-failed"。 |
header.task_id | string | 用戶端產生的task_id。 |
header.error_code | string | 報錯類型描述。 |
header.error_message | string | 具體報錯原因。 |
關於建連開銷和串連複用
WebSocket服務支援串連複用以提升資源的利用效率,避免建立串連開銷。
服務端收到用戶端發送的run-task指令後,將啟動一個新的任務,用戶端發送finish-task指令後,服務端在任務完成時返回task-finished事件以結束該任務。結束任務後WebSocket串連可以被複用,用戶端重新發送run-task指令即可開啟下一個任務。
在複用串連中的不同任務需要使用不同 task_id。
如果在任務執行過程中發生失敗,服務將依然返回task-failed事件,並關閉該串連。此時這個串連無法繼續複用。
如果在任務結束後60秒沒有新的任務,串連會逾時自動斷開。
範例程式碼
範例程式碼僅提供最基礎的服務調通實現,實際業務情境的相關代碼需您自行開發。
在編寫WebSocket用戶端代碼時,為了同時發送和接收訊息,通常採用非同步編程。您可以按照以下步驟來編寫程式:
錯誤碼
如遇報錯問題,請參見錯誤資訊進行排查。
若問題仍未解決,請加入開發人員群反饋遇到的問題,並提供Request ID,以便進一步排查問題。
常見問題
功能特性
Q:在長時間靜默的情況下,如何保持與服務端長串連?
將請求參數heartbeat設定為true,並持續向服務端發送靜音音頻。
靜音音頻指的是在音頻檔案或資料流中沒有聲音訊號的內容。靜音音頻可以通過多種方法產生,例如使用音頻編輯軟體如Audacity或Adobe Audition,或者通過命令列工具如FFmpeg。
Q:如何將音頻格式轉換為滿足要求的格式?
可使用FFmpeg工具,更多用法請參見FFmpeg官網。
# 基礎轉換命令(萬能模板)
# -i,作用:輸入檔案路徑,常用值樣本:audio.wav
# -c:a,作用:音頻編碼器,常用值樣本:aac, libmp3lame, pcm_s16le
# -b:a,作用:位元速率(音質控制),常用值樣本:192k, 320k
# -ar,作用:採樣率,常用值樣本:44100 (CD), 48000, 16000
# -ac,作用:聲道數,常用值樣本:1(單聲道), 2(立體聲)
# -y,作用:覆蓋已存在檔案(無需值)
ffmpeg -i input_audio.ext -c:a 編碼器名 -b:a 位元速率 -ar 採樣率 -ac 聲道數 output.ext
# 例如:WAV → MP3(保持原始品質)
ffmpeg -i input.wav -c:a libmp3lame -q:a 0 output.mp3
# 例如:MP3 → WAV(16bit PCM標準格式)
ffmpeg -i input.mp3 -c:a pcm_s16le -ar 44100 -ac 2 output.wav
# 例如:M4A → AAC(提取/轉換蘋果音頻)
ffmpeg -i input.m4a -c:a copy output.aac # 直接提取不重編碼
ffmpeg -i input.m4a -c:a aac -b:a 256k output.aac # 重編碼提高品質
# 例如:FLAC無損 → Opus(高壓縮)
ffmpeg -i input.flac -c:a libopus -b:a 128k -vbr on output.opusQ:是否支援查看每句話對應的時間範圍?
支援。語音辨識結果中會包含每句話的開始時間戳和結束時間戳記,可通過它們確定每句話的時間範圍。
Q:為什麼使用WebSocket協議而非HTTP/HTTPS協議?為什麼不提供RESTful API?
Voice Messaging Service選擇 WebSocket 而非 HTTP/HTTPS/RESTful,根本在於其依賴全雙工系統通訊能力——WebSocket 允許服務端與用戶端主動雙向傳輸資料(如即時推送語音合成/識別進度),而基於 HTTP 的 RESTful 僅支援用戶端發起的單向要求-回應模式,無法滿足即時互動需求。
Q:如何識別本地檔案(錄音檔案)?
將本地檔案轉成二進位音頻流,通過WebSocket的二進位通道上傳二進位音頻流進行識別(通常為WebSocket庫的send方法)。程式碼片段如下所示,完整樣本請參見範例程式碼。
故障排查
如遇代碼報錯問題,請根據錯誤碼中的資訊進行排查。
Q:無法識別語音(無識別結果)是什麼原因?
請檢查請求參數中的音頻格式(
format)和採樣率(sampleRate/sample_rate)設定是否正確且符合參數約束。以下為常見錯誤樣本:音頻副檔名為 .wav,但實際為 MP3 格式,而請求參數
format設定為 mp3(參數設定錯誤)。音頻採樣率為 3600Hz,但請求參數
sampleRate/sample_rate設定為 48000(參數設定錯誤)。
可以使用ffprobe工具擷取音訊容器、編碼、採樣率、聲道等資訊:
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx使用
paraformer-realtime-v2模型時,請檢查language_hints設定的語言是否與音頻實際語言一致。例如:音頻實際為中文,但
language_hints設定為en(英文)。