更新记录

1.0.1(2026-05-14)

  • 移除log信息

1.0.0(2026-05-14)

  • 初版

平台兼容性

uni-app(5.07)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-nvue Android Android插件版本 iOS 鸿蒙
1.0.0 1.0.0 - - - - 5.0 1.0.0 - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(5.07)

Chrome Safari Android Android插件版本 iOS 鸿蒙 微信小程序
- - 5.0 1.0.0 - - -

xwq-sherpa-onnx-tts

xwq-sherpa-onnx-tts 是一个基于 sherpa-onnx 的离线 TTS 播报插件,目前只支持 Android 端。

插件能力概览

  • 支持基于本地 onnx 模型的离线文本转语音播报
  • 支持初始化模型、开始播报、暂停、继续、停止
  • 支持自定义 sid 说话人和 speed 语速
  • 支持传入 number.fstphone.fstdate.fst 文本归一化规则文件
  • finished 回调在当前实现中会尽量等待 AudioTrack 实际播放完成后再触发

平台说明

  • app-android:当前已实现并有实际代码
  • app-ios:当前目录存在占位文件,暂未提供实际实现
  • app-harmony:当前目录存在占位文件,暂未提供实际实现

如果项目需要上线到 iOSHarmony,请先补齐对应平台实现后再接入业务。

对外暴露的方法

插件推荐通过下面方式引入:

import {
  initSherpaOnxxTts,
  start,
  pause,
  resume,
  stop
} from "@/uni_modules/xwq-sherpa-onnx-tts"

initSherpaOnxxTts(opt)

初始化 TTS 引擎和模型资源。

  • 入参:initTTsOptions
  • 返回:无
  • 说明:建议页面加载后先调用一次,初始化成功后再调用 start

start(opt)

开始播报文本内容。

  • 入参:PlayParams
  • 返回:无
  • 说明:当前实现会把文本送入离线模型生成语音,并自动写入音频播放器

pause()

暂停当前播报。

  • 入参:无
  • 返回:无

resume()

继续当前播报。

  • 入参:无
  • 返回:无

stop()

停止当前播报。

  • 入参:无
  • 返回:无

回调与类型说明

FailCallBack

type FailCallBack = {
  msg: string
  code: number
}

字段说明:

  • msg:错误信息
  • code:错误码,便于业务侧区分初始化失败、播放失败等场景

PlayParams

type PlayParams = {
  text: string
  fail?: ((val: FailCallBack) => void) | null
  finished?: (() => void) | null
}

字段说明:

  • text:需要播报的文本内容
  • fail:播报失败时触发
  • finished:当前播报完成时触发

initTTsOptions 参数表

字段名 类型 必填 说明
model string onnx 模型文件路径,例如 model.onnx
voices string | null 音色文件路径,例如 voices.bin。当前 Android 的 VitsMelo 实现未使用该字段,保留给其他模型或后续扩展
tokens string 词表文件路径,例如 tokens.txt
dataDir string | null 发音引擎数据目录。当前 Android 的 VitsMelo 实现未使用该字段,保留接口兼容
numberFst string | null 数字文本归一化规则文件路径,例如 number.fst
phoneFst string | null 电话号码文本归一化规则文件路径,例如 phone.fst
dateFst string | null 日期文本归一化规则文件路径,例如 date.fst
dictDir string | null 分词字典目录。当前 Android 的 VitsMelo 实现未使用该字段,保留接口兼容
lexicon string 词典文件路径,用于修正特定词汇的发音
content string | null 预留字段,当前初始化流程未使用。实际播报文本请通过 start({ text }) 传入
sid number | null 说话人 ID。未传时默认使用 0
speed number | null 语速。未传时默认使用 1.0
fail ((val: FailCallBack) => void) | null 初始化失败回调
success (() => void) | null 初始化成功回调

对应类型定义如下:

type initTTsOptions = {
  model: string
  voices?: string | null
  tokens: string
  dataDir?: string | null
  numberFst?: string | null
  phoneFst?: string | null
  dateFst?: string | null
  dictDir?: string | null
  lexicon: string
  content?: string | null
  sid?: number | null
  speed?: number | null
  fail?: ((val: FailCallBack) => void) | null
  success?: (() => void) | null
}

接入步骤

1. 准备模型资源

建议把模型目录放到项目 static 下,例如:

static/
  vits-melo-tts-zh_en/
    model.onnx
    tokens.txt
    lexicon.txt
    number.fst
    phone.fst
    date.fst

2. 页面中初始化插件

