• 鸿蒙AI功能开发【hiai引擎框架-文本转语音】 基础视觉服务


    hiai引擎框架-文本转语音

    介绍

    本示例展示了使用hiai引擎框架提供的文本转语音能力。

    本示例展示了对一段中文文本,进行语音合成及播报的能力。

    需要使用hiai引擎框架文本转语音接口@kit.CoreSpeechKit.d.ts.

    效果预览

    1

    使用说明:

    1. 在手机的主屏幕,点击”ttsDemo“,启动应用。
    2. 点击“CreateEngine”按钮,进行能力初始化。
    3. 点击“speak”按钮,试听文本播报。
    4. 点击“stop”等按钮对播报进行事件控制。
    5. 点击“listVoicesCallback/listVoicesPromise”查询支持的语种和音色。

    具体实现

    本示例展示了在@kit.CoreSpeechKit.d.ts定义的API:

    • createEngine(createEngineParams: CreateEngineParams, callback: AsyncCallback): void;
    • createEngine(createEngineParams: CreateEngineParams): Promise;
    • speak(text: string, speakParams: SpeakParams, listener: SpeakListener): void;
    • listVoices(params: VoiceQuery, callback: AsyncCallback): void;
    • listVoices(params: VoiceQuery): Promise;
    • stop(): void;
    • isBusy(): boolean;
    • shutdown(): void;

    业务使用时,需要先进行import导入textToSpeech。 调用speak等接口,传入想要识别的文本,试听播报,观察日志等。参考:

    import { textToSpeech } from '@kit.CoreSpeechKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { TreeMap } from '@kit.ArkTS';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import { UuidBasic } from './UuidBasic';
    
    const TAG: string = 'TtsDemo';
    let ttsEngine: textToSpeech.TextToSpeechEngine;
    
    @Entry
    @Component
    struct Index {
      @State createCount: number = 0;
      @State result: boolean = false;
      @State voiceInfo: string = "";
      @State text: string = "";
      @State textContent: string = "";
      @State utteranceId: string = "123456";
      @State originalText: string = "\n\t\t古人学问无遗力,少壮工夫老始成;\n\t\t" +
        "纸上得来终觉浅,绝知此事要躬行。\n\t\t";
      @State illegalText: string = "";
      private pcmData: TreeMap = new TreeMap();
    
      build() {
        Column() {
          Scroll() {
            Column() {
              TextArea({ placeholder: 'Please enter tts original text', text: `${this.originalText}` })
                .margin(20)
                .focusable(false)
                .border({ width: 5, color: 0x317AE7, radius: 10, style: BorderStyle.Dotted })
                .onChange((value: string) => {
                  this.originalText = value;
                  hilog.info(0x0000, TAG, "original text: " + this.originalText);
                })
    
              Button() {
                Text("CreateEngine")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`createByCallback:createCount:${this.createCount}`);
                this.createByCallback();
              })
    
              Button() {
                Text("CreateEngineByPromise")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`createByPromise:createCount:${this.createCount}`);
                this.createByPromise();
              })
    
              Button() {
                Text("createOfErrorLanguage")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`createOfErrorLanguage:createCount:${this.createCount}`);
                this.createOfErrorLanguage();
              })
    
              Button() {
                Text("createOfErrorPerson")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`createOfErrorPerson:createCount:${this.createCount}`);
                this.createOfErrorPerson();
              })
    
              Button() {
                Text("speak")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`speak:createCount:${this.createCount}`)
                this.speak();
              })
    
              Button() {
                Text("SpeakIllegalText")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.createCount++;
                console.log(`illegalSpeak:createCount:${this.createCount}`)
                this.illegalSpeak();
              })
    
              Button() {
                Text("listVoicesCallback")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.listVoicesCallback();
              })
    
              Button() {
                Text("listVoicesPromise")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                this.listVoicesPromise();
              })
    
    
              Button() {
                Text("stop")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                //停止播报
                hilog.info(0x0000, TAG, "isSpeaking click:-->");
                //this.setListener();
                ttsEngine.stop();
              })
    
              Button() {
                Text("isBusy")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AE7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                hilog.info(0x0000, TAG, "isSpeaking click:-->");
                //查询播报状态
                this.setListener();
                let isBusy: boolean = ttsEngine.isBusy();
                console.log('isBusy :' + isBusy);
              })
    
              Button() {
                Text("shutdown")
                  .fontColor(Color.White)
                  .fontSize(20)
              }
              .type(ButtonType.Capsule)
              .backgroundColor("#0x317AA7")
              .width("80%")
              .height(50)
              .margin(10)
              .onClick(() => {
                //释放引擎
                ttsEngine.shutdown();
              })
    
            }
            .layoutWeight(1)
          }
          .width('100%')
          .height('100%')
    
        }
      }
    
      //创建引擎,通过callback形式返回
      //当引擎不存在、引擎资源不存在、初始化超时,返回错误码1002300005,引擎创建失败
      private createByCallback() {
        //设置创建引擎参数
        let extraParam: Record = { "style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName' }
        let initParamsInfo: textToSpeech.CreateEngineParams = {
          language: 'zh-CN',
          person: 0,
          online: 1,
          extraParams: extraParam
        };
        try {
          //调用createEngine方法
          textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
            if (!err) {
              console.log('createEngine is success');
              //接收创建引擎的实例
              ttsEngine = textToSpeechEngine;
            } else {
              //创建引擎失败时返回错误码1002300005,可能原因:引擎不存在、资源不存在、创建引擎超时
              console.error("errCode is " + JSON.stringify(err.code));
              console.error("errMessage is " + JSON.stringify(err.message));
            }
          });
        } catch (error) {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`createEngine failed, error code: ${code}, message: ${message}.`)
        }
      }
    
      //创建引擎,通过promise形式返回
      private createByPromise() {
        //设置创建引擎参数
        let extraParam: Record = { "style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName' }
        let initParamsInfo: textToSpeech.CreateEngineParams = {
          language: 'zh-CN',
          person: 0,
          online: 1,
          extraParams: extraParam
        };
    
        //调用createEngine方法
        textToSpeech.createEngine(initParamsInfo).then((res: textToSpeech.TextToSpeechEngine) => {
          ttsEngine = res;
          console.log('result:' + JSON.stringify(res));
        }).catch((res: Object) => {
          console.log('result' + JSON.stringify(res));
        });
    
      }
    
      //调用speak播报方法
      //未初始化引擎时调用speak方法,返回错误码1002300007,合成及播报失败
      private async speak() {
        //设置播报相关参数
        let extraParam: Record = {
          "queueMode": 0,
          "speed": 1,
          "volume": 2,
          "pitch": 1,
          "languageContext": 'zh-CN',
          "audioType": "pcm",
          "soundChannel": 1,
          "playType": 1
        }
        let speakParams: textToSpeech.SpeakParams = {
          requestId: UuidBasic.createUUID(),
          extraParams: extraParam
        }
        //设置回调
        this.setListener();
        //调用speak播报方法
        ttsEngine.speak(this.originalText, speakParams);
      }
    
      //查询语种音色信息,以callback形式返回
      private listVoicesCallback() {
        //设置查询相关参数
        let voicesQuery: textToSpeech.VoiceQuery = {
          requestId: UuidBasic.createUUID(),
          online: 1
        }
    
        //调用listVoices方法,以callback返回
        ttsEngine.listVoices(voicesQuery, (err: BusinessError, voiceInfo: textToSpeech.VoiceInfo[]) => {
          if (!err) {
            //接收目前支持的语种音色等信息
            this.voiceInfo = JSON.stringify(voiceInfo);
            console.log('voiceInfo is ' + JSON.stringify(voiceInfo));
          } else {
            console.error("error is " + JSON.stringify(err));
          }
        });
    
      };
    
      //查询语种音色信息,以promise返回
      private listVoicesPromise() {
        //设置查询相关的参数
        let voicesQuery: textToSpeech.VoiceQuery = {
          requestId: UuidBasic.createUUID(),
          online: 1
        }
        //调用listVoice方法
        ttsEngine.listVoices(voicesQuery).then((res: textToSpeech.VoiceInfo[]) => {
          console.log('voiceInfo:' + JSON.stringify(res));
        }).catch((res: Object) => {
          console.error('error is ' + JSON.stringify(res));
        });
      }
    
      private setListener() {
        let speakListener: textToSpeech.SpeakListener = {
          //开始播报回调
          onStart(utteranceId: string, response: textToSpeech.StartResponse) {
            console.log('speakListener onStart: ' + ' utteranceId: ' + utteranceId + ' response: ' + JSON.stringify(response));
          },
          //完成播报回调
          onComplete(utteranceId: string, response: textToSpeech.CompleteResponse) {
            console.log('speakListener onComplete: ' + ' utteranceId: ' + utteranceId + ' response: ' + JSON.stringify(response));
          },
          //停止播报完成回调,调用stop方法并完成时会触发此回调
          onStop(utteranceId: string, response: textToSpeech.StopResponse) {
            console.log('speakListener onStop: ' + ' utteranceId: ' + utteranceId + ' response: ' + JSON.stringify(response));
          },
          //返回音频流
          onData(utteranceId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
            console.log('speakListener onData: ' + ' utteranceId: ' + utteranceId + ' sequence: ' + JSON.stringify(response) + ' audio: ' + audio);
          },
          //错误回调,播报过程发生错误时触发此回调
          //未创建引擎时调用speak方法时返回错误码1002300007,合成及播报失败
          //连续调用两次speak,第二次speak会返回错误码1002300006,服务正忙碌
          onError(utteranceId: string, errorCode: number, errorMessage: string) {
            console.error('speakListener onError: ' + ' utteranceId: ' + utteranceId + ' errorCode: ' + errorCode + ' errorMessage: ' + errorMessage);
          }
        };
        // 设置回调
        ttsEngine.setListener(speakListener);
      }
    
      //使用不支持的语种创建引擎,返回错误码1002300002,语种不支持
      private createOfErrorLanguage() {
        //设置创建引擎参数
        let initParamsInfo: textToSpeech.CreateEngineParams = {
          //不支持的语种
          language: 'ZH-CN',
          person: 0,
          online: 1
        };
        try {
          //调用createEngine方法
          textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
            if (!err) {
              console.log('createEngine is success');
              //接收创建引擎的实例
              ttsEngine = textToSpeechEngine;
            } else {
              //返回错误码1002300002,语种不支持
              console.error("errCode is " + JSON.stringify(err.code));
              console.error("errMessage is " + JSON.stringify(err.message));
            }
          });
        } catch (error) {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`createEngine failed, error code: ${code}, message: ${message}.`)
        }
      }
    
      //使用不支持的语种创建引擎,返回错误码1002300003,音色不支持
      private createOfErrorPerson() {
        //设置创建引擎参数
        let initParamsInfo: textToSpeech.CreateEngineParams = {
          language: 'zh-CN',
          //不支持的音色
          person: 1,
          online: 1
        };
        try {
          //调用createEngine方法
          textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
            if (!err) {
              console.log('createEngine is success');
              //接收创建引擎的实例
              ttsEngine = textToSpeechEngine;
            } else {
              //返回错误码1002300003,音色不支持
              console.error("errCode is " + JSON.stringify(err.code));
              console.error("errMessage is " + JSON.stringify(err.message));
            }
          });
        } catch (error) {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`createEngine failed, error code: ${code}, message: ${message}.`)
        }
      }
    
      //使用非法文本,调用speak播报方法,返回1002300001,文本长度非法
      private illegalSpeak() {
        this.setListener();
        //设置播报相关参数
        let extraParam: Record = { "speed": 1, "volume": 1, "pitch": 1, "audioType": "pcm" }
        let speakParams: textToSpeech.SpeakParams = {
          requestId: UuidBasic.createUUID(),
          extraParams: extraParam
        }
        //调用speak播报方法
        ttsEngine.speak(this.illegalText, speakParams);
      }
    }
    
    

    以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
    下面是鸿蒙的完整学习路线,展示如下:
    1

    除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

    内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

    鸿蒙【北向应用开发+南向系统层开发】文档

    鸿蒙【基础+实战项目】视频

    鸿蒙面经

    在这里插入图片描述

    为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

  • 相关阅读:
    SQLite 学习笔记1 - 简介、下载、安装
    想干程序员这行的,真的很需要这个,T0 级别的《面试资料全集》--Java 问题收录及答案详解,持续更新中...
    MySQL数值函数
    商超智能守护:AI监控技术在零售安全中的应用
    芯片工艺PVT STA分析 OCV分析
    opencv-phase 函数
    Rust实战 | 用 RustRover 开发猜数字游戏
    51单片机自行车码表 速度里程计霍尔测速模拟电机设计
    Linux如何查看目录大小 du -lh --max-depth=1
    Gitlab合并代码并解决冲突演示
  • 原文地址:https://blog.csdn.net/2301_76813281/article/details/141025546