完整开发档案 / 从需求到交付

两套应用如何一步一步开发完成,并串成完整生产链路。

本页按真实工程顺序记录:为什么这样设计、每一步接收什么输入、执行什么操作、产生什么输出、遇到什么风险、如何验证。它既是客户评估材料,也是供 Agent 检索的技术知识页。

6个开发阶段
30个可检索步骤
2套独立本地应用
1条端到端生产链路

阶段一

先定义问题,再决定技术。

  1. 明确最终业务结果

    输入用户只有文案、目标音色、图片和发布需求。
    操作把目标拆为音色克隆、语音生成、视频合成、质量检查、成品导出五个可独立验证的环节。
    输出两套独立应用和一条可组合工作流,而不是一段只能演示的脚本。
  2. 确定本地优先的约束

    输入Apple Silicon 设备、敏感参考音频、希望避免持续 API 费用。
    操作主路径选择 MLX;需要原生兼容时使用隔离的 PyTorch/MPS 子进程;模型权重与 ASR 全部本地保存。
    输出无云端密钥、参考声音不离开本机、可离线执行的基础架构。
  3. 建立统一输入输出合同

    TTS 合同统一为:文本、参考音频或音色缓存、模型模式、采样参数、任务控制回调、输出路径。视频合同统一为:音频、至少一张图片、可选文案、可选首页标题和画布参数。统一合同让界面与底层模型解耦。

  4. 把非功能需求写进产品规则

    规则包括:大模型按需加载;任务必须可观察、可取消;已有输出不得覆盖;无文案时字幕自动关闭;视频方向由首图决定;商业页面必须如实区分原生能力、近似能力与授权边界。

阶段二

开发 IndexTTS2 多模型语音工作台。

  1. 搭建 Gradio 工作台骨架

    先完成模型选择、音色选择、文本输入、参数区、生成按钮、进度状态、试听与下载区域。界面只负责收集意图,生成逻辑全部进入后端适配器。

    关键模块mlx_indextts/webui.py
  2. 接入 IndexTTS 2.5 主引擎

    使用 MLX 8-bit 模型,在适配器中实现 speaker context 构建、音色条件缓存、按自然停顿分段、逐段生成、片段拼接与部分文件写入。中文安全上限高于拉丁文本,降低长句对齐崩溃风险。

    关键模块generate_v25.py
  3. 增加异常时长保护

    生成后根据文字单位估算合理时长上限。若短句被异常扩展成长音频,系统不直接接受,而是缩短文本片段后重试,防止长文中出现局部失真和时间轴漂移。

  4. 接入 IndexTTS 2.0 情绪路径

    保留参考音色克隆,同时开放 happy、sad、angry、afraid、disgusted、melancholic、surprised、calm 八类原生情绪向量和 emo_alpha 强度。2.0 与 2.5 音色缓存分开保存,避免格式误用。

  5. 接入 OmniVoice MLX 三种模式

    实现 clone、design、auto。克隆模式将参考音频编码为 token,并要求准确参考原文;设计模式接收声音描述;自动模式不需要参考音频。输出统一为 24 kHz PCM WAV。

    关键模块generate_omnivoice.py
  6. 解决 OmniVoice 参考音频对齐

    当用户没有填写参考原文时,对“实际送入模型的预处理音频”执行本地 Qwen3-ASR 转写,而不是转写另一份未经裁剪的文件。音频 token 与转写按文件路径、大小、修改时间和截取时长生成缓存键,防止串音色。

  7. 如实实现 OmniVoice 表达预设

    耳语使用原生 whisper 指令;平静、高兴、悲伤、激昂、严肃通过 OmniVoice 确实支持的音高、语速、温度等参数组合近似。界面和文档明确标注“表达近似”,不伪装成 IndexTTS 2.0 的情绪向量。

  8. 接入 Fish Audio S2 Pro

    增加克隆、自动/多说话人、行内表达标签和独立采样参数。输出 44.1 kHz;参考编码可以缓存。为避免长文一次推理申请过大统一内存,普通文案按最多 60 字、标点优先切分。

  9. 处理 Fish 长文截断与恢复

    音频 token 安全下限设为 1024;触顶后自动加倍,最高 4096。每完成一个短片段立即更新进度并写入 .partial.wav,终止任务时保留已完成音频,避免整篇重做。

  10. 接入 VoiceStudio 原生 OmniVoice

    不启动完整桌面前端,只在独立 PyTorch/MPS 子进程中调用固定版本的原生引擎。语音模型走 MPS,audio tokenizer 走 CPU。切换到其他引擎时终止 worker,释放内存。

    关键模块generate_voicestudio.py
  11. 设计按模型隔离的参数档案

    五个引擎各自保存设置。切换模型时恢复该引擎上次使用的参数,“恢复推荐设置”只重置当前引擎。无效控件动态隐藏,降低把 IndexTTS 参数误传给 OmniVoice 的风险。

  12. 建设音色库

    参考音频、预览音频、音色条件、显示名称、常用状态和参考原文形成一个可复用音色档案。选择后可立即试听并作为当前音色;删除操作保留独立危险语义。

  13. 实现长任务状态机

    任务状态包括 idle、running、paused、cancelled 和 completed。进度记录当前片段、总片段、开始时间、暂停时间与已完成耗时;取消信号在每个安全片段之间检查。

  14. 统一输出与质量检查

    先生成浮点音频,再检查空结果、异常峰值、硬截断和时长,最终导出 WAV、MP3 或 FLAC。文件名取文案开头的有效字符,同名追加序号,不覆盖历史文件。

  15. 完成界面信息架构与浏览器验证

    针对长音色名重新分配音色选择区、常用按钮与删除按钮宽度。实测选择区约占 83.3%,操作按钮保留语义和可点面积;相关回归测试通过后才进入发布版本。