先解析静态资源目录,再调用 initSherpaOnxxTts

3. 业务触发播报

通过 start({ text }) 播放文本;如果有播放控制需求,可接入 pauseresumestop

模型下载地址

vits模型(支持中英文):https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-melo-tts-zh_en.tar.bz2

uni-app x 页面用例

<template>
  <view class="page">
    <button @click="initTTs">初始化TTS</button>
    <button @click="playTts">开始播报</button>
    <button @click="pauseTts">暂停</button>
    <button @click="resumeTts">继续</button>
    <button @click="stopTts">停止</button>
  </view>
</template>

<script setup>
import {
  initSherpaOnxxTts,
  start,
  pause,
  resume,
  stop
} from "@/uni_modules/xwq-sherpa-onnx-tts"

const content = ref("清晨推开窗,一股清冽的寒气扑面而来")

const initTTs = () => {
  const path = "static/vits-melo-tts-zh_en"
  const staticPath = UTSAndroid.getResourcePath(path)
  if (staticPath == null || staticPath == "") {
    console.log("VITS 静态资源路径解析失败")
    return
  }

  initSherpaOnxxTts({
    model: staticPath + "/model.onnx",
    voices: null,
    tokens: staticPath + "/tokens.txt",
    dataDir: null,
    lexicon: staticPath + "/lexicon.txt",
    numberFst: staticPath + "/number.fst",
    phoneFst: staticPath + "/phone.fst",
    dateFst: staticPath + "/date.fst",
    sid: 0,
    speed: 1.0,
    success: () => {
      console.log("初始化成功")
    },
    fail: (result) => {
      console.log("初始化失败", result)
    }
  })
}

const playTts = () => {
  start({
    text: content.value,
    finished: () => {
      console.log("播放完成")
    },
    fail: (result) => {
      console.log("播放失败", result)
    }
  })
}

const pauseTts = () => {
  pause()
}

const resumeTts = () => {
  resume()
}

const stopTts = () => {
  stop()
}
</script>

<style>
.page {
  display: flex;
  flex-direction: column;
  padding: 24px;
  gap: 12px;
}
</style>

uni-app 页面用例

如果是传统 uni-app 页面,静态资源路径通常可以通过 plus.io.convertLocalFileSystemURL 获取。

<template>
  <view class="page">
    <button @click="initTTs">初始化TTS</button>
    <button @click="playTts">开始播报</button>
    <button @click="pauseTts">暂停</button>
    <button @click="resumeTts">继续</button>
    <button @click="stopTts">停止</button>
  </view>
</template>

<script>
import {
  initSherpaOnxxTts,
  start,
  pause,
  resume,
  stop
} from "@/uni_modules/xwq-sherpa-onnx-tts"

export default {
  data() {
    return {
      content: "清晨推开窗,一股清冽的寒气扑面而来"
    }
  },
  methods: {
    initTTs() {
      const path = "/static/vits-melo-tts-zh_en"
      const staticPath = plus.io.convertLocalFileSystemURL(path)
      if (!staticPath) {
        console.log("VITS 静态资源路径解析失败")
        return
      }

      initSherpaOnxxTts({
        model: staticPath + "/model.onnx",
        voices: null,
        tokens: staticPath + "/tokens.txt",
        dataDir: null,
        lexicon: staticPath + "/lexicon.txt",
        numberFst: staticPath + "/number.fst",
        phoneFst: staticPath + "/phone.fst",
        dateFst: staticPath + "/date.fst",
        sid: 0,
        speed: 1.0,
        success: () => {
          console.log("初始化成功")
        },
        fail: (result) => {
          console.log("初始化失败", result)
        }
      })
    },
    playTts() {
      start({
        text: this.content,
        finished: () => {
          console.log("播放完成")
        },
        fail: (result) => {
          console.log("播放失败", result)
        }
      })
    },
    pauseTts() {
      pause()
    },
    resumeTts() {
      resume()
    },
    stopTts() {
      stop()
    }
  }
}
</script>

<style>
.page {
  padding: 24rpx;
}
</style>

使用建议

  • 建议在页面进入后先调用一次 initSherpaOnxxTts
  • 初始化完成前不要直接调用 start
  • 模型、词表、词典、规则文件建议保持在同一静态目录下,便于维护
  • 如果是短文本连续播报,建议在上一次 finished 后再发起下一次播报,避免业务层抢占播放状态
  • 如果 fail 回调收到错误,请先检查模型路径、词表路径和静态资源是否已正确打包到应用内

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。