了解即時語音合成HarmonyOS SDK的整合方法、參數、介面、回呼和範例程式碼。
NativeNui
HarmonyOS SDK透過 NativeNui 提供串流文字語音合成能力。
- 透過
new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS)建立串流文字語音合成執行個體。NativeNui.GetInstance()返回的是MODE_DIALOG對話模式單例,不能用於串流文字語音合成。 - 串流文字語音合成模式無需呼叫
initialize()。憑證和合成參數由startStreamInputTts()、playStreamInputTts()或asyncPlayStreamInputTts()直接傳入。 - 透過
INativeStreamInputTtsCallback接收合成事件和音訊資料。 - 合成任務開始時返回
STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED,音訊資料透過onStreamInputTtsDataCallback返回,任務結束時返回STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE,合成出錯時返回STREAM_INPUT_TTS_EVENT_TASK_FAILED。
import { Constants, INativeStreamInputTtsCallback, NativeNui, StreamInputTtsEvent } from 'neonui';
const nuiInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
呼叫流程
Qwen-Audio-TTS支援一次性輸入和串流輸入兩種呼叫方式。
一次性輸入:適用於短文字合成或需要使用SSML的場景。
- 呼叫
playStreamInputTts或asyncPlayStreamInputTts,直接傳入完整文字並開始合成。前者同步阻塞,後者立即返回並在背景合成。無需先呼叫startStreamInputTts,也無需再呼叫停止介面。 - 在
onStreamInputTtsDataCallback中接收音訊資料。 - 收到
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE後,合成結束。
串流輸入:適用於即時對話或長文字邊輸入邊合成的場景。該方式不支援SSML。
- 呼叫
startStreamInputTts建立連線並設定回呼和參數。 - 呼叫
sendStreamInputTts持續傳送文字片段。 - 在
onStreamInputTtsDataCallback中接收音訊資料。 - 文字傳送完畢後,呼叫
stopStreamInputTts結束傳送。 - 收到
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE後,合成結束。
不再使用語音合成功能時,呼叫 releaseStreamInputTts 釋放資源。
單次文字長度和多次累計文字長度均有限制,參見Qwen-Audio-TTS WebSocket API。
startStreamInputTts
啟動雙向串流語音合成,建立連線並註冊回呼。該介面可能阻塞,請勿在UI執行緒呼叫。
startStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
session_id: string,
log_level: number,
save_log: boolean
): number
| 參數 | 類型 | 說明 |
|---|---|---|
callback | INativeStreamInputTtsCallback | 事件和音訊資料回呼。 |
ticket | string | 鑑權、連線和偵錯參數的JSON字串。 |
parameters | string | 語音合成參數的JSON字串。 |
session_id | string | 用戶端指定的工作階段ID。傳入空字串時由伺服器端產生。 |
log_level | number | SDK日誌層級,可使用 Constants.LogLevel 列舉值。取值:0(VERBOSE)、1(DEBUG)、2(INFO)、3(WARNING)、4(ERROR)、5(NONE)。 |
save_log | boolean | 是否儲存本機日誌。設為 true 時必須在 ticket 中設定 debug_path。 |
返回錯誤碼,Constants.NuiResultCode.SUCCESS(0)表示成功。
ticket參數
{
"url": "wss://dashscope.aliyuncs.com/api-ws/v1/inference",
"apikey": "st-****",
"device_id": "my_device_id"
}
| 參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
url | string | 是 | 服務位址。可使用公用位址 wss://dashscope.aliyuncs.com/api-ws/v1/inference,或業務空間專屬位址 wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/inference(北京)和 wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference(新加坡)。將 {WorkspaceId} 替換為真實的業務空間 ID。 |
apikey | string | 是 | API Key。建議使用臨時API Key,以降低長期有效Key外洩的風險。 |
device_id | string | 是 | 終端使用者的唯一識別碼,可使用應用程式內使用者 ID 或用戶端產生的裝置識別碼,主要用於記錄追蹤和問題排查。 |
complete_waiting_ms | number | 否 | 呼叫 stopStreamInputTts(false) 後等待合成完成事件的逾時時間(毫秒),預設值為 10000。 |
debug_path | string | 否 | 記錄檔目錄。僅當 save_log 為 true 時生效,此時必須設定。SDK 最多保留兩個記錄檔。 |
max_log_file_size | number | 否 | 單一記錄檔的最大位元組數。預設值為 104857600(100 MiB),僅當 save_log 為 true 時生效。 |
log_track_level | number | 否 | SDK內部追蹤日誌過濾層級,預設值為 2。取值與 log_level 相同。HarmonyOS回呼介面目前未開放串流TTS日誌回呼,過濾後的日誌僅在SDK內部輸出。 |
parameters參數
{
"model": "qwen-audio-3.0-tts-flash",
"voice": "longanlingxi",
"format": "mp3",
"sample_rate": 24000,
"volume": 50,
"rate": 1.0,
"pitch": 1.0,
"enable_audio_decoder": true
}
| 參數 | 類型 | 是否必須 | 說明 |
|---|---|---|---|
model | string | 是 | 模型名稱。參見語音合成模型。 |
voice | string | 是 | 音色。系統音色參見Qwen-Audio-TTS音色列表;也可使用聲音複製或聲音設計產生的音色。 |
format | string | 否 | 音訊編碼格式,取值為 pcm、wav、mp3(預設)或 opus。 |
enable_audio_decoder | boolean | 否 | 是否啟用SDK內部解碼器,預設值為 false。當格式為MP3或Opus時,設為 true 可將音訊解碼為PCM後再透過資料回呼返回。 |
volume | number | 否 | 音量,預設值為 50,取值範圍為 [0, 100]。 |
sample_rate | number | 否 | 取樣率(Hz),支援 8000、16000、22050(預設)、24000、44100、48000。 |
rate | number | 否 | 語速,預設值為 1.0,取值範圍為 [0.5, 2.0]。 |
pitch | number | 否 | 音調,預設值為 1.0,取值範圍為 [0.5, 2.0]。 |
bit_rate | number | 否 | MP3或Opus位元率(kbps),預設值為 32,取值範圍為 [6, 510]。 |
enable_ssml | boolean | 否 | 是否啟用SSML,預設值為 false。支援範圍參見SSML使用限制。 |
word_timestamp_enabled | boolean | 否 | 是否返回字級時間戳記,預設值為 false,僅在串流輸出模式下可用。支援複製音色;支援的系統音色請參見Qwen-Audio-TTS音色列表。時間戳記結果位於 INativeStreamInputTtsCallback 的 all_response 中。 |
seed | number | 否 | 生成時使用的隨機數種子,可改變合成效果。在模型版本、文字、音色和其他參數均相同時,使用相同的 seed 可重現相同的合成結果。預設值為 0,取值範圍為 [0, 65535]。 |
language_hints | string[] | 否 | 指定語音合成的目標語言,以提升合成效果。此設定與聲音復刻時範例音訊的語種無關;如需設定復刻任務的來源語言,請參見聲音復刻API參考。目前版本僅處理陣列的第一個元素,建議只傳一個值。當數字、縮寫、符號的朗讀方式或小語種合成效果不符合預期時,可設定此參數。例如,將 "hello, this is 110" 按英語讀作「one one zero」而不是中文「么么零」,或將 @ 讀作「at」而不是「艾特」。取值範圍 支援 |
instruction | string | 否 | 控制方言、情感或角色等效果的指令,參見指令控制。 |
enable_aigc_tag | boolean | 否 | 是否嵌入AIGC隱性標識,預設值為 false。 |
aigc_propagator | string | 否 | AIGC標識的 ContentPropagator 欄位,僅在 enable_aigc_tag 為 true 時生效。預設值為阿里雲UID。支援範圍與 enable_aigc_tag 相同。 |
aigc_propagate_id | string | 否 | AIGC標識的 PropagateID 欄位,僅在 enable_aigc_tag 為 true 時生效。預設值為目前請求ID。支援範圍與 enable_aigc_tag 相同。 |
hot_fix | object | 否 | 文字熱修復設定,用於自訂發音或替換文字。格式參見用戶端事件。 |
sendStreamInputTts
sendStreamInputTts(text: string): number
在 startStreamInputTts 成功後傳送待合成的文字片段。該介面不解析SSML標籤。全部文字傳送完成後,呼叫 stopStreamInputTts()。
| 參數 | 類型 | 說明 |
|---|---|---|
text | string | 待合成文字。不支援SSML;SSML標籤會被當作一般文字朗讀。 |
傳回錯誤碼。
stopStreamInputTts
stopStreamInputTts(flag_async: boolean = true): number
結束本輪串流輸入。
true(預設):非同步結束,呼叫後立即返回,透過STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE判斷合成完成。false:同步阻塞,等待全部音訊和合成完成事件。等待時間由complete_waiting_ms控制。
使用同步停止後再呼叫取消介面可能造成阻塞,建議使用預設的非同步方式。
| 參數 | 類型 | 說明 |
|---|---|---|
flag_async | boolean | 是否非同步結束,預設值為 true。設為 true 時不阻塞等待伺服器回應;設為 false 時同步阻塞,等待合成完成。 |
傳回錯誤碼。
cancelStreamInputTts
cancelStreamInputTts(): number
立即中斷連線並終止目前合成任務。呼叫後不會再收到任何音訊資料回呼。返回錯誤碼。
cancelStreamInputTtsKeepConnection
cancelStreamInputTtsKeepConnection(): number
傳送協定層取消指令,取消目前合成任務但保持WebSocket連線,適用於需要立即開始下一輪合成的場景,可省去重新建立連線的開銷。返回錯誤碼。
playStreamInputTts
playStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
text: string,
session_id: string,
log_level: number,
save_log: boolean
): number
同步的一次性合成介面。該介面獨立完成初始化、傳送文字和接收音訊,合成完成後才返回,無需先呼叫 startStreamInputTts,也無需呼叫停止介面。該介面預設啟用SSML;如果顯式設定 enable_ssml,則以設定值為準。請勿在UI執行緒呼叫。
callback、ticket、parameters、session_id、log_level 和 save_log 與 startStreamInputTts 中的定義相同。text 為待合成文字,支援SSML。返回錯誤碼。
asyncPlayStreamInputTts
asyncPlayStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
text: string,
session_id: string,
log_level: number,
save_log: boolean
): number
非同步的一次性合成介面。呼叫後立即返回,結果透過回呼返回。無需先呼叫 startStreamInputTts,也無需呼叫停止介面。該介面預設啟用SSML;如果顯式設定 enable_ssml,則以設定值為準。
callback、ticket、parameters、session_id、log_level 和 save_log 與 startStreamInputTts 中的定義相同。text 為待合成文字,支援SSML。返回錯誤碼。
releaseStreamInputTts
releaseStreamInputTts(): number
釋放串流TTS執行個體及其佔用的資源。建議在頁面銷毀或不再使用語音合成功能時呼叫。返回錯誤碼。
INativeStreamInputTtsCallback
export interface INativeStreamInputTtsCallback {
onStreamInputTtsEventCallback(
event: StreamInputTtsEvent,
task_id: string,
session_id: string,
ret_code: number,
error_msg: string,
timestamp: string,
all_response: string
): void;
onStreamInputTtsDataCallback(data: ArrayBuffer | null): void;
}
onStreamInputTtsEventCallback
| 參數 | 類型 | 說明 |
|---|---|---|
event | StreamInputTtsEvent | 合成事件。 |
task_id | string | 合成任務ID。 |
session_id | string | 工作階段ID。用戶端傳入時原樣返回,否則由伺服器產生。 |
ret_code | number | 錯誤碼,僅任務失敗事件有效。 |
error_msg | string | 錯誤訊息,僅任務失敗事件有效。 |
timestamp | string | 時間戳記結果。 |
all_response | string | 伺服器完整JSON回應,可用於取得用量、時間戳記和錯誤詳細資料。 |
onStreamInputTtsDataCallback
onStreamInputTtsDataCallback(data: ArrayBuffer | null): void;
連續返回音訊片段。處理時需注意:
- MP3和Opus壓縮資料應使用支援串流解碼的播放器,或將
enable_audio_decoder設為true,由SDK解碼為PCM。 - 組裝完整檔案時,應按回呼順序附加資料。
- WAV和MP3僅首個回呼包含檔案標頭;Opus的每一幀為獨立Ogg page,可按順序拼接。
StreamInputTtsEvent
| 事件 | 說明 |
|---|---|
STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED | 伺服器已成功接收請求並開始處理。通常在該事件後,onStreamInputTtsDataCallback 很快會返回第一批音訊資料。 |
STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN | 伺服器開始合成一句文字。 |
STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS | 合成過程資訊,包括計費資訊和時間戳記等。 |
STREAM_INPUT_TTS_EVENT_SENTENCE_END | 伺服器已完成一句文字的合成。 |
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE | 伺服器已返回全部音訊資料,此後不會再呼叫 onStreamInputTtsEventCallback,是資料流結束的明確訊號。該事件不表示本機播放器已經播放完成。 |
STREAM_INPUT_TTS_EVENT_TASK_FAILED | 合成失敗,可從 all_response 取得 task_id、error_code 和 error_message,也可透過回呼參數 ret_code 和 error_msg 取得錯誤訊息。 |
任務失敗回應範例:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "task-failed",
"error_code": "InvalidParameter",
"error_message": "[tts:]Engine return error code: 418",
"attributes": {}
},
"payload": {}
}
範例程式碼
- 取得與設定 API Key。端側應用程式請勿硬式編碼長期有效的 API Key。建議由自建伺服器端取得臨時 API Key,再下發至端側。
- 下載最新 SDK 整合包,解壓縮後將
entry/libs/neonui.har複製到應用程式專案的entry/libs目錄,並在entry/oh-package.json5中新增相依性:
{
"dependencies": {
"neonui": "file:libs/neonui.har"
}
}
- 使用 DevEco Studio 開啟整合包中的範例專案。範例頁面位於
entry/src/main/ets/pages/dashscope/DashCosyVoiceStreamTtsPage.ets。設定API Key後即可執行。
以下範例展示串流輸入的核心流程。音訊播放、參數選擇和任務狀態管理的完整實作,請參考整合包中的 DashCosyVoiceStreamTtsPage.ets。
import { Constants, INativeStreamInputTtsCallback, NativeNui, StreamInputTtsEvent } from 'neonui';
const callback: INativeStreamInputTtsCallback = {
onStreamInputTtsEventCallback: (event: StreamInputTtsEvent, taskId: string,
sessionId: string, retCode: number, errorMsg: string,
timestamp: string, allResponse: string): void => {
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE) {
// 合成完成。
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
// 根据retCode、errorMsg或allResponse处理错误。
}
},
onStreamInputTtsDataCallback: (data: ArrayBuffer | null): void => {
if (data != null) {
// 将PCM数据写入AudioRenderer,或按顺序保存编码音频数据。
}
}
};
const nuiInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
const ticket: Record<string, Object> = {
'url': 'wss://dashscope.aliyuncs.com/api-ws/v1/inference',
'apikey': 'st-****',
'device_id': 'my_device_id'
};
const parameters: Record<string, Object> = {
'model': 'qwen-audio-3.0-tts-flash',
'voice': 'longanlingxi',
'format': 'mp3',
'sample_rate': 24000,
'enable_audio_decoder': true
};
const result = nuiInstance.startStreamInputTts(
callback,
JSON.stringify(ticket),
JSON.stringify(parameters),
'',
Constants.LogLevel.LOG_LEVEL_INFO,
false
);
if (result == Constants.NuiResultCode.SUCCESS) {
nuiInstance.sendStreamInputTts('你好,');
nuiInstance.sendStreamInputTts('欢迎使用实时语音合成。');
nuiInstance.stopStreamInputTts(true);
}
// 在SYNTHESIS_COMPLETE的处理逻辑中调用nuiInstance.releaseStreamInputTts()。
一次性輸入時,直接呼叫 playStreamInputTts 或 asyncPlayStreamInputTts:
const oneShotInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
oneShotInstance.asyncPlayStreamInputTts(
callback,
JSON.stringify(ticket),
JSON.stringify(parameters),
'你好,欢迎使用实时语音合成。',
'',
Constants.LogLevel.LOG_LEVEL_INFO,
false
);
// 在SYNTHESIS_COMPLETE的处理逻辑中调用oneShotInstance.releaseStreamInputTts()。
進階功能
SSML標記語言
目的:透過在文字中嵌入XML標籤,控制發音、語速和停頓等合成細節。
使用限制:僅一次性輸入介面 playStreamInputTts 和 asyncPlayStreamInputTts 支援SSML;串流輸入介面 sendStreamInputTts 不支援。
使用方法:呼叫 playStreamInputTts 或 asyncPlayStreamInputTts 時,SDK預設啟用SSML,直接在 text 中傳入包含SSML標籤的文字。更多資訊,請參見SSML與LaTeX。
數學運算式
目的:使模型能夠正確朗讀常見的數學公式和運算式。
使用方法:在 text 中傳入包含LaTeX格式數學運算式的文字。支援範圍和寫法,請參見LaTeX公式轉語音。