前言
Android开发的同学都知道,在Android当中,实现一段文字合成语音播放,可以使用系统提供的对象TextToSpeech来很快的实现,如果不用系统自带的,也可以使用三方提供的,比如讯飞的语音合成等等,总之,实现起来多种多样,那么,在鸿蒙当中,如何实现根据指定的文本进行合成语音合成播放呢,其实也是非常的简单,因为鸿蒙当中也有textToSpeech。
实现步骤
第一步:创建引擎得到文本转语音类
使用系统自带的Api textToSpeech,调用createEngine方法来创建引擎,接收的参数,用来设置创建引擎实例的相关参数,比如配置的语种、模式、音色和风格等。
TypeScript
private createTextToSpeech() {
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.');
// 接收创建引擎的实例
this.ttsEngine = textToSpeechEngine;
} else {
console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
})
}
关于参数,需要注重说明一下,首先是language,也就是支持的语言,目前只支持中文,也就是"zh-CN";online字段是支持的模式,0为在线模式,目前不支持;1为离线,当前仅支持离线模式;person,音色,0为聆小珊女声音色,当前仅支持聆小珊女声音色;extraParams为风格设置,比如设置广播风格,是否支持后台播放等。
可以发现,虽然有很多参数,但是目前都仅仅支持一种,基本上固定就行,extraParams中有一个isBackStage,也就是是否支持后台播放,为true时,支持后台播报。
第二步,语音播放
文字合成语音,我们只需要调用speak方法即可,两个参数,第一个是需要合成语音的文本,要求是不超过10000字符的中文文本,这个是重点,第二个是,合成播报音频的相关参数,用于配置语速、音量、音调、合成类型等,其中有一个参数requestId需要知道,它在同一实例内仅能用一次,重复设置是不起作用的,如果多次调用,建议每次进行更换,比如用时间戳,随机数等等。
TypeScript
// 调用speak播报方法
private speak(message:string) {
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)}`);
},
// 停止播报完成回调,调用stop方法并完成时会触发此回调
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}`);
}
};
// 设置回调
this.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: "123456-a", // requestId在同一实例内仅能用一次,请勿重复设置
extraParams: extraParam
}
// 调用speak播报方法
this.ttsEngine?.speak(message, speakParams)
}
停止播放
直接调用stop即可。
TypeScript
ttsEngine.stop()
关闭引擎,释放引擎资源
TypeScript
// 调用shutdown接口
ttsEngine.shutdown()
语音识别回调
TypeScript
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)}`);
},
// 停止播报完成回调,调用stop方法并完成时会触发此回调
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}`);
}
};
// 设置回调
this.ttsEngine?.setListener(speakListener);
播报策略
在不同的场景下,比如停顿,单词连读,数字分开读,等等,不同的场景就会有不同的播放策略。
单词播报方式
文本格式:[hN] (N=0/1/2),首先h是固定的,N可以选择012三个数字,0是智能判断单词播放方式。默认值即为0,1是逐个字母进行播报,2是以单词方式进行播报。
举例:
TypeScript
"hello[h1] world"
hello使用单词发音,world及后续单词将会逐个字母进行发音。
数字播报策略
格式和以上一样,[nN] (N=0/1/2),N可以选择012三个数字,0是智能判断数字处理策略,默认值为0;1是作为号码逐个数字播报,2是作为数值播报,超过18位数字不支持,自动按逐个数字进行播报。
举例:
TypeScript
"[n2]123[n1]456[n0]"
其中,123将会按照数值播报,456则会按照号码播报,而后的文本中的数字,均会自动判断。
插入静音停顿
格式为[pN],N为无符号整数,单位为ms。
举例:
TypeScript
"你好[p1000]程序员一鸣"
以上的语句播报时,将会在"你好"后插入1000ms的静音停顿。
指定汉字发音
汉字声调用后接一位数字1~5分别表示阴平、阳平、上声、去声和轻声5个声调,格式为:[=MN],其中M表示拼音,N表示声调,取值范围为,1表示阴平,2表示阳平,3表示上声,4表示去声,5表示轻声。
举例:
TypeScript
"着[=zhao2]火"
"着"字将读作"zhaó"。
相关总结
文本合成语音的能力目前只能在真机上进行测试,不支持模拟器。