在鸿蒙系统应用中,我们如何实现语音播报的效果呢?简单的思路就是将文字转成语音,一下便是鸿蒙当中实现的代码步骤,文章最后附上了封装好的参考代码。
初始化
function createByCallback() {
// 设置创建引擎参数
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) {
Logger.info('Succeeded in creating engine.');
// 接收创建引擎的实例
ttsEngine = textToSpeechEngine;
} else {
// 创建引擎失败时返回错误码1003400005,可能原因:引擎不存在、资源不存在、创建引擎超时
Logger.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
}
export function InitSpeech(){
createByCallback()
}
//调用初始化
InitSpeech()
开始播放
// 调用speak播报方法
// 未初始化引擎时调用speak方法,返回错误码1003400007,合成及播报失败
function speak(textValue: string, req_ID: string, over: SpeechOver) {
let isOverSpeech: boolean = false
let speakListener: textToSpeech.SpeakListener = {
// 开始播报回调
onStart(requestId: string, response: textToSpeech.StartResponse) {
Logger.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
// !!!合成播报和完成播报后都会触发回调,需要加判断播报结束
if (!isOverSpeech) {
isOverSpeech = !isOverSpeech
} else {
ttsEngine.shutdown()
isOverSpeech = !isOverSpeech
let callBack = over.callBack
callBack()
}
Logger.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 停止播报完成回调,调用stop方法并完成时会触发此回调
onStop(requestId: string, response: textToSpeech.StopResponse) {
Logger.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 返回音频流
onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
Logger.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
},
// 错误回调,播报过程发生错误时触发此回调
onError(requestId: string, errorCode: number, errorMessage: string) {
Logger.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
}
};
// 设置回调
ttsEngine.setListener(speakListener);
// 设置播报相关参数
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: req_ID, // requestId在同一实例内仅能用一次,请勿重复设置
extraParams: extraParam
};
// 调用speak播报方法
ttsEngine.speak(textValue, speakParams);
};
export function TextToSpeech(inputText: string, over: SpeechOver) {
inputValueIdx = inputValueIdx++
createByCallback()
speak(inputText, inputValueIdx.toString(), over)
}
export interface SpeechOver {
callBack: () => void
}
取消播放
export function StopSpeech() {
if (ttsEngine.isBusy()) {
ttsEngine.stop()
ttsEngine.shutdown()
}
}
StopSpeech()
参考代码:
import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
import Logger from './Logger';
let ttsEngine: textToSpeech.TextToSpeechEngine;
let inputValueIdx: number = 0; //
function createByCallback() {
// 设置创建引擎参数
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) {
Logger.info('Succeeded in creating engine.');
// 接收创建引擎的实例
ttsEngine = textToSpeechEngine;
} else {
// 创建引擎失败时返回错误码1003400005,可能原因:引擎不存在、资源不存在、创建引擎超时
Logger.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
}
// 调用speak播报方法
// 未初始化引擎时调用speak方法,返回错误码1003400007,合成及播报失败
function speak(textValue: string, req_ID: string, over: SpeechOver) {
let isOverSpeech: boolean = false
let speakListener: textToSpeech.SpeakListener = {
// 开始播报回调
onStart(requestId: string, response: textToSpeech.StartResponse) {
Logger.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
// !!!合成播报和完成播报后都会触发回调,需要加判断播报结束
if (!isOverSpeech) {
isOverSpeech = !isOverSpeech
} else {
ttsEngine.shutdown()
isOverSpeech = !isOverSpeech
let callBack = over.callBack
callBack()
}
Logger.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 停止播报完成回调,调用stop方法并完成时会触发此回调
onStop(requestId: string, response: textToSpeech.StopResponse) {
Logger.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 返回音频流
onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
Logger.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
},
// 错误回调,播报过程发生错误时触发此回调
onError(requestId: string, errorCode: number, errorMessage: string) {
Logger.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
}
};
// 设置回调
ttsEngine.setListener(speakListener);
// 设置播报相关参数
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: req_ID, // requestId在同一实例内仅能用一次,请勿重复设置
extraParams: extraParam
};
// 调用speak播报方法
ttsEngine.speak(textValue, speakParams);
};
export function InitSpeech(){
createByCallback()
}
export function TextToSpeech(inputText: string, over: SpeechOver) {
inputValueIdx = inputValueIdx++
createByCallback()
speak(inputText, inputValueIdx.toString(), over)
}
export function StopSpeech() {
if (ttsEngine.isBusy()) {
ttsEngine.stop()
ttsEngine.shutdown()
}
}
export interface SpeechOver {
callBack: () => void
}