Skip to content

使用方法

安卓火山引擎豆包语音识别语音合成UTS原生插件集成了离在线语音合成,流式语音识别(含一句话),帮助您快速对接豆包语音功能,插件支持uniapp和uniapp x

插件使用注意事项

  • 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您使用插件
  • 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例

    https://pan.baidu.com/s/1hFOKt-G-C-xGcRVexlaW2Q?pwd=paay

sdk文档地址

联系作者

关注微信公众号可联系作者

插件地址

https://ext.dcloud.net.cn/plugin?id=27132

用法

在需要使用插件的页面加载以下代码

js
import * as module from "@/uni_modules/leven-uts-hsSpeech"
js
import * as module from "@/uni_modules/leven-uts-hsSpeech"

页面内容

语音识别

vue
<template>
  <view>
    <view>
      <button type="primary" size="mini" @click="startRecognizer">开始识别</button>
      <button type="primary" size="mini" @click="stopRecognizer">停止识别</button>
      <button type="primary" size="mini" @click="cancelRecognizer">取消识别</button>
    </view>
    <view style="padding: 16px;">
      <view>识别内容:</view>
      <view>{{content}}</view>
    </view>
  </view>
</template>

<script>
  // const module = uni.requireNativePlugin("leven-hsSpeech-SpeechModule");
  import * as module from "@/uni_modules/leven-uts-hsSpeech"
  export default {
    data() {
      return {
        //识别内容
        content: "",
      }
    },
    mounted() {
      this.$nextTick(() => {
        //初始化
        this.init();
      })
    },
    beforeDestroy() {
      module.releaseAsr({
        //成功执行的函数
        success: (res) => {
          console.log(res)
        },
        //失败执行的函数
        fail: (res) => {
          console.log(res)
        },
        //接口调用完成返回函数,不管成功还是失败都会返回
        complete: (res) => {
          console.log(res)
        }
      })
    },
    methods: {
      //停止识别
      cancelRecognizer() {
        module.cancelRecognizer({
          //成功执行的函数
          success: (res) => {
            // console.log(res)
            this.startDisabled = false;
            this.content = "";
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //停止识别
      stopRecognizer() {
        module.stopRecognizer({
          //成功执行的函数
          success: (res) => {
            // console.log(res)
            this.startDisabled = false;
            this.content = "";
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //开始识别
      startRecognizer() {
        let params = {
          //【可选配置】是否开启顺滑(DDC)
          enableDdc: false,
          //【可选配置】是否开启文字转数字(ITN)
          enableItn: false,
          //【可选配置】是否开启标点
          showNluPunc: true,
          //【可选配置】设置识别语种
          language: "en-US",
          //【可选配置】是否启用云端自动判停
          autoStop: false,
          //【可选配置】是否隐藏句尾标点
          disableEndPunc: false,
          //【可选配置】控制识别结果返回的形式,全量返回或增量返回,默认为全量
          resultType: "full",
          //【可选配置】设置VAD头部静音时长,用户多久没说话视为空音频,即静音检测时长
          vadStartSilenceTime: 0,
          //【可选配置】设置VAD尾部静音时长,用户说话后停顿多久视为说话结束,即自动判停时长
          vadEndSilenceTime: 0,
          //【可选配置】设置VAD模式,用于定制VAD场景,默认为空
          vadMode: "",
          //【可选配置】用户音频输入最大时长,仅一句话识别场景生效,单位毫秒,默认为 60000ms.
          vadMaxSpeechDuration: 60000,
          //【可选配置】控制是否返回录音音量,在 APP 需要显示音频波形时可以启用
          enableGetVolume: false,
          //【可选配置】设置纠错词表,识别结果会根据设置的纠错词纠正结果,例如:"{\"古爱玲\":\"谷爱凌\"}",当识别结果中出现"古爱玲"时会替换为"谷爱凌"
          correctWords: "{\"古爱玲\":\"谷爱凌\",\"古埃宁\":\"谷爱凌\",\"谷爱玲\":\"谷爱凌\",\"谷埃宁\":\"谷爱凌\"}",
          // 更新 ASR 热词,例如:"{\"hotwords\":[{\"word\":\"过秦论\",\"scale\":2.0}]}"
          // scale为float类型参数,其中叠词的范围为[1.0,2.0],非叠词的范围为[1.0,50.0],scale值越大,结果中出现热词的概率越大
          updateAsrHotWords: "{\"hotwords\":[{\"word\":\"过秦论\",\"scale\":2.0}]}",
          //使用音频文件识别时,需要设置文件的绝对路径
          // 使用音频文件识别时【必须配置】,否则【无需配置】
          // filePath: ""
        };
        module.startRecognizer({
          params: params,
          //成功执行的函数
          success: (res) => {
            console.log(res)
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //初始化
      init() {
        module.initAsr({
          params: {
            //【必需配置】配置音频来源,可选值:Recorder,File,Stream,Directory
            recorderType: "Recorder",
            //【可选配置】Debug目录
            debugDir: "/storage/emulated/0/hsSpeech/debug",
            //【可选配置】日志级别,可选值:DEBUG,TRACE,INFO,WARN,ERROR,FATAL
            logLevel: "DEBUG",
            //【可选配置】User ID(用以辅助定位线上用户问题)
            uid: "leven",
            //【可选配置】DEVICE_ID(用以辅助定位线上用户问题)
            deviceId: "0",
            //【可选配置】是否保存录音文件
            saveAudio: false,
            //【可选配置】音频采样率,默认16000
            sampleRate: 16000,
            //【可选配置】音频通道数,默认1,可选1或2
            channelNum: 1,
            //【可选配置】上传给服务的音频通道数,默认1,可选1或2,一般与channelNum保持一致即可
            upChannelNum: 1,
            //【可选配置】识别服务域名,默认:wss://openspeech.bytedance.com
            address: "wss://openspeech.bytedance.com",
            //【可选配置】识别服务Uri,默认:/api/v2/asr
            uri: "/api/v2/asr",
            //【必需配置】鉴权相关:Appid
            appId: "4413143697",
            //【必需配置】鉴权相关:Token,Token前需要加上Bearer;
            token: "Bearer;CUT52ZrQxcTNlbY_AtzCxJx4F4SW7KTG",
            //【必需配置】识别服务所用集群
            cluster: "volcengine_streaming_common",
            //【可选配置】链接超时时间
            connTimeout: 3000,
            //【可选配置】接收超时时间
            receiveTimeout: 5000,
            //【可选配置】在线请求断连后,重连次数,默认值为0,如果需要开启需要设置大于0的次数
            maxRetryTimes: 0
          },
          //成功执行的函数
          success: (res) => {
            let data = res.data;
            let status = data.status;
            if (status == "onInitSuccess") {
              //初始化成功
              console.log("初始化成功")
            } else if (status == "onSpeechMessage") {
              //语音消息
              let typeName = data.typeName;
              switch (typeName) {
                case "MESSAGE_TYPE_ENGINE_START":
                  console.log("启动引擎成功")
                  break
                case "MESSAGE_TYPE_ENGINE_STOP":
                  console.log("引擎关闭")
                  break
                case "MESSAGE_TYPE_ENGINE_ERROR":
                  console.log("错误信息回调:" + data.result)
                  break
                case "MESSAGE_TYPE_CONNECTION_CONNECTED":
                  console.log("建连成功")
                  break
                case "MESSAGE_TYPE_PARTIAL_RESULT":
                  console.log("当前请求的部分结果回调:" + data.result)
                  break
                case "MESSAGE_TYPE_FINAL_RESULT":
                  console.log("当前请求最终结果:" + data.result)
                  break
                case "MESSAGE_TYPE_VOLUME_LEVEL":
                  console.log("录音音量:" + data.result)
                  break
              }
            }
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            // console.log(res)
          }
        })
      },
    }
  }
</script>

<style lang="scss">
  .popup-contaner {
    background-color: #FFFFFF;
    border-radius: 8px 8px 0 0;

    &-title {
      padding: 16px;
      border-bottom: 1px solid #f2f2f2;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }

    &-content {
      padding: 16px;
      max-height: 500px;
      overflow-y: auto;
    }
  }
</style>
vue
<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex:1">
  <!-- #endif -->
    <button type="primary" @click="startRecognizer">开始识别</button>
    <button type="primary" @click="stopRecognizer">停止识别</button>
    <button type="primary" @click="cancelRecognizer">取消识别</button>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script setup>
  import * as module from "@/uni_modules/leven-uts-hsSpeech"
  import { LevenOptions } from "@/uni_modules/leven-uts-hsSpeech"

  //取消识别
  function cancelRecognizer() {
    module.cancelRecognizer({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      complete: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  }


  //停止识别
  function stopRecognizer() {
    module.stopRecognizer({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      complete: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  }

  //开始合成
  function startRecognizer() {
    let params = {
      //【可选配置】是否开启顺滑(DDC)
      enableDdc: false,
      //【可选配置】是否开启文字转数字(ITN)
      enableItn: false,
      //【可选配置】是否开启标点
      showNluPunc: true,
      //【可选配置】设置识别语种
      language: "en-US",
      //【可选配置】是否启用云端自动判停
      autoStop: false,
      //【可选配置】是否隐藏句尾标点
      disableEndPunc: false,
      //【可选配置】控制识别结果返回的形式,全量返回或增量返回,默认为全量
      resultType: "full",
      //【可选配置】设置VAD头部静音时长,用户多久没说话视为空音频,即静音检测时长
      vadStartSilenceTime: 0,
      //【可选配置】设置VAD尾部静音时长,用户说话后停顿多久视为说话结束,即自动判停时长
      vadEndSilenceTime: 0,
      //【可选配置】设置VAD模式,用于定制VAD场景,默认为空
      vadMode: "",
      //【可选配置】用户音频输入最大时长,仅一句话识别场景生效,单位毫秒,默认为 60000ms.
      vadMaxSpeechDuration: 60000,
      //【可选配置】控制是否返回录音音量,在 APP 需要显示音频波形时可以启用
      enableGetVolume: false,
      //【可选配置】设置纠错词表,识别结果会根据设置的纠错词纠正结果,例如:"{\"古爱玲\":\"谷爱凌\"}",当识别结果中出现"古爱玲"时会替换为"谷爱凌"
      correctWords: "{\"古爱玲\":\"谷爱凌\",\"古埃宁\":\"谷爱凌\",\"谷爱玲\":\"谷爱凌\",\"谷埃宁\":\"谷爱凌\"}",
      // 更新 ASR 热词,例如:"{\"hotwords\":[{\"word\":\"过秦论\",\"scale\":2.0}]}"
      // scale为float类型参数,其中叠词的范围为[1.0,2.0],非叠词的范围为[1.0,50.0],scale值越大,结果中出现热词的概率越大
      updateAsrHotWords: "{\"hotwords\":[{\"word\":\"过秦论\",\"scale\":2.0}]}",
      //使用音频文件识别时,需要设置文件的绝对路径
      // 使用音频文件识别时【必须配置】,否则【无需配置】
      // filePath: ""
    };
    module.startRecognizer({
      params: params,
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  }

  //获取版本号
  function getSdkVersion() {
    module.getVersion({
      success: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  }

  //初始化
  function init() {
    module.initAsr({
      params: {
        //【必需配置】配置音频来源,可选值:Recorder,File,Stream,Directory
        recorderType: "Recorder",
        //【可选配置】Debug目录
        debugDir: "/storage/emulated/0/hsSpeech/debug",
        //【可选配置】日志级别,可选值:DEBUG,TRACE,INFO,WARN,ERROR,FATAL
        logLevel: "DEBUG",
        //【可选配置】User ID(用以辅助定位线上用户问题)
        uid: "leven",
        //【可选配置】DEVICE_ID(用以辅助定位线上用户问题)
        deviceId: "0",
        //【可选配置】是否保存录音文件
        saveAudio: false,
        //【可选配置】音频采样率,默认16000
        sampleRate: 16000,
        //【可选配置】音频通道数,默认1,可选1或2
        channelNum: 1,
        //【可选配置】上传给服务的音频通道数,默认1,可选1或2,一般与channelNum保持一致即可
        upChannelNum: 1,
        //【可选配置】识别服务域名,默认:wss://openspeech.bytedance.com
        address: "wss://openspeech.bytedance.com",
        //【可选配置】识别服务Uri,默认:/api/v2/asr
        uri: "/api/v2/asr",
        //【必需配置】鉴权相关:Appid
        appId: "4413143697",
        //【必需配置】鉴权相关:Token,Token前需要加上Bearer;
        token: "Bearer;CUT52ZrQxcTNlbY_AtzCxJx4F4SW7KTG",
        //【必需配置】识别服务所用集群
        cluster: "volcengine_streaming_common",
        //【可选配置】链接超时时间
        connTimeout: 3000,
        //【可选配置】接收超时时间
        receiveTimeout: 5000,
        //【可选配置】在线请求断连后,重连次数,默认值为0,如果需要开启需要设置大于0的次数
        maxRetryTimes: 0
      },
      //成功执行的函数
      success: (res) => {
        const data = res.data;
        let status = data.getString("status")
        if (status == "onInitSuccess") {
          console.log("初始化成功")
          //获取版本号
          getSdkVersion();
        } else if (status == "onSpeechMessage") {
          //语音消息
          let typeName = data.getString("typeName");
          switch (typeName) {
            case "MESSAGE_TYPE_ENGINE_START":
              console.log("启动引擎成功")
              break
            case "MESSAGE_TYPE_ENGINE_STOP":
              console.log("引擎关闭")
              break
            case "MESSAGE_TYPE_ENGINE_ERROR":
              console.log("错误信息回调:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_CONNECTION_CONNECTED":
              console.log("建连成功")
              break
            case "MESSAGE_TYPE_PARTIAL_RESULT":
              console.log("当前请求的部分结果回调:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_FINAL_RESULT":
              console.log("当前请求最终结果:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_VOLUME_LEVEL":
              console.log("录音音量:" + data.getString("result"))
              break
          }
        }
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  }

  onMounted(() => {
    //初始化
    init();
  })

  onUnload(() => {
    module.releaseAsr({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  })
</script>

<style>

</style>

语音合成

vue
<template>
  <view>
    <uni-easyinput type="textarea" autoHeight v-model="text"></uni-easyinput>
    <view>
      <button type="primary" size="mini" @click="startTts">开始合成</button>
      <button type="primary" size="mini" @click="stopTts">停止合成</button>
      <button type="primary" size="mini" @click="pausePlay">暂停播放</button>
      <button type="primary" size="mini" @click="resumePlay">继续播放</button>
    </view>
  </view>
</template>

<script>
  // const module = uni.requireNativePlugin("leven-hsSpeech-SpeechModule");
  import * as module from "@/uni_modules/leven-uts-hsSpeech"
  export default {
    data() {
      return {
        text: "愿中国青年都摆脱冷气,只是向上走,不必听自暴自弃者流的话。能做事的做事,能发声的发声。有一分热,发一分光。就令萤火一般,也可以在黑暗里发一点光,不必等候炬火。此后如竟没有炬火:我便是唯一的光。",
        //识别内容
        content: "",
      }
    },
    mounted() {
      this.$nextTick(() => {
        //初始化
        this.init();
      })
    },
    beforeDestroy() {
      module.releaseTts({
        //成功执行的函数
        success: (res) => {
          console.log(res)
        },
        //失败执行的函数
        fail: (res) => {
          console.log(res)
        },
        //接口调用完成返回函数,不管成功还是失败都会返回
        complete: (res) => {
          console.log(res)
        }
      })
    },
    methods: {
      //继续播放
      resumePlay() {
        module.resumePlay({
          //成功执行的函数
          success: (res) => {
            console.log(res)
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //暂停播放
      pausePlay() {
        module.pausePlay({
          //成功执行的函数
          success: (res) => {
            console.log(res)
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //停止合成
      stopTts() {
        module.stopTts({
          //成功执行的函数
          success: (res) => {
            console.log(res)
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //开始识别
      startTts() {
        let params = {
          //【必需配置】需合成的文本,不可超过 80 字
          text: this.text,
          //【必需配置】TTS 使用场景,可选值:normal、novel
          ttsScenario: "normal",
          //【可选配置】需合成的文本的类型,支持直接传文本(TTS_TEXT_TYPE_PLAIN)和传 SSML 形式(TTS_TEXT_TYPE_SSML)的文本,可选值:plain、ssml、json
          textType: "plain",
          //【可选配置】用于控制 TTS 音频的语速,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
          speed: 10,
          //【可选配置】用于控制 TTS 音频的音量,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
          volume: 10,
          //【可选配置】用于控制 TTS 音频的音高,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
          pitch: 10,
          //【可选配置】是否在文本的每句结尾处添加静音段,单位:毫秒,默认为 0ms
          silenceDuration: 0,
          //【可选配置】是否使用 SDK 内置播放器播放合成出的音频,默认为 true
          enablePlayer: true,
          //【可选配置】是否令 SDK 通过回调返回合成的音频数据,默认不返回。
          // 开启后,SDK 会流式返回音频,收到 MESSAGE_TYPE_TTS_AUDIO_DATA_END 回调表示当次合成所有的音频已经全部返回
          dataCallbackMode: false,
          // ------------------------ 在线合成相关配置 -----------------------
          //【必需配置】在线合成使用的发音人代号
          voiceOnline: "",
          //【必需配置】在线合成使用的音色代号
          voiceTypeOnline: "BV700_V2_streaming",
          //【可选配置】是否打开在线合成的服务端缓存,默认关闭
          enableCache: false,
          //【可选配置】指定在线合成的语种,默认为空,即不指定
          languageOnline: "",
          //【可选配置】是否启用在线合成的情感预测功能
          withIntent: false,
          //【可选配置】指定在线合成的情感,例如 happy, sad 等
          emotion: "",
          //【可选配置】需要返回详细的播放进度时应配置为 1, 否则配置为 0 或不配置
          withFrontend: 1,
          //【可选配置】使用复刻音色
          useVoiceClone: false,
          //【可选配置】在开启前述使用复刻音色的开关后,制定复刻音色所用的后端集群
          backendCluster: "",
          // ------------------------ 离线合成相关配置 -----------------------
          //【必需配置】离线合成使用的发音人代号
          voiceOffline: "",
          //【必需配置】离线合成使用的音色代号
          voiceTypeOffline: "",
          //【可选配置】是否降低离线合成的 CPU 利用率,默认关闭
          // 打开该配置会使离线合成的实时率变大,仅当必要(例如为避免系统主动杀死CPU占用持续过高的进程)时才应开启
          limitCpuUsage: false
        };
        module.startTts({
          params: params,
          //成功执行的函数
          success: (res) => {
            console.log(res)
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            console.log(res)
          }
        })
      },
      //初始化
      init() {
        module.initTts({
          params: {
            //【可选配置】初始化模式,可选值:Online,Offline,Both,Alternate,File
            //Online:只进行在线合成,不需要配置离线合成相关参数(默认)
            //Offline:只进行离线合成,不需要配置在线合成相关参数
            //Alternate:优先发起在线合成,失败后(网络错误),启动离线合成引擎开始合成
            //Both:同时发起在线合成与离线合成,在线请求失败的情况下,使用离线合成数据,该模式会消耗更多系统性能;
            //File:文件合成-SDK文档未做详细介绍
            workMode: "Online",
            //【可选配置】Debug目录,音频也保存到此目录
            debugDir: "/storage/emulated/0/hsSpeech/debug",
            //【可选配置】日志级别,可选值:DEBUG,TRACE,INFO,WARN,ERROR,FATAL
            logLevel: "DEBUG",
            //【可选配置】User ID(用以辅助定位线上用户问题)
            uid: "leven",
            //【可选配置】DEVICE_ID(用以辅助定位线上用户问题)
            deviceId: "0",
            //【可选配置】是否将合成出的音频保存到设备上
            // TTS 音频文件保存目录,必须在合成之前创建好且 APP 具有访问权限,保存的音频文件名格式为 tts_{reqid}.wav, {reqid} 是本次合成的请求 id
            saveAudio: true,
            //【可选配置】合成出的音频的采样率,默认为 24000
            sampleRate: 24000,
            //【可选配置】打断播放时使用多长时间淡出停止,单位:毫秒。默认值 0 表示不淡出
            audioFadeoutDuration: 0,
            //【必需配置】鉴权相关:Appid
            appId: "4413143697",
            //【必需配置】鉴权相关:Token,Token前需要加上Bearer;
            token: "Bearer;CUT52ZrQxcTNlbY_AtzCxJx4F4SW7KTG",
            //【可选配置】识别服务域名,默认:wss://openspeech.bytedance.com
            address: "wss://openspeech.bytedance.com",
            //【可选配置】识别服务Uri,默认:/api/v1/tts/ws_binary
            uri: "/api/v1/tts/ws_binary",
            //【必需配置】语音合成服务所用集群
            cluster: "volcano_tts",
            //【可选配置】在线合成下发的 opus-ogg 音频的压缩倍率
            compressionRate: 10,
            // ------------------------ 离线合成相关配置 -----------------------
            //离线合成方式,可选值:
            //SingleVoice:单音色资源是指一个资源文件仅包含一个离线音色,新版(V4 及以上)离线合成用的就是单音色资源
            //MultipleVoice:音色资源是指一个资源文件中包含了多个离线音色,这种资源一般是旧版(V2)离线合成所用资源
            ttsOfflineModeFormat: "SingleVoice",
            //离线合成模型名称,ttsOfflineModeFormat为MultipleVoice时有效
            ttsModelName: "aispeech_tts",
            //【必需配置】离线合成鉴权相关:证书文件存放路径
            licenseDirectory: "/storage/emulated/0/hsSpeech/debug",
            //【必需配置】Authenticate Type:可选值:pre_bind,late_bind
            authenticateType: "pre_bind",
            // 证书名,用于下载按报名授权的证书文件,authenticateType为pre_bind时有效
            ttsLicenseName: "",
            // 业务 ID, 用于下载按报名授权的证书文件,authenticateType为pre_bind时有效
            ttsLicenseBusiId: "",
            //【必需配置】离线合成鉴权相关:Authenticate Address,authenticateType为late_bind时有效
            authenticateAddress: "",
            //【必需配置】离线合成鉴权相关:Authenticate Uri,authenticateType为late_bind时有效
            authenticateUri: "",
            //【必需配置】离线合成鉴权相关:Business Key,authenticateType为late_bind时有效
            businessKey: "",
            //【必需配置】离线合成鉴权相关:Authenticate Secret,authenticateType为late_bind时有效
            authenticateSecret: "fVn88i22Km1zM1WsU4SWc0wcqHOSp8KR",
            // ------------------------ 在离线切换相关配置 -----------------------
            // 断点续播功能在断点处会发生由在线合成音频切换到离线合成音频,为了提升用户体验,SDK 支持
            // 淡出地停止播放在线音频然后再淡入地开始播放离线音频,下面两个参数可以控制淡出淡入的长度
            //【可选配置】断点续播专用,切换到离线合成时淡入的音频长度,单位:毫秒
            ttsFadeInDuration: 30,
            //【可选配置】断点续播专用,在线合成停止播放时淡出的音频长度,单位:毫秒
            ttsFadeoutDuration: 30,
            //【可选配置】APP版本号
            appVersion: "1.0.0",
            //【可选配置】是否使用在线模式
            useOnlineModel: true,
            //【可选配置】离线合成将会使用的音色
            needDownloadVoiceType: [],
            //【可选配置】需要下载的离线合成语种资源
            offlineLanguage: ""
          },
          //成功执行的函数
          success: (res) => {
            console.log(res);
            let data = res.data;
            let status = data.status;
            if (status == "onInitSuccess") {
              //初始化成功
              console.log("初始化成功")
            } else if (status == "onSpeechMessage") {
              //语音消息
              let typeName = data.typeName;
              switch (typeName) {
                case "MESSAGE_TYPE_ENGINE_START":
                  console.log("启动引擎成功")
                  break
                case "MESSAGE_TYPE_ENGINE_STOP":
                  console.log("引擎关闭")
                  break
                case "MESSAGE_TYPE_ENGINE_ERROR":
                  console.log("错误信息回调:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_SYNTHESIS_BEGIN":
                  console.log("合成开始:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_SYNTHESIS_END":
                  console.log("合成结束:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_START_PLAYING":
                  console.log("播放开始:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_PLAYBACK_PROGRESS":
                  console.log("播放进度:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_FINISH_PLAYING":
                  console.log("播放结束:" + data.result)
                  break
                case "MESSAGE_TYPE_TTS_AUDIO_DATA":
                  console.log("音频数据:" + data.result)
                  break
              }
            }
          },
          //失败执行的函数
          fail: (res) => {
            console.log(res)
          },
          //接口调用完成返回函数,不管成功还是失败都会返回
          complete: (res) => {
            // console.log(res)
          }
        })
      },
    }
  }
</script>

<style lang="scss">
  .popup-contaner {
    background-color: #FFFFFF;
    border-radius: 8px 8px 0 0;

    &-title {
      padding: 16px;
      border-bottom: 1px solid #f2f2f2;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }

    &-content {
      padding: 16px;
      max-height: 500px;
      overflow-y: auto;
    }
  }
</style>
vue
<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex:1">
  <!-- #endif -->
    <view>
      <rice-textarea v-model="text" placeholder="请输入合成内容" auto-height></rice-textarea>
    </view>
    <view>
      <button type="primary" size="mini" @click="startTts">开始合成</button>
      <button type="primary" size="mini" @click="stopTts">停止合成</button>
      <button type="primary" size="mini" @click="pausePlay">暂停播放</button>
      <button type="primary" size="mini" @click="resumePlay">继续播放</button>
      <button type="primary" size="mini" @click="text = ''">清除</button>
    </view>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script setup>
  import * as module from "@/uni_modules/leven-uts-hsSpeech"
  import { LevenOptions } from "@/uni_modules/leven-uts-hsSpeech"
  const CN_TEXT = '愿中国青年都摆脱冷气,只是向上走,不必听自暴自弃者流的话。能做事的做事,能发声的发声。有一分热,发一分光。就令萤火一般,也可以在黑暗里发一点光,不必等候炬火。此后如竟没有炬火:我便是唯一的光。';
  //合成文本
  const text = ref(CN_TEXT)

  //停止合成
  function stopTts() {
    module.stopTts({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      complete: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  }

  //恢复播放
  function resumePlay() {
    module.resumePlay({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      complete: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  }

  //暂停播放
  function pausePlay() {
    module.pausePlay({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  }

  //开始合成
  function startTts() {
    module.startTts({
      params: {
        //【必需配置】需合成的文本,不可超过 80 字
        text: text.value,
        //【必需配置】TTS 使用场景,可选值:normal、novel
        ttsScenario: "normal",
        //【可选配置】需合成的文本的类型,支持直接传文本(TTS_TEXT_TYPE_PLAIN)和传 SSML 形式(TTS_TEXT_TYPE_SSML)的文本,可选值:plain、ssml、json
        textType: "plain",
        //【可选配置】用于控制 TTS 音频的语速,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
        speed: 10,
        //【可选配置】用于控制 TTS 音频的音量,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
        volume: 10,
        //【可选配置】用于控制 TTS 音频的音高,支持的配置范围参考火山官网 语音技术/语音合成/离在线语音合成SDK/参数说明 文档
        pitch: 10,
        //【可选配置】是否在文本的每句结尾处添加静音段,单位:毫秒,默认为 0ms
        silenceDuration: 0,
        //【可选配置】是否使用 SDK 内置播放器播放合成出的音频,默认为 true
        enablePlayer: true,
        //【可选配置】是否令 SDK 通过回调返回合成的音频数据,默认不返回。
        // 开启后,SDK 会流式返回音频,收到 MESSAGE_TYPE_TTS_AUDIO_DATA_END 回调表示当次合成所有的音频已经全部返回
        dataCallbackMode: false,
        // ------------------------ 在线合成相关配置 -----------------------
        //【必需配置】在线合成使用的发音人代号
        voiceOnline: "",
        //【必需配置】在线合成使用的音色代号
        voiceTypeOnline: "BV700_V2_streaming",
        //【可选配置】是否打开在线合成的服务端缓存,默认关闭
        enableCache: false,
        //【可选配置】指定在线合成的语种,默认为空,即不指定
        languageOnline: "",
        //【可选配置】是否启用在线合成的情感预测功能
        withIntent: false,
        //【可选配置】指定在线合成的情感,例如 happy, sad 等
        emotion: "",
        //【可选配置】需要返回详细的播放进度时应配置为 1, 否则配置为 0 或不配置
        withFrontend: 1,
        //【可选配置】使用复刻音色
        useVoiceClone: false,
        //【可选配置】在开启前述使用复刻音色的开关后,制定复刻音色所用的后端集群
        backendCluster: "",
        // ------------------------ 离线合成相关配置 -----------------------
        //【必需配置】离线合成使用的发音人代号
        voiceOffline: "",
        //【必需配置】离线合成使用的音色代号
        voiceTypeOffline: "",
        //【可选配置】是否降低离线合成的 CPU 利用率,默认关闭
        // 打开该配置会使离线合成的实时率变大,仅当必要(例如为避免系统主动杀死CPU占用持续过高的进程)时才应开启
        limitCpuUsage: false
      },
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  }

  //初始化
  function init() {
    module.initTts({
      params: {
        //【可选配置】初始化模式,可选值:Online,Offline,Both,Alternate,File
        //Online:只进行在线合成,不需要配置离线合成相关参数(默认)
        //Offline:只进行离线合成,不需要配置在线合成相关参数
        //Alternate:优先发起在线合成,失败后(网络错误),启动离线合成引擎开始合成
        //Both:同时发起在线合成与离线合成,在线请求失败的情况下,使用离线合成数据,该模式会消耗更多系统性能;
        //File:文件合成-SDK文档未做详细介绍
        workMode: "Online",
        //【可选配置】Debug目录,音频也保存到此目录
        debugDir: "/storage/emulated/0/hsSpeech/debug",
        //【可选配置】日志级别,可选值:DEBUG,TRACE,INFO,WARN,ERROR,FATAL
        logLevel: "DEBUG",
        //【可选配置】User ID(用以辅助定位线上用户问题)
        uid: "leven",
        //【可选配置】DEVICE_ID(用以辅助定位线上用户问题)
        deviceId: "0",
        //【可选配置】是否将合成出的音频保存到设备上
        // TTS 音频文件保存目录,必须在合成之前创建好且 APP 具有访问权限,保存的音频文件名格式为 tts_{reqid}.wav, {reqid} 是本次合成的请求 id
        saveAudio: true,
        //【可选配置】合成出的音频的采样率,默认为 24000
        sampleRate: 24000,
        //【可选配置】打断播放时使用多长时间淡出停止,单位:毫秒。默认值 0 表示不淡出
        audioFadeoutDuration: 0,
        //【必需配置】鉴权相关:Appid
        appId: "4413143697",
        //【必需配置】鉴权相关:Token,Token前需要加上Bearer;
        token: "Bearer;CUT52ZrQxcTNlbY_AtzCxJx4F4SW7KTG",
        //【可选配置】识别服务域名,默认:wss://openspeech.bytedance.com
        address: "wss://openspeech.bytedance.com",
        //【可选配置】识别服务Uri,默认:/api/v1/tts/ws_binary
        uri: "/api/v1/tts/ws_binary",
        //【必需配置】语音合成服务所用集群
        cluster: "volcano_tts",
        //【可选配置】在线合成下发的 opus-ogg 音频的压缩倍率
        compressionRate: 10,
        // ------------------------ 离线合成相关配置 -----------------------
        //离线合成方式,可选值:
        //SingleVoice:单音色资源是指一个资源文件仅包含一个离线音色,新版(V4 及以上)离线合成用的就是单音色资源
        //MultipleVoice:音色资源是指一个资源文件中包含了多个离线音色,这种资源一般是旧版(V2)离线合成所用资源
        ttsOfflineModeFormat: "SingleVoice",
        //离线合成模型名称,ttsOfflineModeFormat为MultipleVoice时有效
        ttsModelName: "aispeech_tts",
        //【必需配置】离线合成鉴权相关:证书文件存放路径
        licenseDirectory: "/storage/emulated/0/hsSpeech/debug",
        //【必需配置】Authenticate Type:可选值:pre_bind,late_bind
        authenticateType: "pre_bind",
        // 证书名,用于下载按报名授权的证书文件,authenticateType为pre_bind时有效
        ttsLicenseName: "",
        // 业务 ID, 用于下载按报名授权的证书文件,authenticateType为pre_bind时有效
        ttsLicenseBusiId: "",
        //【必需配置】离线合成鉴权相关:Authenticate Address,authenticateType为late_bind时有效
        authenticateAddress: "",
        //【必需配置】离线合成鉴权相关:Authenticate Uri,authenticateType为late_bind时有效
        authenticateUri: "",
        //【必需配置】离线合成鉴权相关:Business Key,authenticateType为late_bind时有效
        businessKey: "",
        //【必需配置】离线合成鉴权相关:Authenticate Secret,authenticateType为late_bind时有效
        authenticateSecret: "fVn88i22Km1zM1WsU4SWc0wcqHOSp8KR",
        // ------------------------ 在离线切换相关配置 -----------------------
        // 断点续播功能在断点处会发生由在线合成音频切换到离线合成音频,为了提升用户体验,SDK 支持
        // 淡出地停止播放在线音频然后再淡入地开始播放离线音频,下面两个参数可以控制淡出淡入的长度
        //【可选配置】断点续播专用,切换到离线合成时淡入的音频长度,单位:毫秒
        ttsFadeInDuration: 30,
        //【可选配置】断点续播专用,在线合成停止播放时淡出的音频长度,单位:毫秒
        ttsFadeoutDuration: 30,
        //【可选配置】APP版本号
        appVersion: "1.0.0",
        //【可选配置】是否使用在线模式
        useOnlineModel: true,
        //【可选配置】离线合成将会使用的音色
        needDownloadVoiceType: [] as string[],
        //【可选配置】需要下载的离线合成语种资源
        offlineLanguage: ""
      },
      //成功执行的函数
      success: (res) => {
        const data = res.data;
        console.log(data)
        let status = data.getString("status")
        if (status == "onInitSuccess") {
          console.log("初始化成功")
        } else if (status == "onSpeechMessage") {
          //语音消息
          let typeName = data.getString("typeName");
          switch (typeName) {
            case "MESSAGE_TYPE_ENGINE_START":
              console.log("启动引擎成功")
              break
            case "MESSAGE_TYPE_ENGINE_STOP":
              console.log("引擎关闭")
              break
            case "MESSAGE_TYPE_ENGINE_ERROR":
              console.log("错误信息回调:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_TTS_SYNTHESIS_BEGIN":
              console.log("合成开始")
              break
            case "MESSAGE_TYPE_TTS_SYNTHESIS_END":
              console.log("合成结束:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_TTS_START_PLAYING":
              console.log("播放开始:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_TTS_PLAYBACK_PROGRESS":
              console.log("播放进度:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_TTS_FINISH_PLAYING":
              console.log("播放结束:" + data.getString("result"))
              break
            case "MESSAGE_TYPE_TTS_AUDIO_DATA":
              console.log("音频数据:" + data.getString("result"))
              break
          }
        }
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      // complete: (res) => {
      //   console.log(res)
      // }
    } as LevenOptions)
  }

  onMounted(() => {
    init();
  })

  onUnload(() => {
    module.releaseTts({
      //成功执行的函数
      success: (res) => {
        console.log(res)
      },
      //失败执行的函数
      fail: (res) => {
        console.log(res)
      },
      //接口调用完成返回函数,不管成功还是失败都会返回
      complete: (res) => {
        console.log(res)
      }
    } as LevenOptions)
  })
</script>

<style lang="scss">
  .cell-right {
    flex-direction: row;
    justify-content: flex-end;
  }

  .popup-contaner {
    background-color: #FFFFFF;
    border-radius: 8px 8px 0 0;

    &-title {
      padding: 16px;
      border-bottom: 1px solid #f2f2f2;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }

    &-content {
      padding: 16px;
      max-height: 500px;
    }
  }
</style>