Skip to content

TTS 插件开发规范

适用于 BokeBox 外部语音合成插件(storage/plugins/tts/*
仓库:https://github.com/vastsa/BokeBox
协议:LGPL-3.0
宿主 API 版本:apiVersion = 1

核心原则

音色页面由插件自己声明,宿主只做通用渲染,不固定业务布局。

  • 插件导出 meta.voicePanel.fields[]
  • 前端 TtsPluginVoicePanel 按字段类型渲染
  • 后人写插件 无需改主仓 UI 代码
  • 只有要新增字段类型(组件能力)时,才需要给宿主提 PR

可运行示例:

总览:ASR / TTS 插件总览


1. 目录

text
storage/plugins/tts/<dir>/
  plugin.json
  index.js      # ESM,export default plugin
  README.md
bash
cp -R examples/tts-plugin-echo storage/plugins/tts/echo
curl -X POST http://localhost:8787/api/tts-plugins/rescan

2. 最小可运行插件

js
export default {
  id: 'tts.myprovider',
  name: 'My TTS',
  version: '0.1.0',
  riskLevel: 'medium',
  defaultEnabled: false,
  meta: {
    id: 'tts.myprovider',
    name: 'My TTS',
    description: '示例',
    modes: [{ id: 'default', label: '标准' }],
    voices: [
      { id: 'a', name: '音色 A', language: '中文' },
      { id: 'b', name: '音色 B', language: '中文' },
    ],
    supportsStyleTags: false,
    supportsVoiceDesign: false,
    maxCharsPerRequest: 800,
    voiceConfigKey: 'defaultVoice',

    // ★ 插件自己定义页面
    voicePanel: {
      version: 1,
      title: '选择音色',
      description: '这些文案和字段都由插件控制',
      fields: [
        { type: 'info', text: '请选择一个预置音色' },
        { type: 'voiceGrid' }, // 默认读 meta.voices
        {
          type: 'text',
          bind: 'voice',
          label: '或手动填写音色 ID',
          placeholder: 'optional-override-id',
        },
      ],
    },
  },
  isAvailable() { return true },
  async synthesizeChunk(input, ctx) {
    const voice =
      String(input?.tts?.voice || '').trim() ||
      String(ctx?.getConfig?.('defaultVoice') || '') ||
      'a';
    // 调你的 API...
    return {
      audio: Buffer.from([]),
      format: 'wav',
      provider: 'tts.myprovider',
      voice,
      mode: 'default',
      demo: false,
    };
  },
};

3. voicePanel 字段类型(宿主内置组件)

type作用主要属性
info提示文案text
modeTabs模式切换options[];默认 meta.modes
voiceGrid音色网格options[];默认 meta.voices
text / textarea文本输入bind: 'voice' | 'voiceDesign'
select下拉bind + options[{value,label}]
tags多选标签bind: 'styleTags' + options: string[]
effectiveSummary当前生效 / 插件默认voice + voiceConfigKey
actions快捷按钮usePluginDefault / clearOverride / openPluginSettings

条件显示

js
{ type: 'textarea', bind: 'voiceDesign', label: '描述', when: { mode: 'voicedesign' } }
{ type: 'voiceGrid', when: { mode: 'default' } }

数据绑定(TtsOptions)

bind含义
voice任务/全局音色 id 或 reference_id
modedefault / voicedesign(modeTabs 写入)
voiceDesign自然语言音色描述
styleTags风格标签数组

插件配置默认音色:

  • configSchema 声明字段(如 referenceId / defaultVoice
  • meta.voiceConfigKey 指向该字段
  • tts.voice 为空时,合成逻辑应回落 ctx.getConfig(voiceConfigKey)

4. 示例:克隆类(Fish Speech 风格)

js
meta: {
  voiceConfigKey: 'referenceId',
  voicePanel: {
    version: 1,
    title: '参考音色',
    fields: [
      { type: 'info', text: '粘贴音色库 model id' },
      {
        type: 'text',
        bind: 'voice',
        label: 'reference_id',
        placeholder: '留空=插件默认',
      },
      { type: 'effectiveSummary' },
      {
        type: 'actions',
        items: ['usePluginDefault', 'clearOverride', 'openPluginSettings'],
      },
    ],
  },
}

完整实现见 examples/tts-plugin-fishspeech


5. 兼容:voiceUi 简写(可选)

若未提供 voicePanel,宿主会把旧字段编译成面板:

voiceUi编译结果
presetvoiceGrid(+ 可选 modeTabs/tags)
referencetext + effectiveSummary + actions
freeformtext + actions
noneinfo

新插件请直接写 voicePanel,不要依赖简写。


6. 自检清单

  • [ ] meta.voicePanel.fields 非空,页面完全由你定义
  • [ ] synthesizeChunk 正确处理任务 voice 覆盖与插件默认
  • [ ] 长文本适配 maxCharsPerRequest
  • [ ] 返回优先 format: 'wav'
  • [ ] README 说明每个字段含义与音色 id 来源
  • [ ] 不把密钥写进仓库

7. 何时需要改宿主?

需求是否改主仓
新布局、新文案、新字段组合❌ 只改插件 voicePanel
新的字段类型(如上传参考音频)✅ 扩展宿主 field renderer
新的合成协议❌ 插件 synthesizeChunk 内完成

仓库:https://github.com/vastsa/BokeBox
协议:LGPL-3.0