Fork 自 sunyuzheng/lizheng-video-production(课代表视频后期流水线)。原仓库面向视频内容资产生产,本 fork 专注一个方向:把录好的口播/播客音频自动剪好。
Local-first podcast audio editing for Chinese spoken-word content: transcribe locally (Qwen3-ASR on Apple Silicon), then cut unnatural pauses, re-takes, repeated sentences and filler words based on the transcript. Supports per-speaker processing (e.g. speed up one speaker 1.25x, remove only their fillers). All LLM steps (proofreading, semantic editing, shownotes) are done by your in-conversation agent (Kimi / Claude Code) — no API keys, no external CLIs required.
你录完一期节目,把 MP3 丢给它,它会:
- 本地转录:mlx-qwen3-asr,完全离线,支持热词注入(人名、术语不会听错),输出字级时间戳
- 剪停顿:静音检测 + 字幕间隙双路判断,剪掉不自然的停顿,留 0.3 秒气口,切口躲开字头字尾
- 剪重讲:说错了重说的部分,留说顺的最后一遍。句子级比对之外还有字符流级检测,转录没标点也能抓到
- 剪水词:嗯、呃、那个、就是……用字级时间戳精确定位,嵌在流畅句子里的有效词不动
- 按人处理:双人对话能分出谁在说(基频 + 声纹双路交叉验证),可以只给某位嘉宾 1.25 倍速、只剪他/她的水词
- AI 接力:精校字幕、语义剪辑(换个说法的重讲、false start、废话)由对话中的 Kimi 完成,最后产出小宇宙 shownotes(标题、简介、mm:ss 章节时间戳、金句)
实测:一期 48 分 33 秒的双人对谈,机器剪辑 + 语义剪辑 + 单人倍速 + 去水词之后,成品 34 分 29 秒,压缩 29%,全程人工干预只是听了一遍确认。
- Apple Silicon Mac(M1/M2/M3/M4)
- ffmpeg(
brew install ffmpeg) - 首次运行自动下载约 6GB 本地模型,之后完全离线
git clone https://github.com/coding-with-yiqi/podcast-edit.git
cd podcast-edit
python3 -m venv venv
venv/bin/pip install -r requirements.txt按人处理(倍速/分人剪水词)需要额外的声纹库:
venv/bin/pip install resemblyzervenv/bin/python tools/edit_audio.py 你的音频.mp3 --seeds 主播A 嘉宾B --num-speakers 2跑完后音频旁边会出现:
| 文件 | 说明 |
|---|---|
音频名.edited.mp3 |
剪好的成品音频 |
音频名.edited.srt |
与成品对齐的新字幕 |
音频名.final.srt |
剪辑前的完整断句字幕 |
音频名.cut_report.md |
剪辑报告:每处剪掉的时间、原因、原话 |
中间产物在 音频名_process/,其中 cuts.json 是全部剪辑决定,手动改它再重跑 render.py 就能微调任何一刀。
# 1. 声纹分离(需要 resemblyzer):给每个说话人一段参考录音时间
venv/bin/python tools/speaker_diarize.py 音频.mp3 \
--qwen-json 音频名_process/音频名.qwen.json \
--ref 主播A=0.8:10.6 --ref 嘉宾B=12.4:13.2 -o 音频名_process/
# 2. 只给低音说话人 1.25 倍速 + 剪他的水词,生成汇总剪辑清单
venv/bin/python tools/speedup_speaker.py 音频.mp3 音频名_process/cuts.json \
--qwen-json 音频名_process/音频名.qwen.json -o 音频名_process/ \
--speakers 主播A 嘉宾B --speed-speaker 主播A --speed 1.25
# 3. 按汇总清单重渲染
python3 tools/render.py 音频.mp3 音频名_process/音频名.cuts.merged.json \
--srt 音频名_process/音频名.final.srt -o .| 参数 | 默认值 | 作用 |
|---|---|---|
--seeds 词1 词2 |
无 | 热词,转录认准人名和术语 |
--pause-threshold |
0.8 | 停顿超过几秒算不自然 |
--keep-pause |
0.3 | 剪停顿时保留的气口长度 |
--repeat-similarity |
0.72 | 句子相似度达到多少判定重讲 |
--repeat-window |
45 | 重讲往回找多少秒 |
--speed |
1.25 | 倍速(speedup_speaker) |
--skip-* |
- | 跳过转录/断句/分析/渲染单步 |
这个工具的设计是「机器做确定性的事,AI 做判断的事」。机器流水线跑完后,把字幕交给对话中的 Kimi(或 Claude Code):
- 精校:改同音字、统一专有名词(产出一个错字都没有的字幕)
- 语义剪辑:机器只能剪字面重复,「换个说法重讲一遍」要靠 AI 读字幕找出来,提案合并进 cuts.json 重渲染
- shownotes:AI 读剪后字幕,产出小宇宙发布物料(标题、简介、mm:ss 章节、金句、转发文案)
用 Kimi Code 的话,skills/podcast-edit/ 是可以直接加载的 skill,包含完整的接力流程和踩坑记录。
├── tools/ # 剪辑流水线脚本(本 fork 新增 8 个)
├── skills/podcast-edit/ # 可加载的 agent skill(SKILL.md + 参考文档)
├── docs/ # 说明稿(非技术用户版)、上游 README 存档
├── examples/ # 合成示例音频 + 完整示例输出
├── skill/ tools(其余) data/ # 上游课代表仓库原样保留的内容
└── requirements.txt
- 仅支持 Apple Silicon(mlx-qwen3-asr 的硬限制)
- F0 基频分人适合音高差异大的组合(如男女声);两个音高接近的说话人用 speaker_diarize.py 的声纹模式
- 语义剪辑依赖对话中的 AI,不在脚本内自动完成
- 转录、断句的思路来自上游课代表仓库,感谢作者 sunyuzheng 开源
- 本 fork 新增内容(tools/ 下 analyze_cuts.py、render.py、edit_audio.py、find_fillers.py、speaker_diarize.py、speedup_speaker.py、transcribe.py,skills/、docs/、examples/)以 MIT 许可证发布
- 上游原有文件版权归原作者所有;上游未附带许可证文件,其代码遵循 GitHub 平台 fork 条款使用