前言
Android开发的同学都知道,在Android当中,实现一段文字合成语音播放,可以使用系统提供的对象TextToSpeech来很快的实现,如果不用系统自带的,也可以使用三方提供的,比如讯飞的语音合成等等,总之,实现起来多种多样,那么,在鸿蒙当中,如何实现根据指定的文本进行合成语音合成播放呢,其实也是非常的简单,因为鸿蒙当中也有textToSpeech。
实现步骤
第一步:创建引擎得到文本转语音类
使用系统自带的Api textToSpeech,调用createEngine方法来创建引擎,接收的参数,用来设置创建引擎实例的相关参数,比如配置的语种、模式、音色和风格等。
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需要知道,它在同一实例内仅能用一次,重复设置是不起作用的,如果多次调用,建议每次进行更换,比如用时间戳,随机数等等。
// 调用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即可。
ttsEngine.stop()
关闭引擎,释放引擎资源
// 调用shutdown接口 ttsEngine.shutdown()
语音识别回调
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是以单词方式进行播报。
举例:
"hello[h1] world"
hello使用单词发音,world及后续单词将会逐个字母进行发音。
数字播报策略
格式和以上一样,[nN] (N=0/1/2),N可以选择012三个数字,0是智能判断数字处理策略,默认值为0;1是作为号码逐个数字播报,2是作为数值播报,超过18位数字不支持,自动按逐个数字进行播报。
举例:
"[n2]123[n1]456[n0]"
其中,123将会按照数值播报,456则会按照号码播报,而后的文本中的数字,均会自动判断。
插入静音停顿
格式为[pN],N为无符号整数,单位为ms。
举例:
"你好[p1000]程序员一鸣"
以上的语句播报时,将会在“你好”后插入1000ms的静音停顿。
指定汉字发音
汉字声调用后接一位数字1~5分别表示阴平、阳平、上声、去声和轻声5个声调,格式为:[=MN],其中M表示拼音,N表示声调,取值范围为,1表示阴平,2表示阳平,3表示上声,4表示去声,5表示轻声。
举例:
"着[=zhao2]火"
“着”字将读作“zhaó”。
相关总结
文本合成语音的能力目前只能在真机上进行测试,不支持模拟器。