鸿蒙开发:文本合成语音

前言

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ó"。

相关总结

文本合成语音的能力目前只能在真机上进行测试,不支持模拟器。

相关推荐
nashane2 分钟前
HarmonyOS 6学习:视觉流畅与内容完整——旋转动画与长截图的完美融合
学习·华为·harmonyos·harmony app
liulian09164 分钟前
Flutter 依赖注入与设备信息库:get_it 与 device_info_plus 的 OpenHarmony 适配指南总结
flutter·华为·学习方法·harmonyos
SameX13 分钟前
独立开发了一款健康记录 App,聊聊几个让我纠结很久的设计决策
ios
Tangsong40429 分钟前
以Termius的方式进行安卓设备调试?试试【easyadb】| 多功能可视化adb工具
android·adb
报错小能手42 分钟前
Swift UI 框架 实战 简易计数器、待办清单 、随机壁纸图库、个人笔记
ui·ios
IntMainJhy1 小时前
【flutter for open harmony】第三方库Flutter 国际化多语言的鸿蒙化适配与实战指南
数据库·flutter·华为·sqlite·harmonyos
南村群童欺我老无力.1 小时前
鸿蒙动画系统的常见陷阱与性能优化
华为·性能优化·harmonyos
liulian09161 小时前
【Flutter for OpenHarmony 】地图功能适配与位置显示实现指南
flutter·华为·学习方法·harmonyos
IntMainJhy2 小时前
【flutter for open harmony】第三方库「Flutter 聊天组件鸿蒙化适配与实战:从零搭建鸿蒙跨平台聊天页面」
flutter·华为·harmonyos
key_3_feng2 小时前
HarmonyOS NEXT开发环境搭建深度方案
华为·harmonyos