實時語音互動,打造更加智慧便捷的應用

HarmonyOS_SDK發表於2024-09-30

隨著人工智慧和自然語言處理技術的進步,使用者對智慧化和便捷化應用的需求不斷增加。語音互動技術以其直觀的語音指令,革新了傳統的手動輸入方式,簡化了使用者操作,讓應用變得更加易用和高效。

透過語音互動,使用者可以在不方便使用觸屏操作例如駕駛、烹飪時透過語音指令進行操作;在需要輸入大量文字時,透過語音輸入,可以顯著提高資訊輸入的效率;此外,語音互動也為視覺障礙或閱讀困難的使用者提供了一種便捷的替代互動方式。

HarmonyOS SDK 基礎語音服務(Core Speech Kit)整合了語音類基礎AI能力,包括文字轉語音(TextToSpeech)及語音識別(SpeechRecognizer)能力,便於使用者與裝置進行互動,實現將實時輸入的語音與文字之間相互轉換。

文字轉語音

可高效的將一段不超過10000字元的文字合成為可播報的音訊流,將文字轉換成流暢自然的人聲,廣泛適用於有聲閱讀、新聞播報、站廳播報等多個應用場景。

系統無障礙接入文字轉語音能力,在無網狀態下,也可以為視障人士提供普通話播報功能,音色為聆小珊女聲。

image

語音識別

可高效實現將實時語音轉寫成文字,解放雙手,適用於語音聊天、語音搜尋、語音指令、語音問答等多個應用場景。

將一段音訊(時長不超過60s)資訊轉換為文字。語音識別服務提供將音訊資訊轉換為文字的能力,便於使用者與裝置進行互動,實現實時語音互動、語音識別。目前本服務支援的語種為中文,支援離線模型。

image

能力優勢

穩定可靠:端側能力,不依賴網路,穩定可靠。

即開即用:系統原生API,不佔用應用空間,開箱即用。

功能豐富:針對不同場景,提供了豐富的擴充套件和調節引數。

功能演示

image
image

開發步驟

(一) 文字轉語音

1.在使用文字轉語音時,將實現文字轉語音相關的類新增至工程。

import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';

2.呼叫createEngine介面,建立textToSpeechEngine例項。

createEngine介面提供了兩種呼叫形式,當前以其中一種作為示例,其他方式可參考API參考

let ttsEngine: textToSpeech.TextToSpeechEngine;

// 設定建立引擎引數
let extraParam: Record<string, Object> = {"style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName'};
let initParamsInfo: textToSpeech.CreateEngineParams = {
  language: 'zh-CN',
  person: 0,
  online: 1,
  extraParams: extraParam
};

// 呼叫createEngine方法
textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
  if (!err) {
    console.info('Succeeded in creating engine');
    // 接收建立引擎的例項
    ttsEngine = textToSpeechEngine;
  } else {
    // 建立引擎失敗時返回錯誤碼1003400005,可能原因:引擎不存在、資源不存在、建立引擎超時
    console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
  }
});

3.得到TextToSpeechEngine例項物件後,例項化SpeakParams物件、SpeakListener物件,並傳入待合成及播報的文字originalText,呼叫speak介面進行播報。

// 設定speak的回撥資訊
let speakListener: textToSpeech.SpeakListener = {
  // 開始播報回撥
  onStart(requestId: string, response: textToSpeech.StartResponse) {
    console.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
  },
  // 合成完成及播報完成回撥
  onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
    console.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
  },
  // 停止播報回撥
  onStop(requestId: string, response: textToSpeech.StopResponse) {
    console.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
  },
  // 返回音訊流
  onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
    console.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
  },
  // 錯誤回撥
  onError(requestId: string, errorCode: number, errorMessage: string) {
    console.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
  }
};
// 設定回撥
ttsEngine.setListener(speakListener);
let originalText: string = '你好,華為';
// 設定播報相關引數
let extraParam: Record<string, Object> = {"queueMode": 0, "speed": 1, "volume": 2, "pitch": 1, "languageContext": 'zh-CN',  
"audioType": "pcm", "soundChannel": 3, "playType": 1 };
let speakParams: textToSpeech.SpeakParams = {
  requestId: '123456', // requestId在同一例項內僅能用一次,請勿重複設定
  extraParams: extraParam
};
// 呼叫播報方法
ttsEngine.speak(originalText, speakParams);

