首页 > 其他分享 >三文带你轻松上手鸿蒙的 AI 语音 03-文本合成声音

三文带你轻松上手鸿蒙的 AI 语音 03-文本合成声音

时间:2024-12-15 19:22:20浏览次数:4  
标签:播报 03 textToSpeech AI 合成 requestId 语音 文本 三文

三文带你轻松上手鸿蒙的 AI 语音 03-文本合成声音

前言

接上文 三文带你轻松上手鸿蒙的 AI 语音 02-声音文件转文本

HarmonyOS NEXT 提供的 AI 文本合并语音功能,可以将一段不超过 10000 字符的文本合成为语音并进行播报。

场景举例

  • 手机在无网状态下,系统应用无障碍(屏幕朗读)接入文本转语音能力,为视障人士提供播报能力。
  • 类似微信读书,可以实现将文章内容通过语音朗读,可以在无法不方便阅读文章时提供帮助,如一边送外卖一边听书。

实现效果

image-20240829175251444

使用流程

  1. 创建文本合成语音引擎
  2. 设置监听回调
  3. 开始合成

image-20240829173019521

创建文本合成语音引擎

文末会提供封装后的代码

创建文本合成语音引擎需要先引入 textToSpeech,然后调用其 createEngine 方法时,需要准备 初始化引擎的参数

image-20240829173614612

设置监听回调

调用完createEngine 时会返回相应实例,此时可以设置监听回调。

  1. onStart 播报开始时回调
  2. onStop 播报结束时回调
  3. onComplete 合成或播报结束后分别回调此接口,返回请求 ID,完成播报相关信息
  4. onData 合成播报过程中回调此接口,返回请求 ID,音频流信息,音频附加信息如格式、时长等。若需要返回音频流信息,请实现此接口。
  5. onError 合成播报过程中,出现错误时回调,返回请求 ID、错误码及错误描述。

image-20240829174815936

开始合成

完成上面的实例创建和设置监听后,便可以调用 speak 方法开始合成了。但是在调用 speak 时,也需要传递相应的参数。

image-20240829175108921

封装好的代码

import { textToSpeech } from "@kit.CoreSpeechKit";

class TextToSpeechManager {
  /** 语音转文本引擎 */
  private ttsEngine: textToSpeech.TextToSpeechEngine | null = null;
  /** 创建引擎的配置参数 */
  private static extraParam: Record<string, Object> = {
    // 风格 interaction-broadcast:广播风格
    style: "interaction-broadcast",
    // 区域信息。 可选,不设置时默认为“CN”,当前仅支持“CN”。
    locate: "CN",
    // 引擎名称。 可选,引擎名称,不设置是默认为空,当前仅支持单应用、单实例
    name: "EngineName",
  };
  /** 创建引擎的配置参数 */
  private static initParamsInfo: textToSpeech.CreateEngineParams = {
    // 语种, 当前仅支持“zh-CN”中文。
    language: "zh-CN",
    // 音色。 0为聆小珊女声音色,当前仅支持聆小珊女声音色。
    person: 0,
    // 模式。 0为在线,目前不支持;1为离线,当前仅支持离线模式。
    online: 1,
    extraParams: TextToSpeechManager.extraParam,
  };
  /** 会话ID,一个实例只能使用一次 */
  private requestId: string;

  constructor() {
    this.requestId = `tts` + Date.now();
  }

  /** 创建引擎 */
  async createEngine() {
    return (this.ttsEngine = await textToSpeech.createEngine(
      TextToSpeechManager.initParamsInfo
    ));
  }

