news 2026/10/17 2:27:15

语音规则定制:tts-server-android 多音朗读完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
语音规则定制:tts-server-android 多音朗读完整指南

语音规则定制:tts-server-android 多音朗读完整指南

【免费下载链接】tts-server-android这是一个Android系统TTS应用,内置微软演示接口,可自定义HTTP请求,可导入其他本地TTS引擎,以及根据中文双引号的简单旁白/对话识别朗读 ,还有自动重试,备用配置,文本替换等更多功能。项目地址: https://gitcode.com/GitHub_Trending/tt/tts-server-android

如果你用 TTS 读小说时,旁白和对话共用一个音色、听起来糊成一片,那么你需要的是自定义语音规则。tts-server-android 的语音规则让你用几十行 JavaScript 在合成前把文本分段打标,每个标签自动匹配一个不同的语音配置,"旁白女声、对话男声"从此不再是难题。

快速上手:最小可运行示例

在 App 的语音规则编辑页(列表页进入编辑即默认加载内置模板)粘贴下面这段最小脚本,点顶部调试按钮即可运行,示例文本可在菜单里改:

let SpeechRuleJS = { name: "旁白/对话", id: "ttsrv.multi_voice", // 名称与唯一标识 author: "me", version: 1, // version 必须是数字 tags: {narration: "旁白", dialogue: "对话"}, // 标签key → 显示名 handleText(text) { // 核心入口:分段并打标 if (text.includes('“')) return [{text: "引号外", tag: "narration"}, {text: "引号内", tag: "dialogue"}]; return [{text: text, tag: "narration"}]; } };

跑起来后,调试面板的控制台会打印示例文本的分段打标结果;合成时每个tag会去匹配绑定了对应标签的语音配置,匹配不上再按优先级降级。

它到底做了什么:原理速览

  • 脚本跑在Rhino JS 引擎上,必须定义全局对象SpeechRuleJS,其中name/id/author/version/tags由引擎读走用于入库展示
  • handleText(text)是主入口:返回[{text, tag}],可选携带id;每个 tag 对应"多音色"里绑定该标签的语音配置
  • 分段之后,splitText(text)对每段做分句;不实现它则回退到内置标点分句
  • 配置匹配三级兜底:精确id匹配 > 同 tag 随机 > 全局随机;空文本段直接跳过
  • 合成链路顺序:文本替换(前置)→ 语音规则打标 → 分句 → 文本替换(后置)→ 逐段合成

场景拆解:旁白/对话分声与角色定音

场景一:旁白与对话分声朗读

最常见的需求——中文引号里的内容换一个音色。内置默认规则就是逐字符扫描实现,不到 10 行:

handleText(text) { const list = []; let tmpStr = "", endTag = "narration"; text.split("").forEach((char, index) => { tmpStr += char; if (char === '“') { endTag = "dialogue"; list.push({text: tmpStr, tag: "narration"}); tmpStr = ""; } else if (char === '”') { endTag = "narration"; list.push({text: tmpStr.slice(0, -1), tag: "dialogue"}); tmpStr = ""; } else if (index === text.length - 1) list.push({text: tmpStr, tag: endTag}); }); return list; }

关键技巧:遇到左右引号就切换标签,并用slice(0, -1)把引号本身从文本里剔除。

场景二:对话角色指定音色

想让不同角色的对话用不同音色,可以借助handleText的第二参数和返回值里的id:

handleText(text, tagsData) { // tagsData 携带当前启用配置的数据,结构 {tag: {字段: [{id, value}]}} // 匹配到角色后,把该配置 id 写进结果,即可精确命中对应音色 return [{text: text, tag: "dialogue", id: matchedId}]; }

关键技巧:结果里带上id后,引擎会优先精确匹配那条配置;不带则降级为同 tag 随机。

去哪改:关键文件与入口

语音规则的配置方法和源码入口都在这里:

  • model/rhino/speech_rule/SpeechRuleEngine.kt:Rhino 执行脚本、调handleText/splitText的桥梁,想给 JS 增加新桥接函数就改这里
  • service/systts/help/TextProcessor.kt:运行时文本处理编排,替换、匹配、降级逻辑都在此
  • defaultData/speech_rule.js:内置默认规则,新建规则可以直接拿它当起点
  • help/js/speechRule.md:App 内置帮助文档,对handleText/splitText契约注释最细

踩坑清单 ⚠️

  1. 规则不生效 → 多音色开关未开或配置未绑定规则 → 设置里开启多音色,并给配置绑定对应 tag
  2. 保存报版本格式错误 →version缺失或非数字 → 写成纯数字,且name/id/tags都要提供
  3. 标签匹配不上、音色随机跳 → 脚本 tag 与配置绑定 tag 字符串不一致 → 两边保持完全相同的 key
  4. 整段没被朗读 →handleText返回了空白文本段(会被跳过)→ 在脚本里过滤空串
  5. 新语法报语法错误 → Rhino 引擎较老 → 用 ES5 常见语法,并在编辑页调试面板先跑一遍

语音规则是 tts-server-android 里唯一可以"给朗读编程"的入口,掌握handleText与splitText两个函数就能玩出多音色朗读。更多字段契约与示例,参考 help/js/speechRule.md。

【免费下载链接】tts-server-android这是一个Android系统TTS应用,内置微软演示接口,可自定义HTTP请求,可导入其他本地TTS引擎,以及根据中文双引号的简单旁白/对话识别朗读 ,还有自动重试,备用配置,文本替换等更多功能。项目地址: https://gitcode.com/GitHub_Trending/tt/tts-server-android

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 2:26:20

Claudian 插件更新避坑指南:4 层操作稳过升级与回滚

Claudian 插件更新避坑指南:4 层操作稳过升级与回滚 【免费下载链接】claudian An Obsidian plugin that embeds Claude Code/Codex as an AI collaborator in your vault 项目地址: https://gitcode.com/GitHub_Trending/cl/claudian Claudian 是一个把 Cla…

作者头像 李华
网站建设 2026/10/17 2:25:25

神经网络损失函数完全指南:MSE、交叉熵与合页损失

刚接触神经网络的时候,我走过很长一段弯路:对着框架文档把model.fit()跑通,看着损失值从 2.3 掉到 0.1,就觉得自己已经入门了。直到有一次,一个二分类任务的模型怎么调准确率都卡在 70%,我把学习率、batch …

作者头像 李华
网站建设 2026/10/17 2:24:10

深入理解AbstractQueuedSynchronizer:Java并发锁的底层骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 2:24:07

同步FIFO空满判定与Verilog实现:深度8参数化设计详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 2:23:49

YOLOv8鸡蛋检测系统:从数据集制作到Web部署全流程

1. 为什么是鸡蛋检测:养殖场景里的真实痛点先说个场景。某养殖基地每天清晨要统计产蛋量,过去的方法是人进鸡舍,一板一板地数,或者按托盘重量估算。数得快的一小时能清点两三千枚,数完腰酸背痛,回头报表里还…

作者头像 李华