写点什么

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

作者:万少
  • 2024-12-15
    江苏
  • 本文字数:3667 字

    阅读完需:约 12 分钟

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

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

前言

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


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


场景举例


  • 手机在无网状态下,系统应用无障碍(屏幕朗读)接入文本转语音能力,为视障人士提供播报能力。

  • 类似微信读书,可以实现将文章内容通过语音朗读,可以在无法不方便阅读文章时提供帮助,如一边送外卖一边听书。

实现效果

使用流程

  1. 创建文本合成语音引擎

  2. 设置监听回调

  3. 开始合成


创建文本合成语音引擎

文末会提供封装后的代码


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


设置监听回调

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


  1. onStart 播报开始时回调

  2. onStop 播报结束时回调

  3. onComplete 合成或播报结束后分别回调此接口,返回请求 ID,完成播报相关信息

  4. onData 合成播报过程中回调此接口,返回请求 ID,音频流信息,音频附加信息如格式、时长等。若需要返回音频流信息,请实现此接口。

  5. onError 合成播报过程中,出现错误时回调,返回请求 ID、错误码及错误描述。


开始合成

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


封装好的代码

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)}` ); }, // 错误回调 onError(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



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@Componentstruct 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. 开始合成


发布于: 刚刚阅读数: 5
用户头像

万少

关注

还未添加个人签名 2021-12-02 加入

还未添加个人简介

评论

发布
暂无评论
三文带你轻松上手鸿蒙的 AI 语音 03-文本合成声音_鸿蒙_万少_InfoQ写作社区