HarmonyOS之深入解析如何实现语音朗读能力

一、前言

  • 在 HarmonyOS Next 中为应用添加语音朗读能力,主要依赖于系统提供的 TextToSpeech (TTS) 引擎。那么如何借助 HarmonyOS Next 的 textToSpeech API 实现语音朗读能力,让应用具备文本转语音的功能呢?
  • 实现语音朗读功能,本质上是应用通过 TextToSpeech API 与系统 TTS 服务交互的过程。其核心流程如下:

二、语音朗读实现流程

① 配置权限与引入模块

  • 在开始编码前,需要在项目的 module.json5 文件中声明必要的权限。根据应用场景,可能需要网络或设备位置权限。

    {
    "module": {
    "requestPermissions": [
    {
    "name": "ohos.permission.INTERNET",
    "reason": "用于在线语音服务"
    },
    {
    "name": "ohos.permission.APPROXIMATE_LOCATION",
    "reason": "语音服务定位"
    }
    ]
    }
    }

  • 在需要使用的 .ets 文件中,引入相关模块:

    import { textToSpeech } from '@kit.CoreSpeechKit'; // 引入CoreSpeechKit
    import { BusinessError } from '@kit.BasicServicesKit';

② 创建与初始化 TTS 引擎

  • 为了便于复用和管理,通常我们会将 TTS 功能封装成一个独立的管理类,例如 TextToSpeechManager,并采用单例模式确保全局唯一。在项目的 utils 文件夹下新建一个 TextToSpeechManager.ets 文件,用于封装语音朗读相关的功能:
  • 需要引入如下的头文件:

    import { textToSpeech } from '@kit.CoreSpeechKit';
    import { BusinessError } from '@kit.BasicServicesKit';

  • 初始化单例和参数:

    export class TextToSpeechManager {

    复制代码
    private static instance: TextToSpeechManager;
    private constructor() {}
    
    public static getInstance():TextToSpeechManager {
      if (!TextToSpeechManager.instance) {
        TextToSpeechManager.instance = new TextToSpeechManager();
      }
      return TextToSpeechManager.instance;
    }
    
    // 创建TextSpeechEngine实例
    private ttsEngine : textToSpeech.TextToSpeechEngine | null = null;
    // 设置播报相关参数
    private extraParam : Record<string,Object> | null = null;
    // 实例化SpeakParams对象
    private speakParams : textToSpeech.SpeakParams | null = null;
    // SpeakListener对象,设置speak的回调信息
    private speakListener : textToSpeech.SpeakListener | null = null;
    
    createEngine() {
      // 设置创建引擎参数
      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}.`);
        }
      });
    }

    }

③ 设置监听回调

  • 为了感知语音合成的状态(如开始、结束、出错),需要设置监听回调:

    复制代码
    // 得到TextToSpeechEngine实例对象后,实例化SpeakParams对象、SpeakListener对象,并传入待合成及播报的文本originalText,调用speak接口进行播报。
    initParam() {
      // 设置speak的回调信息
      this.speakListener = {
        // 开始播报回调
        onStart(requestId : string, response: textToSpeech.StartResponse) {
          console.info(`onStart, requestId:${JSON.stringify(requestId)} response: ${JSON.stringify(response)}`);
        },
        // 合成完成及播报完成回调
        onComplete(requestId : string, response: textToSpeech.CompleteResponse) {
          console.info(`onComplete, requestId:${JSON.stringify(requestId)} response: ${JSON.stringify(response)}`);
        },
        onStop(requestId : string, response: textToSpeech.StopResponse) {
          console.info(`onStop, requestId:${JSON.stringify(requestId)} response: ${JSON.stringify(response)}`);
        },
        onData(requestId : string, audio : ArrayBuffer, response : textToSpeech.SynthesisResponse) {
          console.info(`onData, requestId:${JSON.stringify(requestId)} response: ${JSON.stringify(response)}`);
        },
        onError(requestId : string, errorCode : number, errorMessage : string) {
          console.info(`onError, errorCode:${JSON.stringify(errorCode)} errorMessage: ${JSON.stringify(errorMessage)}`);
        },
      };
    
      // 设置回调
      this.ttsEngine?.setListener(this.speakListener);
    }

④ 执行语音朗读

  • 准备好引擎和监听后,就可以调用 speak 方法进行朗读了。请注意,单次合成的文本长度通常有不超过 10000 个字符的限制:

    // 调用播报方法: 可以通过修改speakParams主动设置播报策略
    speak(text:string) {
    if (!this.ttsEngine) {
    console.error('TTS Engine is not initialized');
    return;
    }
    if (!text || text.length > 10000) {
    console.error('Text is empty or too long');
    return;
    }
    // 设置播报相关参数
    this.extraParam = {"queueMode":0, "speed": 1, "volume": 0.1, "pitch":1, "languageContext":'zh-CN', "audioType":"pcm", "soundChannel":3,"playType":1};
    this.speakParams = { requestId:new Date().getTime().toString(), // requestId在同一实例内仅能用一次,请勿重复设置
    extraParams: this.extraParam };
    // 调用播报方法:可以通过修改speakParams主动设置播报策略
    this.ttsEngine?.speak(text, this.speakParams);
    }

⑤ 控制播放状态

  • 一个完整的朗读功能还需要提供播放控制:

    // 停止调用播报方法: 当需要停止合成及播报时,可调用stop接口
    stop() {
    if (this.ttsEngine?.isBusy()) {
    this.ttsEngine?.stop();
    }
    }

三、实际应用步骤

  • 首先要导入工具类,在需要使用语音朗读功能的页面中,首先导入封装好的工具类:

    import { TextToSpeechManager } from "../utils/TextToSpeechManager"

  • 初始化TTS引擎,在页面的生命周期方法中进行初始化操作,页面打开时需要创建 TextToSpeechEngine 实例以及实例化相关参数对象:

    private textToSpeechManger = TextToSpeechManager.getInstance();

    aboutToAppear(): void {
    this.textToSpeechManger.createEngine();
    this.textToSpeechManger.initParam();
    }

  • 接下来编写语音朗读的业务函数,当用户点击按钮时,直接将需要播报的文本传入到函数中即可实现语音朗读:

    this.textToSpeechManger.speak(txt);

  • 特色:

    • 多语言支持:支持中英文混合文本
    • 朗读离线使用:无需网络连接即可
    • 使用文本限制:单次最多支持 10,000 字符
    • 音色选择:支持多种音色
    • 配置参数调节:可调节语速、音量、音调等参数
    • 状态回调:提供完整的播放状态监听
相关推荐
BlackWolfSky2 小时前
鸿蒙文件操作
macos·华为·harmonyos·鸿蒙
爱笑的眼睛112 小时前
深入理解HarmonyOS Calendar组件:高级日期选择实现与优化
华为·harmonyos
HMS Core2 小时前
【FAQ】HarmonyOS SDK 闭源开放能力 — Network Kit
华为·harmonyos
爱笑的眼睛112 小时前
HarmonyOS OCR文字识别应用开发:深度指南与分布式实践
华为·harmonyos
一只小风华~2 小时前
HarmonyOS:ArkTS 页导航
深度学习·华为·harmonyos·鸿蒙
你的眼睛會笑2 小时前
uniapp 鸿蒙元服务 真机调试流程指南
华为·uni-app·harmonyos
云雾J视界5 小时前
预测电流控制在光伏逆变器中的低延迟实现:华为FPGA加速方案与并网稳定性验证
华为·fpga开发·dsp·光伏逆变器·mpcc
用户298698530145 小时前
Java: 为PDF批量添加图片水印实用指南
java·后端·api
vistaup8 小时前
DevEco Studio 鸿蒙HarmonyOS 引入本地har
华为·harmonyos