阶段三

开发视频首页 MP4 生成器。

  1. 定义最小输入合同

    音频和至少一张图片是必需项;口播文案可空;字幕默认关闭。第一张图片是首页,后续图片是内容图,上传顺序就是播放顺序。

  2. 建立 Flask 异步任务接口

    POST /api/generate 只负责校验、落盘、创建 job_id 和启动后台线程。页面通过状态接口轮询,避免长时间请求因编码耗时而断开。

    关键模块webui.py
  3. 保存可审计任务目录

    每个任务目录保存原始输入、解析后的逐句文本、处理后画面、字幕 PNG、日志、状态、结果 JSON 与最终 MP4。问题发生时可以定位到图片处理、字幕对齐或编码阶段。

  4. 解析口播文案

    跳过 Markdown 标题,将正文按中文和英文句末标点拆句;标点不足时按原始行回退。没有有效句子时自动进入无字幕模式。

  5. 确定画布和方向

    读取第一张图片并应用 EXIF 方向。自动模式保留原始横屏、竖屏或方形比例;H.264/YUV420P 遇到奇数边长时只补 1 像素,不进行无谓缩放。

  6. 生成首页和内容画面

    所有图片进入同一画布处理流程;只有首页叠加主题、副标题、遮罩、描边和阴影。内容图保持干净,避免标题重复。

    关键模块scripts/make_homepage_bg.py
  7. 构建图片时间线

    单图时覆盖全部音频。多图时播放 1 → 2 → … → N → 1,首尾首页各不超过 3 秒,其余内容图均分剩余时长;短音频按所有播放段均分,不产生负时长。

  8. 检测音频停顿

    FFmpeg silencedetect 使用约 -38 dB、0.15 秒参数提取停顿,排除头尾静音后,选取最长的“句数减一”个停顿作为句界,再恢复时间顺序。

  9. 预渲染逐句字幕

    PIL 将每句字幕绘制成透明 PNG,提供颜色、描边、阴影和自动换行。存在首页副标题时,字幕区域从副标题下方开始,并自动缩小字号避免越界。

  10. 使用绝对时间戳合成

    每个字幕使用 overlay enable='between(t,t0,t1)' 显示。所有字幕、背景和音频在一个 FFmpeg 命令中完成,避免多次转码和逐句累计误差。

    关键模块scripts/compose_video.py
  11. 按内容选择帧率

    无字幕单图使用 1 fps;无字幕多图至少 5 fps,并根据最短图片段自适应提高;有字幕使用 10 fps,将时间对齐误差控制在约 100 ms 内。

  12. 硬件编码与自动回退

    macOS 首选 h264_videotoolbox + aac_at。VideoToolbox 或 AudioToolbox 当前不可用时,自动回退 libx264 ultrafast + AAC,任务无需用户重新提交。

  13. 解决桌面启动环境差异

    从桌面 App 启动时往往没有 Homebrew PATH。程序依次探测 /opt/homebrew/bin/usr/local/bin/opt/local/bin,再回退系统查找,保证能找到 FFmpeg 与 ffprobe。

  14. 汇总结果与历史记录

    结果 JSON 写入音频时长、视频时长、源图尺寸、输出尺寸、方向、字幕状态、图片数和同步表。成品复制到统一输出目录,文件名沿用首页图片主体,同名自动追加序号。

