使用Qwen-Audio-3.0-Realtime即時語音對話HarmonyOS SDK,實現即時音訊輸入以及語音或文字輸出。
使用者指南:關於模型介紹和選型建議請參見即時語音對話。
快速開始
- 取得與設定 API Key
-
下載 SDK 並執行範例程式碼:
- 下載最新 SDK 整合包。
- 解壓縮
.tar.gz格式的 SDK 整合包。在entry/libs目錄中獲取 HAR 格式 SDK,並新增至專案相依性。需要 C++ 接入時,使用整合包內的native/libs與native/include獲取動態連結庫和標頭檔。 - 用 DevEco Studio 開啟工程。範例程式碼位於
DashQwenAudioChatPage.ets,替換 API Key 後體驗功能。
呼叫步驟
- 初始化 SDK
- 按業務需求設定參數:透過 initialize 介面的
parameters參數設定 連線與控制參數;透過 setParams 介面設定 語音對話效果參數。 - 呼叫 startDialog 啟動對話流程。
- 在 onNuiAudioStateChanged 回呼中,根據音訊狀態開啟錄音裝置。
- 在 onNuiNeedAudioData 回呼中持續提供錄音資料,或者透過 updateAudio 持續推送錄音資料。
- 在 onNuiAssistEventCallback 回呼中持續取得 AI 傳回的語音資料。
- 在 onNuiEventCallback 回呼中監聽事件並取得事件資訊。
- 呼叫 stopDialog 停止對話,並透過監聽 EVENT_TRANSCRIBER_COMPLETE 事件確認對話已結束。
- 當對話功能不再使用時,呼叫 release 介面釋放 SDK 資源。
音訊裝置管理
與 Android 使用 AudioRecord / AudioTrack 不同,HarmonyOS 透過 @kit.AudioKit 提供音訊採集與播放能力,分別使用 AudioCapturer(錄音)和 AudioRenderer(播放)。本產品範例已封裝為 AudioRecorder.ets 與 AudioPlayer.ets 兩個工具類別,可直接複用。
錄音(AudioCapturer)
- 建立:透過
audio.createAudioCapturer(capturerOptions)非同步建立,取樣率固定 16kHz、16bit、單聲道(SAMPLE_RATE_16000/CHANNEL_1/SAMPLE_FORMAT_S16LE/ENCODING_TYPE_RAW)。 - 音源(
audio.SourceType):SOURCE_TYPE_MIC:麥克風原始音源,用於開啟 SDK 內部 AEC 時使用(資料經updateAudio送至 SDK)。SOURCE_TYPE_VOICE_COMMUNICATION:通話音源,系統採集時已做回音消除,用於關閉 SDK 內部 AEC 時使用(音訊經onNuiNeedAudioData拉取)。
- 資料事件:透過
capturer.on('readData', (buffer: ArrayBuffer) => void)持續獲得錄音資料。 - 狀態事件:透過
capturer.on('stateChange', (state: audio.AudioState) => void)監聽,STATE_RUNNING表示開始錄音,STATE_STOPPED表示停止。 - 控制:
start()開始、stop()停止、release()釋放。
import { audio } from '@kit.AudioKit';
const audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
};
const audioCapturerInfo: audio.AudioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0
};
const options: audio.AudioCapturerOptions = { streamInfo: audioStreamInfo, capturerInfo: audioCapturerInfo };
audio.createAudioCapturer(options).then((capturer) => {
capturer.on('readData', (buffer: ArrayBuffer) => {
// 将录音数据送入SDK
nuiInstance.updateAudio(buffer, false);
});
capturer.start();
});
注意:HarmonyOS 的
AudioCapturer為非同步建立,建立完成後才能呼叫start()。因此不要在STATE_OPEN時新建並立即啟動錄音器——應先建立完畢,再在STATE_OPEN回調中start()(範例在doInit階段建立,onNuiAudioStateChanged階段啟動)。
播放(AudioRenderer)
- 建立:透過
audio.createAudioRenderer(rendererOptions)非同步建立。 - 取樣率:DashScope realtime 合成的語音回答音訊為 24kHz(
AudioPlayer建構時傳入)。 - 資料事件:透過
renderer.on('writeData', (data: ArrayBuffer): audio.AudioDataCallbackResult => ...)拉取待播放音訊,返回AudioDataCallbackResult.VALID表示已填充資料,INVALID表示無資料。 - 狀態事件:透過
renderer.on('stateChange', (state: audio.AudioState) => void)監聽播放入口/結束。 - 控制:
start()開始、stop()停止、pause()暫停(暫停會保留已緩衝資料)。
import { audio } from '@kit.AudioKit';
const audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_24000,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
};
const audioRendererInfo: audio.AudioRendererInfo = {
usage: audio.StreamUsage.STREAM_USAGE_VOICE_ASSISTANT,
rendererFlags: 0
};
const options: audio.AudioRendererOptions = { streamInfo: audioStreamInfo, rendererInfo: audioRendererInfo };
audio.createAudioRenderer(options, (err, renderer) => {
renderer.on('writeData', (data: ArrayBuffer): audio.AudioDataCallbackResult => {
// 从队列取出AI返回的音频填入data, 返回VALID/INVALID
return audio.AudioDataCallbackResult.VALID;
});
renderer.start();
});
AEC 參考訊號:開啟 SDK 內部 AEC 時,播放器輸出的音訊需作為參考訊號送入 SDK,呼叫
nuiInstance.pushReferenceData(data, false)(對應 AndroidupdateRefAudio)。
權限宣告
使用錄音功能需在 module.json5 中宣告麥克風權限:
{
"requestPermissions": [
{ "name": "ohos.permission.MICROPHONE" }
]
}
請求參數
連線與控制參數
透過在 initialize 介面的 parameters 參數中傳入一個 JSON 字串來設定。
參數範例:以下為 JSON 字串範例,參數未完整列出。請按實際需求在編碼時補充:
{
"url": "wss://dashscope.aliyuncs.com/api-ws/v1/inference",
"apikey": "st-****",
"device_id": "my_device_id",
"service_mode": "1"
}
參數說明
| 參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
|
| 是 | 服務位址:
{WorkspaceId} 替換為真實的Workspace ID。 |
|
| 是 | API Key。 |
|
| 是 | 執行模式。即時語音對話固定為 |
|
| 是 | 用於識別終端使用者的唯一字串,可設為應用程式內使用者 ID 或用戶端產生的裝置唯一識別碼。此 ID 主要用於日誌追蹤和問題排查。 |
audio_update_manually |
| 否 | 是否啟用主動推送音訊資料模式,預設值:"false"。 |
workspace |
| 否 | 當參數 audio_update_manually 設定為 "true" 時,且啟用端側音訊能力(如 AEC、VAD)時,必須設定 workspace,即端側資源檔案儲存的路徑。 |
|
| 否 | 日誌檔案的儲存路徑。此參數僅在呼叫 initialize 介面時將 |
|
| 否 | 是否儲存偵錯用的音訊檔案。音訊檔案儲存於
save_log設為true時生效。同時,debug_path也必須被設定。 |
|
| 否 | 設定日誌檔案的最大位元組數。 |
|
| 否 | 控制透過日誌回呼(
log_track_level與level(透過initialize介面設定)共同決定最終回調的日誌。一條日誌的級別數值必須同時大於或等於log_track_level和level的值,才會被回調。例如,log_track_level設為2 (INFO),level設為3 (WARNING),則只有WARNING及以上級別(數值>=3)的日誌才會被回調。 |
aec_params |
| 否 | 端側 AEC 能力進階參數設定物件。當參數 audio_update_manually 設定為 "true" 時才啟用此設定物件。 |
aec_params.enable_aec |
| 否 | 是否開啟端側 AEC 回音消除能力。 |
aec_params.save_audio |
| 否 | 是否開啟端側 AEC 回音消除模組音訊儲存功能。當 |
aec_params.enable_aec_data_callback |
| 否 | 是否將 AEC 後的資料傳送給使用者,預設為 false;開啟後在 onNuiAssistEventCallback 的 EVENT_AEC_DATA 接收。 |
vad_params |
| 否 | 端側 VAD 能力進階參數設定物件。 |
vad_params.enable_vad |
| 否 | 是否開啟端側 VAD 人聲偵測能力。 |
vad_params.save_audio |
| 否 | 是否開啟端側 VAD 人聲偵測模組音訊儲存功能。 |
語音對話效果參數
透過在 setParams 介面的 params 參數中傳入一個 JSON 字串來設定。
參數範例:以下為 JSON 字串範例,參數未完整列出。請按實際需求在編碼時補充:
{
"service_type": 4,
"nls_config": {
"model": "qwen-audio-3.1-realtime-plus",
"sr_format": "pcm"
}
}
參數說明
| 一級參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
|
| 是 | 語音服務類型。即時語音對話固定為 |
|
| 是 | 語音對話核心設定物件,包含模型選擇、對話效果控制等關鍵參數。 |
|
| 是 | 指定模型名稱。支援 qwen-audio-3.1-realtime-plus、qwen-audio-3.0-realtime-plus 和 qwen-audio-3.0-realtime-flash 系列模型。 |
|
| 是 | 輸入音訊格式。當前僅支援 |
|
| 否 | array 格式的字串,模型輸出模態設定,可選值:
|
nls_config.voice |
| 否 | TTS 音色名稱,3.1 Plus 的預設值為
3.1 Plus 還支援 |
nls_config.enable_speech_emotion |
| 否 | 是否開啟情緒增強功能。開啟後,回覆音色的情緒變化更明顯。預設值: |
nls_config.instructions |
| 否 | 系統指令,用於設定模型的角色身分、回答風格和行為偏好。對整個對話生效。 |
nls_config.max_history_turns |
| 否 | 允許單次請求的最大歷史 QA 輪數。取值範圍為 1-50,預設值為 20。 |
nls_config.tools |
| 否 | array 格式的字串。Function Calling 工具定義清單。配置後模型可根據使用者輸入自主決定是否呼叫工具。 |
nls_config.turn_detection |
| 否 | JSON 物件形式的字串。輪次偵測設定。未設定時則切換為 push-to-talk 模式(手動提交音訊並觸發推理)。否則啟用雙工對話模式。 |
nls_config.turn_detection.type |
| 否 | VAD 類型,可選值:
|
nls_config.turn_detection.threshold | float | 否 | VAD 靈敏度,僅在 server_vad 模式下生效(smart_turn 模式下無效)。值越低,VAD 越靈敏,越容易將微弱聲音(包括背景雜訊)識別為語音;值越高,越不靈敏,需要更清晰、音量更大的語音才能觸發。 |
nls_config.turn_detection.silence_duration_ms |
| 否 | 語音結束後需保持靜音的最短時間(毫秒),僅在 server_vad 模式下生效(smart_turn 模式下無效)。逾時即觸發模型回應。值越低,回應越快,但可能在短暫停顿時誤觸發。 |
nls_config.turn_detection.voiceprint_audio_urls |
| 否 | array 形式的字串。僅在 smart_turn 模式下生效。目標使用者預錄音訊的公網可存取 URL 清單,用於說話人增強。傳入後,模型將在雙工對話中精準鎖定目標說話人,有效忽略旁人聲音與背景雜訊。最多支援 5 個 URL。音訊格式要求:16kHz PCM 或 WAV。 |
關鍵介面
NativeNui
initialize
初始化語音對話 SDK 執行個體。SDK 為單例模式,在呼叫 release 前禁止重複初始化。
此介面會引起阻塞,應在非 UI 執行緒呼叫。
方法簽章public initialize(callback: INativeNuiCallback,
parameters: string,
level: number,
save_log: boolean = false): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 事件和資料回調介面的實作。 |
|
| JSON 字串,包含驗證、連線和偵錯參數。請參見連線與控制參數。 |
|
| 控制 SDK 自身日誌的列印層級。 |
|
| 是否儲存本機日誌。若為 |
setParams
以 JSON 格式設定 語音對話效果參數。在 startDialog 之前呼叫。
方法簽章public setParams(params: string): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
|
startDialog
開始對話。
方法簽章public startDialog(vad_mode: Constants.VadMode, dialog_params: string): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| VAD 模式。固定為 |
|
| 如果 連線與控制參數 的 |
stopDialog
結束對話,呼叫此介面後,伺服器端將返回最終對話結果並結束任務。
方法簽章public stopDialog(): number
cancelDialog
立即結束對話,呼叫此介面後,不等待伺服器端返回最終對話結果就立即結束任務。
方法簽章public cancelDialog(): number
dialogAction
在互動過程中下達對話動作指令,用於更新對話上下文等執行階段行為。
方法簽章public dialogAction(params: string): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| JSON 格式的字串,用於更新對話上下文等執行階段行為。 |
|
| 固定"action"。 |
|
| 具體的執行指令,當前支援"function_call"、"play_start"、"play_over"。
|
|
| 當 |
|
| 事件類型,當
|
|
|
|
|
|
|
context.item參數:
| 參數 | 類型 | 說明 |
|---|---|---|
id |
| 選填。對話項目的唯一識別碼。未傳送時由伺服器端自動產生。若指定的 ID 已存在於對話中,會傳回錯誤。 |
type |
| 必選。對話項類型,可選值:
|
role |
|
|
content | array |
output_text:助手文字輸出,必填欄位 text。 |
call_id |
| ( |
name |
| ( |
arguments |
|
|
output |
| ( |
context.response參數:
| 參數 | 類型 | 說明 |
|---|---|---|
modalities |
| array 格式的字串,模型輸出模態設定,可選值:
|
voice | string | 覆蓋本輪的 TTS 音色。 |
範例:
{
"type": "action",
"command": "function_call",
"context": {
"item": {
"call_id": "call_xxxx",
"output": "{\"city\":\"杭州\",\"condition\":\"晴\",\"temperature\":18}",
"type": "function_call_output"
},
"type": "conversation.item.create"
}
}
{
"type": "action",
"command": "function_call",
"context": {
"response": {
"modalities": [
"text",
"audio"
]
},
"type": "response.create"
}
}
updateAudio
參數 audio_update_manually 設定為 "true" 時,錄音資料不再是透過 onNuiNeedAudioData 填入,而是用此介面主動推送。
方法簽章public updateAudio(data: ArrayBuffer, first_pack: boolean): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 推送的音訊資料(PCM)。 |
|
| 是否為首包。SDK內部會按 |
pushReferenceData(對應Android updateRefAudio)
參數 audio_update_manually 設定為 "true" 時,且啟用了端側 AEC 回音消除能力,則需要用此介面推送播放器播放的音訊資料作為參考訊號。
方法簽章public pushReferenceData(data: ArrayBuffer, first_pack: boolean): number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 推送的音訊資料(PCM)。 |
|
| 是否為首包。SDK內部會按 |
release
釋放 SDK 所有內部資源。此方法呼叫後,SDK 執行個體將變為不可用狀態,如需再次使用,必須重新呼叫 initialize 進行初始化。
方法簽章public release(): number
GetVersion
取得目前 SDK 版本資訊。
方法簽章public GetVersion(): string
傳回值說明
目前 SDK 版本資訊。
INativeNuiCallback:監聽回呼
onNuiEventCallback:監聽事件資訊
方法簽章onNuiEventCallback: (event: Constants.NuiEvent, resultCode: number, arg2: number,
kwsResult: KwsResult, asrResult: AsrResult) => void;
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 回調事件。 |
|
| 僅在出現 |
|
| 保留參數。 |
|
| 語音辨識結果。 |
|
| 語音喚醒功能。無需關注此參數。 |
onNuiAudioStateChanged:監聽音訊狀態
SDK 透過此回調通知何時應該開始或停止錄音。
方法簽章onNuiAudioStateChanged: (state: Constants.AudioState) => void
AudioState 狀態說明
| 狀態 | 說明 |
|---|---|
| 互動啟動,可以開啟錄音裝置進行錄音。 |
| 互動停止,可以停止錄音。 |
| SDK 執行個體已釋放,可以徹底關閉錄音裝置。 |
onNuiAudioRMSChanged:監聽錄音音量
監聽錄音資料的音量,可用於UI顯示。
方法簽章onNuiAudioRMSChanged: (val: number) => number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 錄音資料的音量值。 |
onNuiNeedAudioData:填入待處理音訊資料
開始對話後,該回呼會被連續觸發,需在其中提供待處理的音訊資料。參數 audio_update_manually 設定為 "true" 時可不關注這個回呼。
方法簽章onNuiNeedAudioData: (buffer: ArrayBuffer) => number
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
| 填充的音訊資料。SDK會按 |
實際填入的位元組數。
onNuiAssistEventCallback:輔助資料和資訊結果
此回調用於接收 SDK 內部的輔助事件和相關資料。
方法簽章onNuiAssistEventCallback?: (event: Constants.NuiEvent, info: string, infoLen: number,
data: ArrayBuffer) => void;
參數說明
| 參數 | 類型 | 說明 |
|---|---|---|
|
|
|
|
| 附加資訊,通常為JSON 字串。 |
|
| 附加資訊長度。 |
|
| 附加的二進位資料,例如AI返回的TTS音訊。 |
注意:HarmonyOS中此回調為可選實作(
?),不關注時可不實作。
onNuiLogTrackCallback:監聽追蹤日誌
此回調用於接收 SDK 內部的詳細日誌,方便進行問題定位和偵錯。
onNuiLogTrackCallback: (level: Constants.LogLevel, log: string) => void
NuiEvent:事件類型
HarmonyOS SDK 中事件類型透過 Constants.NuiEvent 列舉定義,以下列出即時語音對話相關的事件:
| 事件 | 說明 |
|---|---|
EVENT_TRANSCRIBER_STARTED | 任務啟動成功。 |
EVENT_VAD_START | 任務啟動後即觸發此事件。不代表偵測到人聲起點。 |
EVENT_VAD_END | 偵測到人聲終點。 |
EVENT_ASR_PARTIAL_RESULT | 語音辨識中間結果。 |
EVENT_ASR_RESULT | 完整的語音辨識結果。 |
EVENT_ASR_ERROR | 語音對話過程中發生錯誤。 |
EVENT_MIC_ERROR | 因連續 2 秒未收到任何音訊資料而觸發。 |
EVENT_SENTENCE_START | 偵測到一句話開始。 |
EVENT_SENTENCE_END | 偵測到一句話結束,此時會返回一句完整的辨識結果。 |
EVENT_TRANSCRIBER_COMPLETE | 語音對話結束。 |
EVENT_AUDIO_TRANSCRIPTION | 音訊模式下的文字字幕增量事件,串流返回字幕片段。 |
EVENT_AUDIO_TRANSCRIPTION_COMPLETED | 音訊模式下的字幕輸出完成事件。 |
EVENT_OTHER_RESULT | 其他未歸類事件資訊,例如 function_call 的返回結果等。 |
EVENT_ASR_TTS_START | AI 開始返回 TTS 資料。 |
EVENT_ASR_TTS_DATA | AI 返回的 TTS 資料。 |
EVENT_ASR_TTS_COMPLETE | AI 返回 TTS 資料結束。 |
EVENT_RESULT_TRANSLATED | 翻譯中間結果。 |
EVENT_RESULT_TRANSLATED_END | 翻譯結果輸出結束。 |
EVENT_AEC_DATA | AEC 回音消除後的音訊資料。 |