Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Automated video editing skill for talk/vlog/standup videos. Use when: cutting video, splitting video into sentences, merging video clips, extracting audio, transcribing speech, auto-editing oral presentation videos, combining selected sentence clips into a final video, generating video cover/thumbnail with title. Requires ffmpeg and whisper.
.claude/skills/leoyeai-video-editing/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 97% | 49 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 113% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 363% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 338% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 148% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 199% | 0% |
根据语音内容,将口播/脱口秀类视频按句子自动切分,然后按用户选择合成带字幕的最终视频。
在执行任何操作之前,先运行环境检测:
bashpython3 scripts/utils.py
这会自动检测平台(macOS/Linux/WSL/Windows)、GPU 类型、可用编码器、Whisper 引擎,并给出诊断报告。
如果缺少依赖,提示用户安装:
brew install ffmpeg(macOS)或 apt install ffmpeg(Linux/WSL)或下载 Windows 版本pip install faster-whisper(推荐,速度快 4 倍)或 pip install openai-whisperpip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple如果项目根目录有 .venv 虚拟环境,运行 Python 脚本前先激活:
bashsource .venv/bin/activate # macOS/Linux/WSL # Windows: .venv\Scripts\activate
/mnt/c/Windows/Fonts/)--mirror 参数强制启用对每个输入视频文件,使用 extract_audio.py 提取音频:
bashpython3 scripts/extract_audio.py "<video_path>"
输出:与视频同目录下的 <video_name>_audio.wav 文件。
使用 transcribe.py 对音频进行语音识别,生成带时间戳的逐句文本:
bashpython3 scripts/transcribe.py "<audio_path>" --model auto --language zh
--model auto:根据硬件自动选择最佳模型(NVIDIA GPU → large-v3,Apple Silicon → large-v3-turbo,集成显卡 → medium,纯 CPU → small)tiny, base, small, medium, large-v3, large-v3-turbo--engine auto:自动检测 faster-whisper(推荐)或 openai-whisper--mirror:中国用户使用镜像源下载模型--language:zh(中文),en(英文),ja(日文)等,也可省略让 whisper 自动检测输出:与音频同目录下的 <video_name>_transcript.json 文件,格式如下:
json{ "segments": [ {"id": 1, "start": 0.0, "end": 2.5, "text": "大家好"}, {"id": 2, "start": 2.5, "end": 5.1, "text": "今天我们来聊一个话题"} ] }
转录后检查:如果文本中有明显的识别错误(如产品名、专有名词),应修正 transcript.json 中的文字后再进行后续步骤。
使用 split_video.py 根据转录结果将视频切分为独立片段:
bashpython3 scripts/split_video.py "<video_path>" "<transcript_json_path>"
输出:在视频同目录下创建 <video_name>_clips/ 文件夹,包含按句子编号命名的片段文件,如 clip_001.mp4, clip_002.mp4 等。
注意:
-ss 后置 + re-encode),确保音频在句子边界精确切断。使用 burn_subtitles.py 为每个片段烧录字幕:
bashpython3 scripts/burn_subtitles.py "<clips_dir>" "<transcript_json_path>"
字幕行为:
fonts/ 目录)--font-path 指定自定义字体文件--font-size 调整字号(默认 48,基于 1080p 自动缩放)输出:<video_name>_clips_subtitled/ 目录,包含带字幕的片段。
注意:此步骤完成后,Phase 4-5 中应使用 _clips_subtitled/ 目录而非 _clips/ 目录。
展示片段列表给用户,格式如下:
视频片段列表:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# | 时间区间 | 内容
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1 | 00:00.0 - 00:02.5 | 大家好
2 | 00:02.5 - 00:05.1 | 今天我们来聊一个话题
3 | 00:05.1 - 00:08.3 | 这个话题非常有意思
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
请选择要合成的片段(示例):
- 连续范围:1-10
- 多个片段:1,3,5,7
- 混合选择:1-4,6,8-10如果有多个视频文件,分别展示每个视频的片段列表,让用户跨视频选择。 选好后可将来自不同视频的片段复制到同一个临时目录中,按顺序重新编号后合成。
等待用户回复选择后,进入 Phase 5。
使用 merge_clips.py 将用户选择的片段合成为最终视频:
bashpython3 scripts/merge_clips.py "<clips_dir>" --select "1-4,6,8" --output "<output_path>"
--select:用户选择的片段编号,支持 1-4(范围)、1,3,5(逐个)、1-4,6,8-10(混合)。--output:输出文件路径,默认为 <clips_dir>/../<video_name>_final.mp4。输出:合成后的最终视频文件。
合成完成后,为视频生成封面图片。
交互流程:
bashpython3 scripts/generate_cover.py "<final_video_path>" --title "封面标题文字" --transcript "<transcript_json_path>"
--title:封面上显示的标题文字--transcript:转录 JSON 路径(当未提供 --title 时,脚本会输出全文供 AI 总结)--font-path:可选,指定自定义字体--output:可选,指定输出路径,默认为 <video_name>_with_cover.mp4注意:
输出:<video_name>_with_cover.mp4
为最终视频添加可视化的章节进度条。
使用 add_chapter_bar.py 在视频上叠加章节时间轴:
bashpython3 scripts/add_chapter_bar.py "<video_path>" --transcript "<transcript_json_path>"
自动行为:
也可以提供自定义章节 JSON:
bashpython3 scripts/add_chapter_bar.py "<video_path>" --chapters chapters.json
chapters.json 格式:
json{ "chapters": [ {"title": "开场", "start": 0.0, "end": 15.0}, {"title": "正题", "start": 15.0, "end": 60.0} ] }
参数说明:
--transcript:从转录 JSON 自动生成章节--chapters:使用自定义章节 JSON--style color(默认):彩色分段,每章不同颜色--style mono:单色风格,灰白交替,更简约--max-chapters:自动分章的最大章节数(默认 8)--font-path:自定义字体--output:输出路径,默认为 <video_name>_chapters.mp4输出:<video_name>_chapters.mp4,同时在终端打印 YouTube 兼容的章节时间戳。
合成完成后,对最终视频执行一次验证流程:
large 模型,base/small 模型中文识别率较低。large 模型约需 2.9GB 下载空间。libass 和 libfreetype。macOS 可通过 brew install ffmpeg 获取。bash ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=PTS/1.25[v];[0:a]atempo=1.25[a]" -map "[v]" -map "[a]" -c:v libx264 -preset fast -crf 18 -c:a aac -b:a 192k output_1.25x.mp4
遇到错误时,先运行环境诊断:
bashpython3 scripts/utils.py
No such filter: 'drawtext' 或 No such filter: 'ass'原因:ffmpeg 编译时未包含 libfreetype(drawtext 所需)或 libass(字幕所需)。
诊断:
bashffmpeg -hide_banner -filters 2>/dev/null | grep -E "drawtext|ass|subtitles"
如果无输出,说明缺少对应滤镜。
解决:
brew install ffmpeg 可能不包含这些库。使用第三方 tap 安装完整版:bash brew tap homebrew-ffmpeg/ffmpeg brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac 该 tap 默认启用 --enable-libfreetype --enable-libass --enable-libfontconfig。
apt install ffmpeg 通常已包含。如果缺少,安装开发依赖后从源码编译:bash sudo apt install libfreetype6-dev libfontconfig1-dev libass-dev
Undefined constant or missing '(' in 'iw*0.5-tw/2'原因:ffmpeg drawtext 的 x 表达式中使用了 tw(text width),但某些 ffmpeg 版本中 tw 在 x 参数的上下文中不可用。
解决:脚本已修复此问题(使用像素值 {pixel_x}-text_w/2 代替 iw*{frac}-tw/2)。如果你修改了脚本并遇到此错误,请使用 text_w 而非 tw,并确保 x 表达式中不包含 iw* 动态计算。
Invalid alpha value specifier '%{eif:...}' (drawtext fontcolor)原因:试图在 fontcolor 参数中嵌入 %{eif} 表达式来实现透明度渐变,但 ffmpeg 不支持在颜色值中使用此语法。
解决:使用 drawtext 的 alpha 参数(独立于 fontcolor),而非试图在 fontcolor=white@'%{eif:...}' 中嵌入表达式。正确写法:
drawtext=text='hello':fontcolor=white:alpha='if(lt(t,1),t,1)'错误写法(会报错):
drawtext=text='hello':fontcolor=white@'%{eif:if(lt(t,1),t,1):d:2}'h264_videotoolbox / h264_nvenc / h264_qsv 报错)原因:检测到的硬件编码器不支持当前的视频参数(如特殊分辨率、色彩空间),或驱动版本不兼容。
诊断:
bashffmpeg -encoders 2>/dev/null | grep -E "nvenc|videotoolbox|qsv|amf"
解决:在脚本命令后添加 --force-cpu 参数(如脚本支持),或手动替换编码参数。也可以在 scripts/utils.py 中临时修改 get_ffmpeg_encoder() 函数,让它直接返回 ("libx264", ["-preset", "fast", "-crf", "18"])。
原因:系统中没有可用的中文字体文件。
诊断:
bashpython3 -c "from scripts.utils import find_chinese_font; print(find_chinese_font())"
如果返回 (None, ...),说明未找到中文字体。
解决:
bash sudo apt install fonts-noto-cjk
/mnt/c/Windows/Fonts/msyh.ttc(微软雅黑),前提是 Windows 已安装该字体。--font-path /path/to/your/font.ttf 参数。fonts/ 目录。原因:网络问题,尤其是中国用户无法访问 HuggingFace。
解决:
--mirror 参数:python3 scripts/transcribe.py audio.wav --mirror --model autobash export HF_ENDPOINT=https://hf-mirror.com
HF_ENDPOINT 后会自动走镜像。pip install faster-whisper 安装失败 / 超时解决:中国用户使用清华镜像:
bashpip install faster-whisper -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn
诊断:
bashwhich ffmpeg && ffmpeg -version | head -1
解决:
bashsudo apt update && sudo apt install ffmpeg
如果系统源的 ffmpeg 版本过旧(< 4.0),使用 PPA:
bashsudo add-apt-repository ppa:savoury1/ffmpeg4 sudo apt update && sudo apt install ffmpeg
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-09 | fail→pass | 13,850 | 6,345 | -54% | 1 | 1 | 0% | 2,812 | 5,988 | +113% | 0 | 0 | — |
case-01 | fail→fail | 26,150 | 3,051 | -88% | 1 | 1 | 0% | 4,877 | 5,164 | +6% | 0 | 0 | — |
case-02 | fail→fail | 27,245 | 4,654 | -83% | 1 | 1 | 0% | 5,748 | 4,870 | -15% | 0 | 0 | — |
case-03 | fail→fail | 22,314 | 2,760 | -88% | 1 | 1 | 0% | 5,087 | 4,982 | -2% | 0 | 0 | — |
case-04 | fail→pass | 6,540 | 2,658 | -59% | 1 | 1 | 0% | 1,084 | 5,014 | +363% | 0 | 0 | — |
case-05 | fail→pass | 6,842 | 4,052 | -41% | 1 | 1 | 0% | 1,230 | 5,392 | +338% | 0 | 0 | — |
case-06 | fail→pass | 12,069 | 2,988 | -75% | 1 | 1 | 0% | 2,055 | 5,087 | +148% | 0 | 0 | — |
case-07 | fail→pass | 9,906 | 3,235 | -67% | 1 | 1 | 0% | 1,750 | 5,234 | +199% | 0 | 0 | — |
case-08 | fail→pass | 12,782 | 10,370 | -19% | 1 | 1 | 0% | 2,505 | 6,281 | +151% | 0 | 0 | — |
case-10 | fail→pass | 10,078 | 4,640 | -54% | 1 | 1 | 0% | 1,901 | 5,537 | +191% | 0 | 0 | — |
case-11 | fail→fail | 7,176 | 6,991 | -3% | 1 | 1 | 0% | 1,312 | 6,010 | +358% | 0 | 0 | — |
case-12 | pass→pass | 13,075 | 4,321 | -67% | 1 | 1 | 0% | 2,060 | 5,290 | +157% | 0 | 0 | — |
case-13 | fail→pass | 12,331 | 6,633 | -46% | 1 | 1 | 0% | 1,888 | 5,778 | +206% | 0 | 0 | — |
case-18 | fail→pass | 11,176 | 3,854 | -66% | 1 | 1 | 0% | 1,805 | 5,219 | +189% | 0 | 0 | — |
case-14 | fail→pass | 9,616 | 4,101 | -57% | 1 | 1 | 0% | 1,471 | 5,293 | +260% | 0 | 0 | — |
case-15 | pass→pass | 12,397 | 10,846 | -13% | 1 | 1 | 0% | 1,943 | 6,366 | +228% | 0 | 0 | — |
case-16 | fail→pass | 6,444 | 2,533 | -61% | 1 | 1 | 0% | 1,146 | 5,039 | +340% | 0 | 0 | — |
case-17 | fail→pass | 7,589 | 3,741 | -51% | 1 | 1 | 0% | 1,440 | 5,199 | +261% | 0 | 0 | — |
case-19 | fail→fail | 11,297 | 6,817 | -40% | 1 | 1 | 0% | 1,804 | 5,639 | +213% | 0 | 0 | — |
case-20 | pass→pass | 9,139 | 5,218 | -43% | 1 | 1 | 0% | 1,513 | 5,658 | +274% | 0 | 0 | — |
case-21 | fail→pass | 24,479 | 3,389 | -86% | 1 | 1 | 0% | 2,239 | 5,247 | +134% | 0 | 0 | — |
case-22 | fail→pass | 13,033 | 11,696 | -10% | 1 | 1 | 0% | 2,178 | 6,567 | +202% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +64 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.