  /** 设置回调监听 */
  async setListener(callback?: (res: textToSpeech.CompleteResponse) => void) {
    // 设置speak的回调信息
    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
          )}`
        );
        callback && callback(response);
      },
      // 停止播报回调
      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)}`
        );
      },
      // 错误回调
      one rror(requestId: string, errorCode: number, errorMessage: string) {
        console.error(
          `onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`
        );
      },
    };
    // 设置回调
    this.ttsEngine?.setListener(speakListener);
  }

  /** 开始转换 */
  async speak(originalText: string) {
    // 设置播报相关参数
    let extraParam: Record<string, Object> = {
      queueMode: 0,
      // 语速。可选,支持范围[0.5-2],不传参时默认为1。
      speed: 1,
      // 音量。 可选,支持范围[0-2],不传参时默认为1
      volume: 2,
      // 音调。
      // 可选,支持范围[0.5-2],不传参时默认为1
      pitch: 1,
      // 语境,播放阿拉伯数字用的语种。 可选,当前仅支持“zh-CN”中文,不传参时默认“zh-CN”。
      languageContext: "zh-CN",
      // 音频类型,当前仅支持“pcm”
      audioType: "pcm",
      //  通道。 可选,参数范围0-16,整数类型,可参考音频流使用来选择适合自己的音频场景。  不传参时默认为3,语音助手通道
      soundChannel: 3,
      // 合成类型。 可选,不传参时默认为1。 0:仅合成不播报,返回音频流。 1:合成与播报不返回音频流。
      playType: 1,
    };
    let speakParams: textToSpeech.SpeakParams = {
      requestId: this.requestId, // requestId在同一实例内仅能用一次,请勿重复设置
      extraParams: extraParam,
    };
    // 调用播报方法
    this.ttsEngine?.speak(originalText, speakParams);
  }

  /** 停止转换 */
  async stop() {
    this.ttsEngine?.stop();
  }
}

export default TextToSpeechManager;

页面中使用

Index.ets

image-20240829175251444

import { PermissionManager } from '../utils/permissionMananger'
import { Permissions } from '@kit.AbilityKit'
import SpeechRecognizerManager from '../utils/SpeechRecognizerManager'
import { AudioCapturerManager } from '../utils/AudioCapturerManager'
import TextToSpeechManager from '../utils/TextToSpeechManager'

@Entry
@Component
struct Index {
  @State
  text: string = ""
  fileName: string = ""
  // 1 申请权限
  fn1 = async () => {
    // 准备好需要申请的权限 麦克风权限
    const permissions: Permissions[] = ["ohos.permission.MICROPHONE"]
    // 检查是否拥有权限
    const isPermission = await PermissionManager.checkPermission(permissions)
    if (!isPermission) {
      //   如果没权限,就主动申请
      PermissionManager.requestPermission(permissions)
    }
  }
  // 2 实时语音识别
  fn2 = () => {
    SpeechRecognizerManager.init(res => {
      console.log("实时语音识别", JSON.stringify(res))
      this.text = res.result
    })
  }
  // 3 开始录音
  fn3 = () => {
    this.fileName = Date.now().toString()
    AudioCapturerManager.startRecord(this.fileName)
  }
  // 4 接收录音
  fn4 = () => {
    AudioCapturerManager.stopRecord()
  }
  // 5 声音文件转换文本
  fn5 = () => {
    SpeechRecognizerManager.init2(res => {
      this.text = res.result
      console.log("声音文件转换文本", JSON.stringify(res))
    }, this.fileName)
  }
  // 6 文本合成声音
  fn6 = async () => {
    const tts = new TextToSpeechManager()
    await tts.createEngine()
    tts.setListener((res) => {
      console.log("res", JSON.stringify(res))
    })
    tts.speak("我送你离开 千里之外")
  }

