
sherpa-onnx Flutter TTS 示例从模型选择到构建跨平台语音合成应用【免费下载链接】sherpa-onnxSpeech-to-text, text-to-speech, speaker diarization, speech enhancement, source separation, and VAD using next-gen Kaldi with onnxruntime without Internet connection. Support embedded systems, Android, iOS, HarmonyOS, Raspberry Pi, RISC-V, RK NPU, Axera NPU, Ascend NPU, x86_64 servers, websocket server/client, support 12 programming languages项目地址: https://gitcode.com/GitHub_Trending/sh/sherpa-onnx本文基于 sherpa-onnx 仓库中的 flutter-examples/tts 官方示例完整讲解如何在 Flutter 中接入 sherpa-onnx 实现离线文本转语音TTS如何挑选并下载 TTS 模型、如何用generate-asset-list.py注册资源、如何通过model_config.dart切换 11 种内置模型以及如何在 Android、iOS、Linux、macOSarm64 与 x86_64、Windows 与 Web 六个平台上构建和运行该应用并附 Linux 构建报错的修复方法。读完本文你可以独立完成一个可跨平台部署、支持多音色与语速控制的 Flutter 语音合成 Demo。示例概览一个跨六平台的离线 TTS Demoflutter-examples/tts是 sherpa-onnx 提供的 Flutter 文本转语音示例工程。它的核心能力是将文本输入送入sherpa_onnxDart 包中的OfflineTts引擎离线合成 PCM 音频保存为 WAV 文件后回放并在界面中列出历史合成结果标签中携带文本摘要、说话人 ID 与语速。从工程结构看该示例的关键组成如下lib/main.dart应用入口。底部导航分为 “TTS” 与 “Info” 两个页面Info 页会展示当前所选模型目录名与对应的模型下载地址来自model_config.dart中的selectedModelDir/selectedModelUrllib/model_config.dart模型选择与OfflineTtsConfig定义的唯一入口native 与 Web 两条代码路径都读取它文件头注释明确说明 “Both native (model.dart) and web (model_web.dart) use this”lib/model.dart将 assets 中的模型文件拷贝到应用沙盒目录并把所有相对路径解析为绝对路径最终产出sherpa_onnx.OfflineTtsConfiglib/tts_manager.dartTTS 生命周期管理器。native 端通过Isolate在后台 isolate 中执行推理Web 端则委托给TtsWorker与 Web Worker 通信generate-asset-list.py扫描assets/目录并把文件清单写入 pubspec.yaml 的assets:段。依赖方面pubspec.yaml 中固定了sherpa_onnx: 1.13.7并引入audioplayers音频回放、path_provider沙盒路径、url_launcher等依赖要求 Dart SDK3.2.0 4.0.0、Flutter2.8.1。该示例在以下平台可用AndroidiOSLinuxmacOSarm64 与 x86_64 均支持WindowsWeb第一步选择一个 TTS 模型并放入 assets 目录在flutter build之前必须先选定一个 TTS 模型并修改代码引用它。sherpa-onnx 在官方 release 的tts-models标签下提供了完整模型列表VITS Piper、VITS、Kokoro、MatchaTTS、KittenTTS、Pocket TTS、Supertonic TTS 等覆盖英文、中英混合、中文等场景模型目录名与model_config.dart中的配置一一对应。以仓库 README 中的示例模型vits-piper-en_US-amy-low为例操作步骤为README 原文中的下载命令如下目录与命令可直接复制cd flutter-examples/tts/assets wget https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-en_US-amy-low.tar.bz2 tar xf vits-piper-en_US-amy-low.tar.bz2 rm vits-piper-en_US-amy-low.tar.bz2 cd .. ./generate-asset-list.py关于 generate-asset-list.py 的运行有两点必须理解它的作用是把模型文件注册为 Flutter 资源。脚本会遍历./assets/下所有目录将非空的目录跳过1.5x、2.x、3.x、4.x等图标密度目录整理成pubspec.yaml中flutter:段的assets:条目并写回文件。如果assets/为空脚本会打印Warning: no assets found in ./assets/.此时需要先放入模型再运行一次。它假设assets:是pubspec.yaml中flutter:段的最后一段见文件头部 docstring。当前仓库中的 pubspec.yaml 的flutter:段只有uses-material-design: true脚本会自动在其后插入assets:段若已有assets:段则替换旧的- assets/...条目。这一步不可省略不运行./generate-asset-list.pyFlutter 不知道到哪里去找模型文件构建出来的应用无法加载模型。第二步在 model_config.dart 中切换模型索引模型下载完成后只需修改 lib/model_config.dart 中的索引常量const int selectedModelIndex 0;该文件用 Dart 3 的switch表达式集中定义了 11 个可用模型索引 0–10全部返回OfflineTtsConfig对象。对照表如下模型路径、字段均摘自 model_config.dart 源码索引模型配置类型关键模型文件0VITS Piper英文 amy-lowOfflineTtsVitsModelConfigvits-piper-en_US-amy-low/en_US-amy-low.onnxtokens.txtespeak-ng-data1VITS Piper中文 xiao_yaOfflineTtsVitsModelConfigzh_CN-xiao_ya-medium.onnxtokens/lexicon并启用ruleFstsphone/date/number 三个 FST 规则2VITS Piper英文 libritts_rOfflineTtsVitsModelConfigen_US-libritts_r-medium.onnx3VITS英文 inflect-nano-v2OfflineTtsVitsModelConfigvits-inflect-en-nano-v2/model.onnx4Kokoro英文 int8OfflineTtsKokoroModelConfigkokoro-int8-en-v0_19/model.int8.onnxvoices.bin5Kokoro中英多语言OfflineTtsKokoroModelConfigkokoro-multi-lang-v1_0/model.onnx 双 lexicon6MatchaTTS英文 ljspeechOfflineTtsMatchaModelConfigmodel-steps-3.onnx vocodervocos-22khz-univ.onnx7MatchaTTS中英OfflineTtsMatchaModelConfigmatcha-icefall-zh-en 三个ruleFsts8KittenTTS英文 fp16OfflineTtsKittenModelConfigkitten-nano-en-v0_1-fp16/model.fp16.onnxvoices.bin9Pocket TTS英文 int8零样本语音克隆OfflineTtsPocketModelConfiglm_flow/lm_main/encoder/decoder/text_conditioner等 7 个文件10Supertonic TTS英文 int8OfflineTtsSupertonicModelConfigduration_predictor/text_encoder/vector_estimator/vocoder等 7 个文件几个值得注意的实现细节每种模型族只需填充对应字段。OfflineTtsModelConfig同时包含vits、kokoro、kitten、matcha、pocket、supertonic、zipvoice等子配置运行时按你填了哪一组来启用对应引擎通用参数。各模型示例都设置了numThreads: 2与debug: true中文与中英混合模型通过ruleFsts传入逗号分隔的 FST 文件如phone-zh.fst,date-zh.fst,number-zh.fst用于电话号码、日期、中文读音的文本正则化索引越界会直接抛错_ throw ArgumentError(Invalid selectedModelIndex: ...)见 model_config.dart#L212所以索引只允许 0–10文件顶部的selectedModelDir会按优先级vits.model → matcha.acousticModel → kokoro.model → kitten.model → pocket.lmFlow → supertonic.durationPredictor → zipvoice.encoder从第一个非空模型路径提取目录名selectedModelUrl则据此拼出对应的 release 下载地址供 Info 页面展示。模型如何被加载assets 拷贝与路径解析配置好模型后运行时由 lib/model.dart 完成“从资源到引擎配置”的衔接其流程为_copyAllAssetFiles()通过AssetManifest枚举所有已注册资源并逐一从rootBundle读取、写入应用支持目录getApplicationSupportDirectory()。拷贝逻辑会先比较目标文件是否存在且大小一致避免每次启动重复拷贝大模型文件见 model.dart#L110-L135prepareModelConfig()以应用支持目录为基准用_abs()/_absMulti()把模型配置中的所有相对路径model、tokens、lexicon、dataDir、ruleFsts等解析为绝对路径然后组装出sherpa_onnx.OfflineTtsConfig。逗号分隔的多路径如kokoro.lexicon的 “us-en,zh” 双词典会由_absMulti逐项展开为绝对路径。也就是说model_config.dart里写的是相对于 assets 根目录的路径而真正传给引擎的始终是解包到磁盘后的绝对路径——这就是为什么模型必须放进assets/且必须运行generate-asset-list.py。合成引擎架构Isolate 隔离与流式进度lib/tts_manager.dart 是理解这个示例“为什么不会卡 UI”的关键。从源码结构看它采用平台条件导入import ./model.dart if (dart.library.js_interop) ./model_web.dart as m;nativeAndroid/iOS/Linux/macOS/Windows_initNative()通过Isolate.spawn(_workerEntry, ...)启动后台 isolate主 isolate 与后台 isolate 之间用一对SendPort/ReceivePort通信。协议为主 isolate 发送OfflineTtsConfig→ 后台 isolate 调用sherpa_onnx.OfflineTts(config)创建引擎并回发_Ready(numSpeakers)之后每条_GenerateRequest含 text、sid、speed、generationId、参考音频等触发一次合成后台通过tts.generateWithConfig(text, config, onProgress: ...)执行推理onProgress回调每产出一段 PCM 就发送_AudioChunk(samples, progress, sampleRate, generationId)上报进度0.0–1.0完成后发送_GenerateDone完整音频、时长、耗时。取消机制每次合成开始时后台会回发一个“per-generation cancel port”主 isolate 调cancel()时向该 port 发trueonProgress回调检测到取消标志后返回 0 停止生成见 tts_manager.dart#L427-L440。Web 端由于 WASM 调用会阻塞 worker取消策略是直接销毁 worker 再重建。每个 isolate 都要初始化源码注释特别强调sherpa_onnx.initBindings()必须在每个调用其 Dart API 的 isolate中执行一次——主 isolate 因为writeWave()等后续操作也要调用。生成完成后主 isolate 用sherpa_onnx.writeWave()把 PCM 写成 WAV文件名带-sid-X-speed-Y后缀并通过audioStream推送到界面界面还会展示合成时长与耗时。合成参数说话人sid、语速speed、silenceScale、Pocket TTS 的扩散步数numSteps等都收敛在OfflineTtsGenerationConfig中这为后续做多音色、变语速、零样本克隆扩展留好了接口。构建六大平台的构建命令Linuxflutter build linuxmacOS构建 universalarm64 x86_64应用flutter build macos只构建x86_64export FLUTTER_XCODE_ARCHSx86_64 flutter build macos只构建arm64export FLUTTER_XCODE_ARCHSarm64 flutter build macosWindowsflutter build windowsAndroidflutter build apk --split-per-abiWeb直接运行flutter run -d chrome或者构建后用任意 HTTP 服务器托管产物flutter build web cd build/web python3 -m http.server 6006然后浏览器访问http://localhost:6006即可。iOS先把 iPhone 连接到电脑用flutter devices查看可用设备会列出iPhone (mobile) • 设备UDID • ios等条目然后用设备 UDID 以 release 模式安装运行flutter run -d 00008030-001064212E85802E --releaseREADME 同时记录了 iOS 真机签名这一典型卡点首次构建常会失败并报类似Error (Xcode): No profiles for com.k2fsa.sherpa.onnx.tts were found: ...的处理办法是在 Xcode 中打开ios/Runner.xcworkspace核对 Bundle Identifier 与你的签名身份一致选中Product - Build修复签名问题然后重新执行flutter run -d UDID --release最终会看到Installing and launching...的成功输出。Linux 构建报错修复缺少 gstreamer 依赖在 Linux 上执行flutter build linux时若看到如下 CMake 报错Building Linux application... CMake Error at /usr/local/share/cmake-3.29/Modules/FindPkgConfig.cmake:634 (message): The following required packages were not found: - gstreamer-1.0 Call Stack (most recent call first): /usr/local/share/cmake-3.29/Modules/FindPkgConfig.cmake:862 (_pkg_check_modules_internal) flutter/ephemeral/.plugin_symlinks/audioplayers_linux/linux/CMakeLists.txt:24 (pkg_check_modules)原因是audioplayers_linux插件依赖 GStreamer 开发包。安装对应依赖即可sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libunwind-dev小结flutter-examples/tts展示了 sherpa-onnx 在 Flutter 生态中的完整落地路径模型以普通 assets 资源随包分发generate-asset-list.py一条命令完成资源注册model_config.dart用“索引 switch 表达式”把 11 种不同架构的 TTS 模型VITS/Kokoro/Matcha/Kitten/Pocket/Supertonic统一到同一套OfflineTtsConfig接口TtsManager用 Isolatenative或 Web Workerweb隔离推理线程并以onProgress回调实现流式进度与可取消合成最终通过writeWave落盘 WAV 并由audioplayers回放。完成模型下载、注册资源、修改索引三步后按平台选择对应flutter build/flutter run命令即可在六大平台上得到同一套离线语音合成应用。【免费下载链接】sherpa-onnxSpeech-to-text, text-to-speech, speaker diarization, speech enhancement, source separation, and VAD using next-gen Kaldi with onnxruntime without Internet connection. Support embedded systems, Android, iOS, HarmonyOS, Raspberry Pi, RISC-V, RK NPU, Axera NPU, Ascend NPU, x86_64 servers, websocket server/client, support 12 programming languages项目地址: https://gitcode.com/GitHub_Trending/sh/sherpa-onnx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考