关于文字转语音的操作
先上代码,然后我再详细说说遇到的坑点
写一个工具类
export class Text2VioceUtils {}起名Text2VioceUtils
首先你要文字转语音你需要一个鸿蒙提供的引擎来做这个事情
static Text2VioceEngine: textToSpeech.TextToSpeechEngine
然后textToSpeech包下边有个函数createEngine
这个函数有个参数,类型是CreateEngineParams,就是创建引擎时候需要给引擎配置的参数返回值是Promise,这个应该不陌生,在我之前写的文章里有介绍,看见promiss就知道这个是个异步,你需要在前面加个await等待,函数名前对应加async ,你用一个变量去接收他 返回值就是这个引擎,再说createEngine函数,他有个重载函数就是CreateEngineParams参数后边有个回调函数类型是AsyncCallback ,这个类型AsyncCallback<T, E = void>有俩返回值,默认有个BusinessError就是报错的信息,另一个就是咱们用到的TextToSpeechEngine,都是大同小异,写法不同而已,你可以在外卖定义一个回调函数//static callback: AsyncCallback<textToSpeech.TextToSpeechEngine>,在创建引擎的之前去把你的回调函数赋值,然后创建的时候把你定义的回调函数填进去,也可以直接写在创建函数里面,都是一样的,看你想怎么写,下面的写法是鸿蒙官方给的示例写法
textToSpeech.createEngine(Text2VioceUtils.initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
if (!err) {
console.info('Succeeded in creating engine');
// 接收创建引擎的实例
Text2VioceUtils.Text2VioceEngine = textToSpeechEngine;
} else {
// 创建引擎失败时返回错误码1003400005,可能原因:引擎不存在、资源不存在、创建引擎超时
console.error(Failed to create engine. Code: ${err.code}, message: ${err.message}.
);
}
});
这里我就遇到了之前上文中提到的坑点,说我接收到的引擎是一个undefined
报错信息如下
Error message:Cannot read property createEngine of undefined
按照我写c#的思维逻辑,就是返回的是个null,意思是你没创建引擎成功,因为你在定义的时候你没给你定义的变量赋值,所以是null,然后我就在定义的地方加了一个?,我还是先不把这个奇怪的地方先说了,先记住这个undefined,我还是先说代码好了。
创建引擎的参数CreateEngineParams 目前只支持离线版 online是1,
static initParamsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN',
person: 0,
online: 1,
extraParams: Text2VioceUtils.extraParam
};
extraParams这个参数可写可不写因为他带个?这里就不多说了直接赋值粘贴因为官网上也没说啥意思
{"style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName'}
创建好了以后需要注册一些回调方法
//设置speak的回调
let speaklistener: textToSpeech.SpeakListener = {
// 开始播报回调
onStart(requestId: string, response: textToSpeech.StartResponse) {
},
// 合成完成及播报完成回调
onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
},
// 停止播报回调
onStop(requestId: string, response: textToSpeech.StopResponse) {
},
// 返回音频流
onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
},
// 错误回调
onError(requestId: string, errorCode: number, errorMessage: string) {
}
}
//绑定
Text2VioceUtils.Text2VioceEngine.setListener(speaklistener)
把回调函数绑定上,然后就可以播放了
// 调用播报方法
Text2VioceUtils.Text2VioceEngine.speak(originalText, Text2VioceUtils.speakParams);
播放有两个参数一个是你的文本内容,一个是SpeakParams 语音播放的参数,主要是什么语速啊,音量啊,声音类型啊(pcm)这些配置
static extraParam1: Record<string, Object> = {"queueMode": 0, "speed": 1, "volume": 2, "pitch": 1, "languageContext": 'zh-CN',
"audioType": "pcm", "soundChannel": 3, "playType": 1 };
static speakParams: textToSpeech.SpeakParams = {
requestId: util.generateRandomUUID(), // requestId在同一实例内仅能用一次,请勿重复设置
extraParams: Text2VioceUtils.extraParam1
};
这些代码就可以了,足够跑起来的了,如果关掉,或者正在播放时候你再转语音他会有繁忙,都会有对应的参数,比如shutdown,isbusy等
那我就开始说坑点了,别看代码少,md有问题!我之前不说是有个报错undefined么,在创建的时候报错一下,我就把获取到引擎调用的地方都加了?,报错没有了,app也不会闪退了,然后我debug看了下,引擎还是没有创建出来依旧是undefined,我就把加?的地方都撤回了,结果就speak函数的地方有undefined报错,我以为这回是创建好了,打断点,依旧没创建,没创建你干嘛不给我闪退报错呢。我怀疑是有缓存,随即清理项目,依旧没改变,然后我就怀疑是模拟器的问题,不是真机的话开发起来难度真的不小,代码写的真不知道对错,随机用官方给的代码跑一边,也是undefined报错,然后我就确定了,肯定不是我代码的错。官方代码跑模拟器也报错,随即释怀了,不用再去纠结了。最后总结一句话:作为程序,你要相信自己写的代码。再一句话,mate50pro调试不了真机,连官方提供的tesing都tm链接不上,sdk是5.0以上的,这对想转行学next代价有点太大了。不仅要买个新手机,还要多掉好多头发