  build() {
    Column({ space: 10 }) {
      Text(this.text)

      Button("申请权限")
        .onClick(this.fn1)
      Button("实时语音识别")
        .onClick(this.fn2)

      Button("开始录音")
        .onClick(this.fn3)
      Button("结束录音")
        .onClick(this.fn4)

      Button("声音文件转换文本")
        .onClick(this.fn5)
      Button("文本合成声音")
        .onClick(this.fn6)

    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

总结

HarmonyOS NEXT 提供的 AI 文本合并语音功能,可以将一段不超过 10000 字符的文本合成为语音并进行播报

使用的步骤为 3 步

  1. 创建文本合成语音引擎
  2. 设置监听回调
  3. 开始合成

标签:播报,03,textToSpeech,AI,合成,requestId,语音,文本,三文
From: https://www.cnblogs.com/aspXiaoBai/p/18608349

相关文章

  • 三文带你轻松上手鸿蒙的 AI 语音 02-声音文件转文本
    三文带你轻松上手鸿蒙的AI语音02-声音文件转文本接上一文前言本文主要实现使用鸿蒙的AI语音功能将声音文件识别并转换成文本实现流程利用AudioCapturer录制声音,生成录音文件利用AI语音功能,实现识别两个录音库介绍在HarmonyOSNEXT应用开中,实现录音的两个核心......
  • 三文带你轻松上手鸿蒙的 AI 语音 01-实时语音识别
    三文带你轻松上手鸿蒙的AI语音01-实时语音识别前言HarmonyOSNext中集成了强大的AI功能。CoreSpeechKit(基础语音服务)是它提供的众多AI功能中的一种。CoreSpeechKit(基础语音服务)集成了语音类基础AI能力,包括文本转语音(TextToSpeech)及语音识别(SpeechRecognizer)能力,便......
  • 揭示NVIDIA成功背后的关键因素,并探讨其未来在AI领域的潜力
    揭示NVIDIA成功背后的关键因素,并探讨其未来在AI领域的潜力NVIDIA的成功背后有几个关键因素,这些因素不仅巩固了其在当前市场的领导地位,也为未来在人工智能(AI)领域的发展奠定了坚实的基础。以下是对此的详细探讨:1.硬件和软件的深度整合NVIDIA的核心竞争力体现在其硬件(如GPU......
  • 鸿蒙动画开发03——弹簧曲线动画
    1、概述ArkUI提供了预置动画曲线函数(指定了动画属性从起始值到终止值的变化规律)如Linear、Ease、EaseIn等。另外,ArkUI也提供了由弹簧振子物理模型产生的弹簧曲线。通过弹簧曲线,开发者可以设置超过设置的终止值,在终止值附近震荡,直至最终停下来的效果。弹簧曲线的动画效果比其他曲......
  • PyQt5 使用结合Logging 在 QPlainTextEdit/QTextBrowser 上显示日志信息
    PyQt5使用结合Logging在QPlainTextEdit/QTextBrowser上显示日志信息本文演示PyQt5如何与Python的标准库Logging结合,然后输出日志信息到如:QPlainTextEditQTextBrowser上代码结构本文中全部代码全在test_QPlainTextEdit_Log.py这一个文件中编码,步骤中有变动的地方会注......
  • 用 semalt 给新网站 CheckNumber.AI 跑个网页分析
    直接访问网站,加上网站域名(https://CheckNumber.AI):https://semalt.com/analyzer?url=checknumber.ai大概等1、2分钟后,分析结果就出来了:第一屏里给出了总体的一个评分(这个网站截图不知道为啥没显示出来)第二屏里给出了页面SEO的信息,除了Title、Metadescription,还把网站的各......
  • 初等数论-03-解同余方程
    欧拉函数定义与\(m\)互素的剩余类的个数记为\(\varphi(m),\varphi(m)\)称之为欧拉函数关于欧拉函数的结论定理1:(欧拉定理)若\((k,m)=1,\)则:\(k^{\varphi(m)}\equiv1(\bmodm)\)$定理2:(费尔玛小定理)若\(p\)为素数,则对所有的整数\(a,a^{p}=a(\bmodm)\)$定......
  • C# OnnxRuntime 实现百度网盘AI大赛-表格检测第2名方案第二部分-表格分割
    目录说明效果模型项目代码参考下载说明百度网盘AI大赛-表格检测的第2名方案。该算法包含表格边界框检测、表格分割和表格方向识别三个部分,首先,ppyoloe-plus-x对边界框进行预测,并对置信度较高的表格边界框(box)进行裁剪。裁剪后的单个表格实例会送入到DBNet中进行语......
  • 专业版对标office,一站式AI办公
    在众多的办公套件中,微软的Office和wpS无疑成为了最受欢迎的选择。微软Office凭借其强大的功能和广泛的应用场景,赢得了全球用户的青睐。而wpS则以其轻量级和高性价比而受到许多用户的喜爱。软件不仅拥有与MicrosoftOffice相似的界面和功能,还提供了丰富的模板和格式选项,尤其......
  • GameMaker Studio开发:高级动作系统_敌人AI与行为模式设计
    敌人AI与行为模式设计在动作游戏中,敌人AI的设计和实现是游戏体验的关键因素之一。一个精心设计的敌人AI可以让玩家感到挑战,增加游戏的趣味性和可玩性。本节将详细介绍如何在GameMakerStudio中设计和实现高级敌人AI与行为模式。敌人AI的设计原则设计敌人AI时,需要考虑以下......