本文介紹Fun-ASR-Realtime即時語音辨識Python SDK的參數和介面細節。
前提條件
已開通服務並擷取與配置 API Key。請配置API Key到環境變數,而非寫入程式碼在代碼中,防範因代碼泄露導致的安全風險。
快速開始
Recognition類提供了非流式調用和雙向流式調用等介面。請根據實際需求選擇合適的調用方式:
- 非流式調用:針對本地檔案進行識別,並一次性返回完整的處理結果。適合處理錄製好的音頻。
- 雙向流式調用:可直接對音頻流進行識別,並即時輸出結果。音頻流可以來自外部裝置(如麥克風)或從本地檔案讀取。適合需要即時反饋的情境。
非流式調用
提交單個語音即時轉寫任務,通過傳入本地檔案的方式同步阻塞地拿到轉寫結果。
執行個體化Recognition類綁定請求參數,調用call進行識別/翻譯並最終擷取識別結果(RecognitionResult)。
from http import HTTPStatus
import dashscope
from dashscope.audio.asr import Recognition
import os
# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下為新加坡地區的配置,調用時請將"{WorkspaceId}"替換為真實的業務空間ID,各地區的配置不同。
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
recognition = Recognition(model='fun-asr-realtime',
format='wav',
sample_rate=16000,
callback=None)
result = recognition.call('{YOUR_AUDIO_FILE}')
if result.status_code == HTTPStatus.OK:
print('識別結果:')
print(result.get_sentence())
else:
print('Error: ', result.message)
print(
'[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
.format(
recognition.get_last_request_id(),
recognition.get_first_package_delay(),
recognition.get_last_package_delay(),
))
雙向流式調用
提交單個語音即時轉寫任務,通過實現回調介面的方式流式輸出即時識別結果。
-
啟動流式語音辨識
執行個體化Recognition類綁定請求參數和回調介面(RecognitionCallback),調用
start方法啟動流式語音辨識。 -
串流
迴圈調用Recognition類的
send_audio_frame方法,將從本地檔案或裝置(如麥克風)讀取的二進位音頻流分段發送至服務端。在發送音頻資料的過程中,服務端會通過回調介面(RecognitionCallback)的
on_event方法,將識別結果即時返回給用戶端。建議每次發送的音頻時間長度約為100毫秒,資料大小保持在1KB至16KB之間。
-
結束處理
調用Recognition類的
stop方法結束語音辨識。該方法會阻塞當前線程,直到回調介面(RecognitionCallback)的
on_complete或者on_error回調觸發後才會釋放線程阻塞。
import os
import signal # for keyboard events handling (press "Ctrl+C" to terminate recording)
import sys
import dashscope
import pyaudio
from dashscope.audio.asr import *
mic = None
stream = None
# Set recording parameters
sample_rate = 16000 # sampling rate (Hz)
channels = 1 # mono channel
dtype = 'int16' # data type
format_pcm = 'pcm' # the format of the audio data
block_size = 3200 # number of frames per buffer
# Real-time speech recognition callback
class Callback(RecognitionCallback):
def on_open(self) -> None:
global mic
global stream
print('RecognitionCallback open.')
mic = pyaudio.PyAudio()
stream = mic.open(format=pyaudio.paInt16,
channels=1,
rate=16000,
input=True)
def on_close(self) -> None:
global mic
global stream
print('RecognitionCallback close.')
stream.stop_stream()
stream.close()
mic.terminate()
stream = None
mic = None
def on_complete(self) -> None:
print('RecognitionCallback completed.') # recognition completed
def on_error(self, message) -> None:
print('RecognitionCallback task_id: ', message.request_id)
print('RecognitionCallback error: ', message.message)
# Stop and close the audio stream if it is running
if 'stream' in globals() and stream.is_active():
stream.stop_stream()
stream.close()
# Forcefully exit the program
sys.exit(1)
def on_event(self, result: RecognitionResult) -> None:
sentence = result.get_sentence()
if 'text' in sentence:
print('RecognitionCallback text: ', sentence['text'])
if RecognitionResult.is_sentence_end(sentence):
print(
'RecognitionCallback sentence end, request_id:%s, usage:%s'
% (result.get_request_id(), result.get_usage(sentence)))
def signal_handler(sig, frame):
print('Ctrl+C pressed, stop recognition ...')
# Stop recognition
recognition.stop()
print('Recognition stopped.')
print(
'[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
.format(
recognition.get_last_request_id(),
recognition.get_first_package_delay(),
recognition.get_last_package_delay(),
))
# Forcefully exit the program
sys.exit(0)
# main function
if __name__ == '__main__':
# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下為新加坡地區的配置,調用時請將"{WorkspaceId}"替換為真實的業務空間ID,各地區的配置不同。
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
# Create the recognition callback
callback = Callback()
# Call recognition service by async mode, you can customize the recognition parameters, like model, format,
# sample_rate
recognition = Recognition(
model='fun-asr-realtime',
format=format_pcm,
# 'pcm'、'wav'、'opus'、'speex'、'aac'、'amr', you can check the supported formats in the document
sample_rate=sample_rate,
# support 8000, 16000
semantic_punctuation_enabled=False,
callback=callback)
# Start recognition
recognition.start()
signal.signal(signal.SIGINT, signal_handler)
print("Press 'Ctrl+C' to stop recording and recognition...")
# Create a keyboard listener until "Ctrl+C" is pressed
while True:
if stream:
data = stream.read(3200, exception_on_overflow=False)
recognition.send_audio_frame(data)
else:
break
recognition.stop()
import os
import time
import dashscope
from dashscope.audio.asr import *
# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下為新加坡地區的配置,調用時請將"{WorkspaceId}"替換為真實的業務空間ID,各地區的配置不同。
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
from datetime import datetime
def get_timestamp():
now = datetime.now()
formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
return formatted_timestamp
class Callback(RecognitionCallback):
def on_complete(self) -> None:
print(get_timestamp() + ' Recognition completed') # recognition complete
def on_error(self, result: RecognitionResult) -> None:
print('Recognition task_id: ', result.request_id)
print('Recognition error: ', result.message)
exit(0)
def on_event(self, result: RecognitionResult) -> None:
sentence = result.get_sentence()
if 'text' in sentence:
print(get_timestamp() + ' RecognitionCallback text: ', sentence['text'])
if RecognitionResult.is_sentence_end(sentence):
print(get_timestamp() +
'RecognitionCallback sentence end, request_id:%s, usage:%s'
% (result.get_request_id(), result.get_usage(sentence)))
callback = Callback()
recognition = Recognition(model='fun-asr-realtime',
format='wav',
sample_rate=16000,
callback=callback)
try:
audio_data: bytes = None
f = open("{YOUR_AUDIO_FILE}", 'rb')
if os.path.getsize("{YOUR_AUDIO_FILE}"):
# 一次性將檔案資料全部讀入buffer
file_buffer = f.read()
f.close()
print("Start Recognition")
recognition.start()
# 從buffer中間隔3200位元組發送一次
buffer_size = len(file_buffer)
offset = 0
chunk_size = 3200
while offset < buffer_size:
# 計算本次要發送的資料區塊大小
remaining_bytes = buffer_size - offset
current_chunk_size = min(chunk_size, remaining_bytes)
# 從buffer中提取當前資料區塊
audio_data = file_buffer[offset:offset + current_chunk_size]
# 發送音頻資料幀
recognition.send_audio_frame(audio_data)
# 更新位移量
offset += current_chunk_size
# 添加延遲類比即時傳輸
time.sleep(0.1)
recognition.stop()
else:
raise Exception(
'The supplied file was empty (zero bytes long)')
except Exception as e:
raise e
print(
'[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
.format(
recognition.get_last_request_id(),
recognition.get_first_package_delay(),
recognition.get_last_package_delay(),
))
介面地址
SDK的介面地址需在初始化前設定為下方地址(包含WorkspaceId)。如需切換到其他地區,請修改 dashscope.base_websocket_api_url為對應地區的URL。
新加坡
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference
調用時請將{WorkspaceId}替換為真實的Workspace ID。
華北2(北京)
wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/inference
調用時請將{WorkspaceId}替換為真實的Workspace ID。
切換到新加坡地區:
import dashscope
# 調用時請將"{WorkspaceId}"替換為真實的業務空間ID
dashscope.base_websocket_api_url = 'wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
重要阿里雲百鍊為華北2(北京)、新加坡地區推出了業務空間專屬網域名稱,能夠為推理請求提供卓越的效能和更高的穩定性,建議遷移至新網域名稱:
- 華北2(北京)地區:從
dashscope.aliyuncs.com遷移至{WorkspaceId}.cn-beijing.maas.aliyuncs.com - 新加坡地區:從
dashscope-intl.aliyuncs.com遷移至{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
請求參數
請求參數通過Recognition類的構造方法(init)進行設定。
| 參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
model | str | 是 | 模型名稱。 |
sample_rate | int | 是 | 採樣率(Hz)。 取值範圍:8k模型僅支援 8000 Hz,其他模型支援任意採樣率。 |
format | str | 是 | 音頻格式。 取值範圍:
重要opus/speex:必須使用Ogg封裝; wav:必須為PCM編碼; amr:僅支援AMR-NB類型。 |
vocabulary_id | str | 否 | 先行編譯熱詞列表 ID。 需預先調用建立熱詞列表介面產生,識別時傳入該 ID 即可使用列表中的熱詞。 適用於詞彙已知且相對穩定、需要跨請求複用同一詞表的情境。 使用方法請參見先行編譯熱詞。 |
semantic_punctuation_enabled | bool | 否 | 是否啟用語義斷句。 預設值:False。
語義斷句準確性更高,適合會議轉寫情境;VAD(Voice Activity Detection,語音活動檢測)斷句延遲較低,適合互動情境。 |
max_sentence_silence | int | 否 | VAD 斷句靜音閾值(ms)。當一段語音後的靜音時間長度超過該閾值時,系統會判定該句子已結束。當 預設值:1300。 取值範圍:[200, 6000]。 |
multi_threshold_mode_enabled | bool | 否 | 重要僅在 是否啟用多閾值模式。啟用後可防止 VAD 斷句切割過長。 預設值:False。 |
punctuation_prediction_enabled | bool | 否 | 設定是否在識別結果中自動添加標點:
|
heartbeat | bool | 否 | 是否啟用心跳包。 預設值:False。
靜音音頻指的是在音頻檔案或資料流中沒有聲音訊號的內容。靜音音頻可以通過多種方法產生,例如使用音頻編輯軟體如Audacity或Adobe Audition,或者通過命令列工具如FFmpeg。 使用該欄位時,SDK版本不能低於1.23.1。 |
language_hints | list[str] | 否 | 待識別音頻語種。無預設值,不設定時模型自動識別。 僅支援設定 1 個值,設定多個時僅第一個生效。 點擊查看支援的語言代碼
|
speech_noise_threshold | float | 否 | 語音與噪音的判定閾值,用於調整語音活動檢測(VAD)的靈敏度。 取值範圍:[-1.0, 1.0]。 取值說明:
此參數為進階配置參數,調整可能顯著影響識別效果,建議:
|
special_word_filter | str | 否 | 指定在語音辨識過程中需要處理的敏感詞,並支援對不同敏感詞設定不同的處理方式。詳情請參見敏感詞過濾。 |
callback | RecognitionCallback | 否 | 回調介面(RecognitionCallback)。 |
以下參數通過Recognition執行個體的call或start方法的關鍵字參數傳入。
| 參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
raw_input | dict | 否 | 輸入對象,用於傳入對話上下文(context)。上下文用於輔助識別、提升專有詞彙的識別準確率。使用方法詳見快速開始。 重要僅 dict 中需包含
重要約束:上下文訊息( 重要攜帶上下文時, 說明使用該欄位時,SDK版本不能低於1.25.23。
|
關鍵介面
Recognition類
Recognition通過from dashscope.audio.asr import *方式引入。
| 成員方法 | 方法簽名 | 說明 |
|---|---|---|
call | | 基於本地檔案的非流式調用,該方法會阻塞當前線程直到全部音頻讀完,該方法要求所識別檔案具有可讀許可權。 識別結果以 |
start | | 開始語音辨識。 基於回調形式的流式即時識別,該方法不會阻塞當前線程。需要配合 |
send_audio_frame | | 推送音頻。每次推送的音頻流不宜過大或過小,建議每包音頻時間長度為100ms左右,大小在1KB~16KB之間。 識別結果通過回調介面(RecognitionCallback)的on_event方法擷取。 |
stop | | 停止語音辨識,阻塞到服務將收到的音頻都識別後結束任務。 |
get_last_request_id | | 擷取request_id,在建構函式調用(建立對象)後可以使用。 |
get_first_package_delay | | 擷取首包延遲,從發送第一包音頻到收到首包識別結果延遲,在任務完成後使用。 |
get_last_package_delay | | 獲得尾包延遲,發送 |
get_response | | 擷取最後一次報文,可以用於擷取task-failed報錯。 |
回調介面(RecognitionCallback)
雙向流式調用時,服務端會通過回調的方式,將關鍵流程資訊和資料返回給用戶端。您需要實現回調方法,處理服務端返回的資訊或者資料。
class Callback(RecognitionCallback):
def on_open(self) -> None:
print('串連成功')
def on_event(self, result: RecognitionResult) -> None:
# 實現接收識別結果的邏輯
pass
def on_complete(self) -> None:
print('任務完成')
def on_error(self, result: RecognitionResult) -> None:
print('出現異常:', result)
def on_close(self) -> None:
print('串連關閉')
callback = Callback()
| 方法 | 參數 | 傳回值 | 描述 |
|---|---|---|---|
| 無 | 無 | 當和服務端建立串連完成後,該方法立刻被回調。 |
|
| 無 | 當服務有回複時會被回調。 |
| 無 | 無 | 當所有識別結果全部返回後進行回調。 |
|
| 無 | 發生異常時該方法被回調。 |
| 無 | 無 | 當服務已經關閉串連後進行回調。 |
響應結果
識別結果(RecognitionResult)
RecognitionResult代表雙向流式調用中一次即時識別或非流式調用的識別結果。
| 成員方法 | 方法簽名 | 說明 |
|---|---|---|
get_sentence | | 擷取當前識別的句子及時間戳記資訊。回調中返回的是單句資訊,所以此方法傳回型別為Dict[str, Any]。 詳情請參見單句資訊(Sentence)。 |
get_request_id | | 擷取請求的request_id。 |
is_sentence_end | | 判斷給定句子是否已經結束。該方法通過檢查 |
單句資訊(Sentence)
Sentence類成員如下:
| 參數 | 類型 | 說明 |
|---|---|---|
begin_time | int | 句子開始時間,單位為ms。 |
end_time | int | 句子結束時間,單位為ms。 |
text | str | 識別文本。 |
words | 字時間戳記資訊(Word)的list集合 | 字時間戳記資訊。 |
字時間戳記資訊(Word)
Word類成員如下:
| 參數 | 類型 | 說明 |
|---|---|---|
begin_time | int | 字開始時間,單位為ms。 |
end_time | int | 字結束時間,單位為ms。 |
text | str | 字。 |
punctuation | str | 標點。 |
錯誤碼
如遇報錯問題,請參見錯誤碼進行排查。
若問題仍未解決,請加入開發人員群反饋遇到的問題,並提供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.opus
Q:如何識別本地檔案(錄音檔案)?
識別本地檔案有兩種方式:
-
直接傳入本地檔案路徑:此種方式在最終識別結束後擷取完整識別結果,不適合即時反饋的情境。
參見非流式調用,在Recognition類的
call方法中傳入檔案路徑對錄音檔案直接進行識別。 -
將本地檔案轉成二進位流進行識別:此種方式一邊識別檔案一邊流式擷取識別結果,適合即時反饋的情境。
參見雙向流式調用,通過Recognition類的
send_audio_frame方法向服務端發送二進位流對其進行識別。
故障排查
Q:無法識別語音(無識別結果)是什麼原因?
-
請檢查請求參數中的音頻格式(
format)和採樣率(sampleRate/sample_rate)設定是否正確且符合參數約束。以下為常見錯誤樣本:- 音頻副檔名為 .wav,但實際為 MP3 格式,而請求參數
format設定為 mp3(參數設定錯誤)。 - 音頻採樣率為 3600Hz,但請求參數
sampleRate/sample_rate設定為 48000(參數設定錯誤)。
可以使用ffprobe工具擷取音訊容器、編碼、採樣率、聲道等資訊:
- 音頻副檔名為 .wav,但實際為 MP3 格式,而請求參數
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
- 若以上檢查均無問題,可通過定製熱詞提升對特定詞語的識別效果。