Appearance
使用方法
安卓火山引擎豆包语音识别语音合成UTS原生插件集成了离在线语音合成,流式语音识别(含一句话),帮助您快速对接豆包语音功能,插件支持uniapp和uniapp x
插件使用注意事项
- 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您使用插件
- 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例
sdk文档地址
- 离在线语音合成:https://www.volcengine.com/docs/6561/79827?lang=zh
- 流式语音设别:https://www.volcengine.com/docs/6561/125686?lang=zh
联系作者

关注微信公众号可联系作者
插件地址
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>