本文へ移動
cccskills
無料GitHub で公開

voice-clone-tts

把自媒体口播文案变成配音音频。自动做章节/分段拆分,用 MiniMax TTS(含用户本人的复刻音色)逐句合成,按采样帧精确拼接,停顿节奏可控。默认只出音频,需要字幕时可加出 SRT。

触发场景:(1) 用户给一段文案要求"生成配音"、"做成音频"、"配个音"、"转成语音";(2) 口播稿/自媒体文案转成品音频;(3) 用户要"出个口播"、"用我的声音读一遍";(4) 需要复刻声音做 TTS;(5) 用户要文案的 SRT 字幕;(6) 使用 /voice-clone-tts 命令。

インストール方法を見る

含まれるファイル(7)

  • SKILL.md12.0 KB
  • config.json452 B
  • references/voices.md2.5 KB
  • scripts/build.py8.4 KB
  • scripts/clone_voice.sh3.1 KB
  • scripts/segment.py12.5 KB
  • scripts/synth.py11.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

文案 → 配音

给一段口播文案,产出 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

跑完必须做验证那一节的时间轴核对,再把结果告诉用户。

为什么逐句合成,而不是把整篇丢给 TTS

mmx speech synthesize 支持到 10k 字符,整篇一次性合成技术上可行。不这么做有四个理由:

  1. 停顿可控。 整段合成的停顿由模型即兴决定;逐句合成才能让章节 700ms、 自然段 400ms、句子 180ms 各归各位,口播节奏才稳。
  2. 增量续跑。 改一句只重合成一句(靠文件名指纹识别),改一版文案不用重跑全篇。
  3. 失败粒度细。 撞限流时只补失败的那几段,不是整篇重来。
  4. 超长文案不受 10k 限制。

语调不是理由。 实测同一段 435 字文案,停顿两侧音高跳变:逐句拼接 26.4%、 整段合成 28.2%,逐句反而略优(MiniMax 内部很可能本来就按句处理)。 所以不要为了"语调更连贯"改成整段合成,那会白白丢掉上面四条。

三条实测得出的硬约束

1. 必须用 WAV 合成,不能用 MP3。 MP3 的 duration_ms 比真实音频长 54–59ms (编码器 padding),逐段累加会持续漂移;WAV 误差 <1ms。

段MP3 API/实测WAV API/实测
12736 / 2681.9 (+54)2728 / 2728.4 (+0.4)
24320 / 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、最坏 230msbuild.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/)保留不删:改文案时能增量续跑,只重合成变化的段。

工作流

步骤 1:分章(这一步由你做,不是脚本)

「合理拆分章节」是语义判断,正则做不好。先读文案,判断结构:

  • 文案已有章节标记(## 标题、一、、【标题】、第一章)→ 直接进步骤 2,segment.py 能识别。
  • 文案是大段白文 → 你来读懂内容、找逻辑断点,写成 chapters.json:
[
  {"title": "开场钩子", "text": "第一段……\n\n第二段……"},
  {"title": "核心论证", "text": "……"}
]

分章原则:按论述逻辑切(钩子/铺垫/论证/转折/结论),单章 200–600 字为宜。段落之间用空行分隔——空行会成为 400ms 停顿,是听感上的呼吸点。

步骤 2:切分

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

输出会报告分段数、计费字符数、单条宽度分布。检查一下最大宽度是否超限,超限说明有超长无标点句。

步骤 3:合成

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 清理。

步骤 4:拼接出片

python3 $S/build.py segments.json -o voiceover

产出 voiceover.mp3。

需要 SRT 时

默认不出。用户明确要字幕文件时:

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 调默认值,或用命令行覆盖单次运行。

项默认说明
voicenanmiVoice2026a个人复刻音色,默认就用它,无需每次指定
fallback_voiceChinese (Mandarin)_Radio_Host仅在音色失效的报错提示里出现,不会自动切换
modelspeech-2.8-hd也可 speech-2.8-turbo(更快更便宜)
max_chars20单条字幕最大视觉宽度(中文字=1,ASCII=0.5)
min_chars8低于此宽度的片段会并入相邻段

段间停顿(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 字符,首字符必须字母,只允许字母/数字/-/_,末位不能是 -/_。

两个坑:

  • 需要账号已完成实名认证,否则复刻接口报错
  • 复刻音色 7 天内未被正式调用会被自动删除,长期不用要定期合成一次保活

排错

现象原因
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。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

将口播稿、文章或已有音频与 SRT 制作为可自动播放的 16:9 网页视频演示(Vite + React + TypeScript)。用连续视觉场景、证据画面、卡片状态变化与 MG 动画解释内容;支持点击推进、整段原声驱动、按绝对时间验帧,以及预览页一键导出 1K/2K/4K MP4。适用于 B 站、YouTube、视频号口播配画面与产品演示。

日本語の概要は準備中です。原文の説明を表示しています。

NanmiCoder/creator-dev-kit912026年9月18日 更新

NanmiCoder のスキルをすべて見る

このスキルの問題を報告する