(二) 語音識別

1.在使用語音識別時,將實現語音識別相關的類新增至工程。

import { speechRecognizer } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';

2.呼叫createEngine方法,對引擎進行初始化,並建立SpeechRecognitionEngine例項。

createEngine方法提供了兩種呼叫形式,當前以其中一種作為示例,其他方式可參考API參考

let asrEngine: speechRecognizer.SpeechRecognitionEngine;
let requestId: string = '123456';
// 建立引擎,透過callback形式返回
// 設定建立引擎引數
let extraParam: Record<string, Object> = {"locate": "CN", "recognizerMode": "short"};
let initParamsInfo: speechRecognizer.CreateEngineParams = {
  language: 'zh-CN',
  online: 1,
  extraParams: extraParam
};
// 呼叫createEngine方法
speechRecognizer.createEngine(initParamsInfo, (err: BusinessError, speechRecognitionEngine: speechRecognizer.SpeechRecognitionEngine) => {
  if (!err) {
    console.info('Succeeded in creating engine.');
    // 接收建立引擎的例項
    asrEngine = speechRecognitionEngine;
  } else {
    // 無法建立引擎時返回錯誤碼1002200008,原因:引擎正在銷燬中
    console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
  }
});

3.得到SpeechRecognitionEngine例項物件後,例項化RecognitionListener物件,呼叫setListener方法設定回撥,用來接收語音識別相關的回撥資訊。

// 建立回撥物件
let setListener: speechRecognizer.RecognitionListener = {
  // 開始識別成功回撥
  onStart(sessionId: string, eventMessage: string) {
    console.info(`onStart, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
  },
  // 事件回撥
  onEvent(sessionId: string, eventCode: number, eventMessage: string) {
    console.info(`onEvent, sessionId: ${sessionId} eventCode: ${eventCode} eventMessage: ${eventMessage}`);
  },
  // 識別結果回撥,包括中間結果和最終結果
  onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {
    console.info(`onResult, sessionId: ${sessionId} sessionId: ${JSON.stringify(result)}`);
  },
  // 識別完成回撥
  onComplete(sessionId: string, eventMessage: string) {
    console.info(`onComplete, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
  },
  // 錯誤回撥,錯誤碼透過本方法返回
  // 如:返回錯誤碼1002200006,識別引擎正忙,引擎正在識別中
  // 更多錯誤碼請參考錯誤碼參考
  onError(sessionId: string, errorCode: number, errorMessage: string) {
    console.error(`onError, sessionId: ${sessionId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
  }
}
// 設定回撥
asrEngine.setListener(setListener);

4.設定開始識別的相關引數,呼叫startListening方法,開始合成。

let audioParam: speechRecognizer.AudioInfo = {audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16};
let extraParam: Record<string, Object> = {"vadBegin": 2000, "vadEnd": 3000, "maxAudioDuration": 40000};
let recognizerParams: speechRecognizer.StartParams = {
  sessionId: requestId,
  audioInfo: audioParam,
  extraParams: extraParam
};
// 呼叫開始識別方法
asrEngine.startListening(recognizerParams);

5.傳入音訊流,呼叫writeAudio方法,開始寫入音訊流。讀取音訊檔案時,開發者需預先準備一個pcm格式音訊檔案。

let uint8Array: Uint8Array = new Uint8Array();
// 可以透過如下方式獲取音訊流:1、透過錄音獲取音訊流;2、從音訊檔案中讀取音訊流
// 寫入音訊流,音訊流長度僅支援640或1280
asrEngine.writeAudio(requestId, uint8Array);

瞭解更多詳情>>

訪問基礎語音服務聯盟官網

獲取文字轉語音服務開發指導文件

獲取語音識別服務開發指導文件

相關文章