阶段四

把两套应用串成十万字、二十万字级项目。

  1. 按章节建立项目清单

    项目规模不设置业务层固定篇幅上限。10 万字可以作为一个受保护任务或多个章节任务;20 万字及更大项目按书、章、节拆成批次。每个批次记录文本范围、音色、模型、参数、随机种子、输出文件和状态。

  2. 任务内继续安全分段

    “项目批次”解决规模问题,“模型安全片段”解决推理稳定性。即使一个章节包含几万字,送入模型的每次推理仍控制在该模型经过验证的安全范围。

  3. 逐段落盘与可恢复执行

    生成一个片段就落盘并更新清单。发生暂停、取消、机器重启或单段失败时,从未完成的片段继续,而不是从项目开头重做。

  4. 统一合并与章节边界

    按清单顺序合并音频,在章节之间插入可配置静音或交叉淡化。最终既可交付单章文件,也可合成整本长音频。

  5. 长视频由音频时长驱动

    视频合成本身没有写死分钟数上限,总时长取决于音频。数小时内容可以输出为单个 MP4,也可以按章节拆成多集;实际限制来自磁盘空间、编码时间和目标平台上传规则,而不是页面人为截断。

  6. 批量视频保持确定性

    每集使用明确的首页图、内容图顺序、音频、文案和参数。结果清单记录成品路径、时长、画面尺寸、字幕句数与校验状态,便于后续平台发布。

准确表述:当前 TTS WebUI 单任务设有 100,000 字符保护上限;20 万字及更大项目通过章节和批次队列完成。这样既能承接大规模内容,又不会把“无限”误解为一次性把整本书塞进模型。

阶段五

测试、验收与失败恢复。

测试对象正常路径边界路径验收证据
TTS 模型切换五个引擎逐一加载并生成切换时释放旧模型;隐藏无效参数输出文件、参数档案、内存释放日志
音色克隆清晰参考音频和匹配原文缺原文、本地 ASR、不同音色缓存隔离参考转写、音色条件、试听结果
长文生成多段连续输出暂停、取消、token 触顶、异常时长进度、partial WAV、重试日志
图片时间线单图与三图短音频、奇数尺寸、EXIF 旋转ffconcat、播放顺序、输出宽高
字幕同步停顿充足的逐句口播停顿不足、长字幕、副标题避让同步表、PNG 尺寸、帧对齐时间
视频编码VideoToolbox + AudioToolbox硬件编码失败后软件回退ffprobe 编码、时长、播放检查

“页面显示完成”不是验收。音频要能播放且无明显截断;视频要核对时长、宽高、H.264/AAC 编码、首尾画面、字幕边界、下载名和输出目录。失败时保留日志与中间产物,先定位具体阶段,再决定重试、降级或调整输入。

阶段六

让人能看懂,也让 AI 能准确检索。

  1. 每个主题使用独立 URL

    首页、IndexTTS2、视频生成器、完整开发过程和模型比较分别有独立中英文地址,避免所有内容埋在一次 JavaScript 切换中。

  2. 先写事实,再写宣传

    页面保留模型名、运行时、采样率、输入条件、接口、状态、算法、优点、缺点和限制。检索系统可以直接抽取事实,不需要从口号推断。

  3. 提供结构化入口

    HTML 中加入 SoftwareApplication、HowTo、FAQPage 与 ProfessionalService Schema;同时提供 llms.txtllms-full.txt、模型 JSON、开发步骤 JSON 和 sitemap。

  4. 保持中英文一一对应

    使用 hreflang 标记语言版本,中文为默认;英文页面保留相同事实结构,方便跨语言 Agent 与搜索引擎建立对应关系。

  5. 公开可访问并持续验证

    部署后确认页面、图片、纯文本索引和 JSON 端点均返回成功状态。后续每次修改继续更新最后核对日期与结构化数据。

下一步

从技术阅读进入具体方案。