video-clipper
Pass从长视频(直播回放、会议录像、播客)中批量生成短视频切片。基于转写文稿精确定位观点边界,自动去除静音卡顿和口吃,输出音画同步的短视频。适用于:直播切片、会议精华提取、短视频二创、播客精彩片段。
(0)
1
2
2
Install Skill
Skills are third-party code from public GitHub repositories. SkillHub scans for known malicious patterns but cannot guarantee safety. Review the source code before installing.
Install globally (user-level):
npx skillhub install yfge/video-skills-suite/video-clipperInstall in current project:
npx skillhub install yfge/video-skills-suite/video-clipper --projectSuggested path: ~/.claude/skills/video-clipper/
SKILL.md Content
---
name: video-clipper
description: 从长视频(直播回放、会议录像、播客)中批量生成短视频切片。基于转写文稿精确定位观点边界,自动去除静音卡顿和口吃,输出音画同步的短视频。适用于:直播切片、会议精华提取、短视频二创、播客精彩片段。
---
# Video Clipper — 长视频智能切片
## 依赖
- **ffmpeg / ffprobe**: 视频切片、静音检测、trim+concat(系统已安装)
- **whisperx venv**: `scripts/.venv-whisperx/`(用于二次质检)
- **转写 JSON**: 需要 `video-to-text` skill 的带时间戳 JSON 输出(用于精确定位和口吃检测)
- **脚本集**(均在 `workspace/scripts/`):
- `batch-clip-v4.sh` — 主批量切片脚本(去静音 + 去口吃 + crossfade)
- `smart-silence.py` — 智能静音处理(长静音删除 / 短静音压缩)
- `stutter-detect.py` — 口吃检测(基于原始转写 JSON)
- `clip-postcheck.py` — WhisperX 二次扫描 + 自动修复残留口吃
- `batch-postcheck.sh` — 批量二次质检脚本
- `iterate-until-clean.py` — 单条 clip 反复迭代(转写→检测→修复→再转写)直到零问题
## 完整四阶段流程
```
Phase 1: 素材准备
Phase 2: 切片点定位(观点边界)
Phase 3: 批量切片(去静音 + 去口吃 + crossfade)← batch-clip-v4.sh
Phase 4: 二次质检(WhisperX 重转写 → 残留口吃检测修复)← batch-postcheck.sh
```
---
### Phase 1: 素材准备
1. **确认输入文件**,获取总时长
2. **CJK 文件名处理**:含中文则建英文 symlink,后台 nohup 命令需用英文路径
```bash
ln -sf "/path/to/直播回放.mp4" /tmp/livestream-input.mp4
```
3. **确认转写 JSON 存在**:`video-to-text` skill 的输出(含 word_segments 级时间戳)
---
### Phase 2: 切片点定位
**最关键的一步——不能凭直觉猜时间戳,必须基于转写文字精确定位。**
#### 2.1 候选话题来源
- 优先用 `insight-extractor` 输出中的金句和时间戳
- 或人工给出话题名,再用转写 JSON 定位
#### 2.2 用转写 JSON 校准边界
```python
import json
with open("transcript.json") as f:
data = json.load(f)
for seg in data["segments"]:
if START <= seg["start"] <= END:
m, s = divmod(int(seg["start"]), 60)
h, m = divmod(m, 60)
ts = f"{h}:{m:02d}:{s:02d}" if h else f"{m}:{s:02d}"
print(f" [{ts}] {seg['text'].strip()}")
```
#### 2.3 精确边界原则
1. **观点完整**:从引入/铺垫 → 结论/反应,不截断
2. **前不带冗余**:切掉闲聊、过渡、无关内容
3. **后不拖尾**:观点讲完即切,不带下一话题开头
4. **扩展确认**:向前后各扩 2-3 分钟,确认边界无误
#### 2.4 时间戳格式
- < 60 分钟:`MM:SS`(如 `41:40`)
- ≥ 60 分钟:`H:MM:SS`(如 `1:50:08`)
---
### Phase 3: 批量切片(主流程)
使用 `scripts/batch-clip-v4.sh`。
#### 三层清理管道
1. **精确粗切** (`ffmpeg -ss ... -to ...`):从原视频按时间段切出原始片段
2. **静音 + 口吃跳切** (`smart-silence.py` + `stutter-detect.py`):
- 长静音(≥0.5s):完全跳过
- 短静音(0.25-0.5s):压缩到 0.12s(保留呼吸感)
- 口吃(重复词/短语):基于原始转写 JSON 检测,跳过第一次出现
3. **filter_complex trim+concat + crossfade**:
- 视频:plain concat(避免视觉闪烁)
- 音频:链式 `acrossfade`(每拼接点 20ms,消除"咔哒"感)
#### ⚠️ 关键约束
- **不能用 `select/aselect`**:长视频音视频时间基不同,会产生漂移
- **必须用 `nohup` 后台运行**:14 条 × 每条约 2-3 分钟,总耗时 ~20-30 分钟
- **macOS zsh 无 `mapfile`**:用 `while IFS= read -r line` 替代
- **时间戳 >59:59 时**:必须用 `H:MM:SS` 格式(`109:30` → `1:49:30`)
#### 运行方式
```bash
# 确认 symlink 存在
ln -sf "/path/to/原始视频.mp4" /tmp/livestream-input.mp4
# 后台运行
nohup bash workspace/scripts/batch-clip-v4.sh > /tmp/batch-clip-v4.log 2>&1 &
# 监控
tail -f /tmp/batch-clip-v4.log
```
#### 修改切片列表
编辑 `batch-clip-v4.sh` 中的 `clips=()` 数组,格式为 `"start|end|name"`:
```bash
clips=(
"30:16|31:58|01-胆子够大"
"1:50:08|1:52:20|02-AI后背发凉"
...
)
```
---
### Phase 4: 二次质检(WhisperX post-check)
**为什么需要二次质检?**
口吃检测基于原始转写 JSON,但原始转写有时会漏掉某些口吃(没有转写出来)。
编辑后的 clip 可能仍含残留口吃,需要用 WhisperX **重新转写 clip 本身**,再做检测。
```
原始转写 JSON → stutter-detect.py → 跳切 → clip
↓
clip-postcheck.py(WhisperX 重转写)
↓
发现残留 → 自动二次修复
```
#### 运行 post-check
```bash
# 激活 whisperx venv
source scripts/.venv-whisperx/bin/activate
# 单条检测(不修复,只报告)
python3 scripts/clip-postcheck.py clips/02-AI后背发凉.mp4
# 单条检测 + 自动修复(-fixed.mp4 会替换原文件)
python3 scripts/clip-postcheck.py clips/02-AI后背发凉.mp4 --fix
# 批量检测 + 自动修复全部 clips/
bash scripts/batch-postcheck.sh
```
#### clip-postcheck.py 检测项
1. **单字重复**(AA 型):运运、对对对 → 保留最后一个
2. **短语重复**(ngram 2-4 字):就是就是、当时的当时 → 保留后一个
3. **低置信度簇**:3 个以上 score<0.05 的连续字,且与后文重叠 → 标记为跳切残留
**有效叠词白名单(不误判)**:试试、看看、谢谢、刚刚、常常、爷爷、妈妈 等 100+ 词
#### 单条反复迭代(最严格模式)
对质量要求极高的 clip,用 `iterate-until-clean.py`:
```bash
source scripts/.venv-whisperx/bin/activate
python3 scripts/iterate-until-clean.py clips/02-AI后背发凉.mp4
```
每轮:WhisperX 转写 → 检测 → 修复 → 替换 → 再转写验证。
最多 5 轮,通常 1-2 轮收敛。
#### 每条耗时
WhisperX 转写 1 分钟 clip ≈ 60-90 秒(CPU)。
14 条全部 post-check ≈ 15-20 分钟。**务必后台运行**。
---
### Phase 5: 最终检查
```bash
for f in clips/*.mp4; do
[ -f "$f" ] || continue
sz=$(du -h "$f" | cut -f1)
dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$f" 2>/dev/null | cut -d. -f1)
min=$((dur/60)); sec=$((dur%60))
printf "%-35s %5s %d:%02d\n" "$(basename "$f")" "$sz" "$min" "$sec"
done
```
---
## 输出规格
- **位置**:`workspace/clips/<编号>-<名称>.mp4`
- **命名**:`01-胆子够大.mp4`、`02-AI后背发凉.mp4`
- **编码**:H.264 CRF23 + AAC 128kbps + faststart
- **大小**:3-25MB/条(取决于时长)
- **压缩率**:比原始切片平均短 20-30%(静音 + 口吃 + crossfade)
---
## 与其他 Skill 的衔接
```
video-to-text → 转写 JSON(时间戳 + 口吃检测来源)
↓
insight-extractor → 观点摘要(切片候选来源)
↓
video-clipper → 短视频切片(本 skill)
├── Phase 3: batch-clip-v4.sh(去静音 + 去口吃 + crossfade)
└── Phase 4: batch-postcheck.sh(WhisperX 二次质检)
↓
(人工 / 剪映加字幕)→ 发布短视频平台
```
---
## 踩坑记录
| 问题 | 原因 | 解决 |
|------|------|------|
| 音画不同步 | `select/aselect` 滤镜音视频时间基不同 | 改用 `trim/atrim + concat` |
| 时间戳不认 | `109:30` 格式超过 59:59 | 改为 `H:MM:SS`(`1:49:30`)|
| macOS zsh 报错 | `mapfile` 不存在 | 用 `while IFS= read -r line` |
| 中文文件名乱码 | nohup 后台 + CJK 路径 | 建英文 symlink |
| exec session 超时 | 15-30 分钟任务被 SIGTERM | 所有批量任务必须 `nohup` |
| 残留口吃 | 原始转写漏识别,stutter-detect 抓不到 | Phase 4 WhisperX post-check |
| 跳切"咔哒"声 | trim+concat 拼接点音频突变 | 每拼接点加 20ms `acrossfade` |
| 口吃误判叠词 | 试试/看看/谢谢 被当作重复 | `VALID_REDUP` 白名单过滤 |
---
## 性能参考
| 切片数 | 总原始时长 | Phase 3 耗时 | Phase 4 耗时 |
|--------|-----------|-------------|-------------|
| 6 条 | ~15 min | ~8 min | ~10 min |
| 14 条 | ~35 min | ~20 min | ~20 min |
| 20 条 | ~50 min | ~30 min | ~28 min |