将口播稿、文章或已有音频与 SRT 制作为可自动播放的 16:9 网页视频演示(Vite + React + TypeScript)。用连续视觉场景、证据画面、卡片状态变化与 MG 动画解释内容;支持点击推进、整段原声驱动、按绝对时间验帧,以及预览页一键导出 1K/2K/4K MP4。适用于 B 站、YouTube、视频号口播配画面与产品演示。
The English summary is being prepared. Showing the original description.
把自媒体口播文案变成配音音频。自动做章节/分段拆分,用 MiniMax TTS(含用户本人的复刻音色)逐句合成,按采样帧精确拼接,停顿节奏可控。默认只出音频,需要字幕时可加出 SRT。
触发场景:(1) 用户给一段文案要求"生成配音"、"做成音频"、"配个音"、"转成语音";(2) 口播稿/自媒体文案转成品音频;(3) 用户要"出个口播"、"用我的声音读一遍";(4) 需要复刻声音做 TTS;(5) 用户要文案的 SRT 字幕;(6) 使用 /voice-clone-tts 命令。
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
给一段口播文案,产出 voiceover.mp3。
默认不出 SRT——用户在剪映里做字幕,那边能直接可视化调时间轴,比导 SRT 顺手;
而且 macOS 不认识 .srt 扩展名,双击会触发 Gatekeeper 警告,反而添乱。
用户明确要字幕文件时才加 --srt(能力仍在,见「需要 SRT 时」一节)。
音色已固化在 config.json,直接跑就是用户本人的复刻声音,不需要问用户选音色,
更不要重新复刻——复刻是一次性的独立动作,只有用户明确要求换声音时才碰 clone_voice.sh。
四条命令跑完全程,不要逐步征求同意,一口气做完再汇报:
S=~/.claude/skills/voice-clone-tts/scripts
mkdir -p voiceover-主题 && cd voiceover-主题 # 文案写进 script.md
python3 $S/segment.py script.md -o segments.json
python3 $S/synth.py segments.json
python3 $S/build.py segments.json -o voiceover
跑完必须做验证那一节的时间轴核对,再把结果告诉用户。
mmx speech synthesize 支持到 10k 字符,整篇一次性合成技术上可行。不这么做有四个理由:
语调不是理由。 实测同一段 435 字文案,停顿两侧音高跳变:逐句拼接 26.4%、 整段合成 28.2%,逐句反而略优(MiniMax 内部很可能本来就按句处理)。 所以不要为了"语调更连贯"改成整段合成,那会白白丢掉上面四条。
1. 必须用 WAV 合成,不能用 MP3。 MP3 的 duration_ms 比真实音频长 54–59ms
(编码器 padding),逐段累加会持续漂移;WAV 误差 <1ms。
| 段 | MP3 API/实测 | WAV API/实测 |
|---|---|---|
| 1 | 2736 / 2681.9 (+54) | 2728 / 2728.4 (+0.4) |
| 2 | 4320 / 4260.9 (+59) | 4388 / 4388.6 (+0.6) |
synth.py 已强制 --format wav,不要改。这条即使不出 SRT 也要守——
成品时长会不准,和视频轨对不齐。
2. 一个分段 = 一次 TTS 调用 = 一个 WAV。 严格一一对应,才谈得上增量续跑和精确时间轴。
3. 时间轴按采样帧算,不要用 API 的 duration_ms。 build.py 用 Python wave 模块
按写入输出流的 frame 数累加,时间戳和音频出自同一个计数器,数学上必然一致。
顺带一提 --subtitles 为什么没用:41 字文案只返回一条 9 秒字幕;
435 字返回 5 条、每条 11–16 秒——按时长切不按句切,做视频字幕不可用。
逐句合成再拼接,最容易被质疑的就是「听起来断不断」。四项都实测过:
| 项 | 实测结果 | 处理方式 |
|---|---|---|
| 拼接处爆音 | 50 个边界零跳变,段尾样本值全为 0 | 天然安全,MiniMax 输出首尾即静音 |
| 段间音量 | RMS 标准差 0.56dB,最大偏离 ±1.4dB | 无需处理(人耳需 3dB 才明显) |
| 停顿节奏 | 每段自带首尾静音中位 60ms、最坏 230ms | build.py 默认修剪,停顿改由 silence_ms 独控 |
| 跨句语调 | 见下 | 无需处理 |
关于语调:整段合成并不比逐句拼接更连贯。 拿同一段 435 字文案做过 A/B:
| 版本 | 停顿两侧音高跳变(中位) | >25% 占比 |
|---|---|---|
| 整段一次性合成 | 28.2% | 57% |
| 逐句合成后拼接 | 26.4% | 53% |
逐句版反而略优,差异在噪声范围内——MiniMax 内部很可能本来就是按句处理的。 所以不要为了"语调连贯"改成整段合成,那会丢掉句子级时间戳,得不偿失。
顺带确认过:speech synthesize 支持到 10k 字符,长文本本身没问题;
但 435 字的 --subtitles 只返回 5 条、每条 11–16 秒(按时长切,不按句),
做视频字幕依然不可用。这条路堵死了,逐句合成是目前唯一能同时拿到
「精确时间轴 + ≤20 字字幕」的方案。
文案从哪来。 用户通常直接把文案粘在对话里,不是给文件路径。
先把它原样写成 script.md(不要改写、不要润色、不要加标题——用户给什么就是什么,
这是配音稿,改一个字声音就不对了)。用户给的是文件路径时直接用。
产出放哪。 默认在当前工作目录下建 voiceover-<主题短名>/,
所有中间件和成品都放里面,不要污染用户的项目根目录。
用户明确指定了目录就用他给的。开工前用一句话告诉用户产出位置。
目录长这样:
voiceover-<主题>/
├── script.md # 原始文案
├── segments.json # 切分结果(中间态,可校对、可续跑)
├── wav/ # 逐段音频(中间件)
└── voiceover.mp3 # ← 成品
中间件(segments.json、wav/)保留不删:改文案时能增量续跑,只重合成变化的段。
「合理拆分章节」是语义判断,正则做不好。先读文案,判断结构:
## 标题、一、、【标题】、第一章)→ 直接进步骤 2,segment.py 能识别。chapters.json:[
{"title": "开场钩子", "text": "第一段……\n\n第二段……"},
{"title": "核心论证", "text": "……"}
]
分章原则:按论述逻辑切(钩子/铺垫/论证/转折/结论),单章 200–600 字为宜。段落之间用空行分隔——空行会成为 400ms 停顿,是听感上的呼吸点。
S=~/.claude/skills/voice-clone-tts/scripts
python3 $S/segment.py script.md -o segments.json
# 或用你写好的章节骨架
python3 $S/segment.py script.md --chapters chapters.json -o segments.json
输出会报告分段数、计费字符数、单条宽度分布。检查一下最大宽度是否超限,超限说明有超长无标点句。
python3 $S/synth.py segments.json
并发默认 3,不要调高。 实测并发 6 跑 51 段时,有 19 段撞 rate limit exceeded(RPM);
降到 3 之后 51 段零失败。脚本内置自适应节流:撞限流会自动降速,之后慢慢恢复。
中断或失败后重跑同一命令即可续传,已合成的段会跳过。
若仍有大量限流失败,按提示加 --jobs 2 --interval 1.5。
音频文件名带「文本+音色+模型」指纹(0007_a3f2b1c9.wav)。改了文案重跑,
变化的段指纹变、自动重新合成,没变的段照常复用——不会出现「文案改了但音频还是旧的」。
遗留的失效音频用 --prune 清理。
python3 $S/build.py segments.json -o voiceover
产出 voiceover.mp3。
默认不出。用户明确要字幕文件时:
python3 $S/build.py segments.json -o voiceover --srt
时间轴与音频同源(都来自采样帧计数),实测偏差 0.0ms,抽样波形互相关相关度 1.000。
什么时候值得要:文案里有英文专有名词。实测 whisper 转写本 skill 的音频,
数字全对(2736、2681.9、54),但专名大面积出错——
ffprobe→NAS Pro、WAV→Wave、MiniMax→minimax、duration→Duration。
剪映的 ASR 同理。而本 skill 的 SRT 文本就是原稿,一个字不会错。
法律、医疗、技术类文案(「代位权」「折价补偿」「《建工解释二》」这类)尤其明显。
交付时提醒用户:.srt 别双击——macOS 没有默认关联,会随机挑 App 打开,
还可能被 Gatekeeper 拦。直接在剪映里「导入字幕」,或右键用文本编辑打开。
ffprobe -v error -show_entries format=duration -of csv=p=0 voiceover.mp3
实测时长应与 build.py 报告的总时长一致。两者对不上说明有段音频缺失或格式不一致,别交付。
再确认 synth.py 报的是 N/N 段就绪——有失败段却继续 build,成品会缺句子。
改 config.json 调默认值,或用命令行覆盖单次运行。
| 项 | 默认 | 说明 |
|---|---|---|
voice | nanmiVoice2026a | 个人复刻音色,默认就用它,无需每次指定 |
fallback_voice | Chinese (Mandarin)_Radio_Host | 仅在音色失效的报错提示里出现,不会自动切换 |
model | speech-2.8-hd | 也可 speech-2.8-turbo(更快更便宜) |
max_chars | 20 | 单条字幕最大视觉宽度(中文字=1,ASCII=0.5) |
min_chars | 8 | 低于此宽度的片段会并入相邻段 |
段间停顿(silence_ms):子句 80ms / 句子 180ms / 自然段 400ms / 章节 700ms。
嫌节奏赶就调大 sentence;口播感要紧凑就调小。静音时长由我们指定,改了也不影响时间轴精度。
build.py 默认会剪掉每段自带的首尾静音(--no-trim 可关闭),这样实际停顿就等于
上面设定的值,不会因为个别段自带 200ms+ 静音而忽长忽短。附带好处:字幕起点正好卡在
出声瞬间,不再提前 60ms 出现。修剪阈值 --trim-db -45、保留边距 --trim-margin 15
(留边距是为了不切掉爆破音和气声的起始)。
字幕停留:build.py --gap-hold 600 表示间隔 ≤600ms 时字幕延续到下一条开始,避免闪烁。设 0 则严格按语音起止。
mmx 没有 voice clone 命令,走「CLI 上传 + HTTP 复刻」:
$S/clone_voice.sh 素材.mov myVoiceName01 # 底噪明显时加 --denoise
素材要求:10 秒–5 分钟,≤20MB,mp3/m4a/wav(脚本会自动从视频抽音轨并校验)。
voice_id 规则:8–256 字符,首字符必须字母,只允许字母/数字/-/_,末位不能是 -/_。
两个坑:
| 现象 | 原因 |
|---|---|
rate limit exceeded(RPM) | 并发太高。用默认 --jobs 3,严重时 --jobs 2 --interval 1.5,重跑续传 |
voice id not exist | 音色 ID 拼错,或复刻音色已过期被删。mmx speech voices 查系统音色 |
| 成品时长不对/SRT 对不上音频 | 多半是有段落用了 MP3 合成。检查 wav/ 下是否都是 .wav |
| 成品少了句子 | synth.py 有失败段就直接 build 了。先确认它报 N/N 段就绪 |
build.py 报格式不一致 | 某段 WAV 采样率/声道不同,删掉该段 WAV 重跑 synth.py |
| 合成大面积失败 | mmx auth status 查 key;mmx quota 查额度。TTS 走字符计费,不在 Token Plan 面板内 |
| 某段语调突兀 | 该段可能太短。调大 min_chars 让它并入相邻段 |
| 纯中文长句在词中间断开 | 中文没有词边界信号,无标点时只能按宽度切。给文案加逗号是唯一解 |
底层 CLI 的完整命令参考见官方 skill mmx-cli。
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
将口播稿、文章或已有音频与 SRT 制作为可自动播放的 16:9 网页视频演示(Vite + React + TypeScript)。用连续视觉场景、证据画面、卡片状态变化与 MG 动画解释内容;支持点击推进、整段原声驱动、按绝对时间验帧,以及预览页一键导出 1K/2K/4K MP4。适用于 B 站、YouTube、视频号口播配画面与产品演示。
The English summary is being prepared. Showing the original description.