AI自动化剪辑:三个Skill打造从长视频到成片的流水线 📅 发布时间:2026/8/31 3:05:49 👁 浏览次数: 一条短视频从拿到原始素材到发布通常要经历粗剪、去废片段、加字幕、挑高光、配乐、转场、导出这几个环节。如果你只是偶尔剪一条 vlog用剪映、Premiere 手动拖一拖也能接受但如果你每周要处理几条长访谈、课程回放、直播切片就会明显感觉到真正耗时间的不是“剪辑操作”而是反复在时间轴上做判断——哪些片段值得留哪几句话信息密度最高哪里该切一刀。我用 AI 编程助手的方式做自动化剪辑把整个流程拆成了 3 个 Skill并且已经跑通了一套从“长视频输入”到“成片输出”的流水线。先说判断AI 自动化剪辑的关键不是让 AI 帮你点按钮而是把剪辑师脑子里的判断规则变成一套可以复用、可以调试、可以逐步调优的 Skill。这篇文章我会先解释 Skill 到底是什么、为什么它比普通提示词更适合做剪辑流水线然后把 3 个 Skill 的设计思路、代码实现、运行验证、常见坑逐一拆开讲。读完你可以直接照着一套最小实现跑通自己的自动化剪辑流程。1. 为什么是 Skill而不是“AI 一键成片”市面上已经有不少“AI 一键成片”工具输入一段文字描述就能生成视频。这类工具在营销素材、快剪场景下确实有用但它有两个问题素材内容是模型生成的不是你真实拍摄的成片风格由平台模板决定很难针对你自己的节目形态做精细调整。如果你要剪的是真实拍摄的课程、访谈、直播回放需要的是另一类工具一个能听懂“帮我保留老板讲核心观点的部分去掉寒暄”、能自动调用剪辑命令、能按固定节奏输出成片的自动化框架。这就是 Skill 的用武之地。Skill 可以类比为“用户态插件”。它是结构化文件加脚本的集合包含三个核心部分描述文件告诉 AI 这个 Skill 在什么场景下使用、能解决什么问题。工作流提示词把剪辑中需要连续执行的步骤写成到位的指令让 AI 按照固定顺序处理任务。工具脚本真正去调用 ffmpeg、语音识别、字幕导出、视频拼接等命令把 AI 的“裁剪意图”变成真实文件操作。普通提示词是“一次性对话”Skill 是“可复用流程”。普通提示词给不出稳定的工具调用逻辑Skill 可以像函数一样被随时调用。对视频剪辑这种“流程长、步骤多、重复性高”的场景Skill 的优势非常明显它把剪辑经验沉淀成了代码而不是留在某次对话上下文里。2. 自动化剪辑流水线的整体设计我跑通的 3 个 Skill正好对应剪辑三个阶段阶段Skill 名称主要职责输入输出第一阶段粗剪切分长视频去头尾、删除静音和明显废片段、按场景切分原始长视频带时间戳的分段片段列表第二阶段字幕与高光语音转写、字幕生成、根据关键词和语义密度提取高光片段分段片段列表SRT 字幕、高光片段列表第三阶段成片合成按高光片段排序拼接、添加转场、自动配乐、统一导出格式高光片段列表最终成片文件用流程表达就是原始视频 - Skill 1 粗剪切分 - 分段片段 - Skill 2 字幕与高光 - 高光列表 | v 最终成片 - Skill 3 成片合成 - 高光片段文件 ------------------------这样的拆法有一个很重要的理由每个 Skill 只完成一件事输入输出都是标准文件所以中间任何一步出错都可以单独排查、单独重跑。剪辑行业多年的工程经验也是这样收敛的先做素材整理再做内容理解最后才做包装合成。如果你一开始就想写一个“全自动剪好一条视频”的大脚本大概率会陷入一个极其长的 if-else 泥潭。把流程拆成 Skill本质上是把复杂度分摊到了不同的边界里。3. 环境准备与 Skill 项目结构这套 Skill 方案的运行环境并不复杂核心依赖是 ffmpeg 和 Python。ffmpeg 负责视频处理Python 负责编排和调用本地工具AI 编程助手负责理解需求并调度 Skill。我建议的最小环境如下依赖说明版本建议操作系统macOS / Linux / Windows WSL以实际项目为准ffmpeg视频剪切、拼接、转码建议使用较新的稳定版Python脚本编排3.9 以上语音识别工具本地 Whisper 或云端 ASR 接口以实际项目为准以我使用的 AI 编程助手支持 Skill 机制的工具为例每个 Skill 是一个独立的目录结构如下skills/ ├── rough-cut/ │ ├── SKILL.md │ └── scripts/ │ ├── split_scenes.py │ └── cut_fragments.sh ├── subtitle-highlight/ │ ├── SKILL.md │ └── scripts/ │ ├── transcribe.py │ └── extract_highlights.py └── final-mix/ ├── SKILL.md └── scripts/ ├── concat_clips.py └── export_final.shSKILL.md 是这个 Skill 的说明书AI 会先读它理解职责再去调用 scripts 里的脚本。整个目录挂到你的 AI 编程助手工作区之后AI 就可以在对话中识别当前任务并自动加载对应 Skill。4. Skill 1粗剪切分——把长视频变成可用片段第一个 Skill 解决的是“素材太长”的问题。一段两小时的直播回放如果直接全部转写、全部保留后面的处理压力会非常大。粗剪的目标不是做精细剪辑而是快速去重、去静音、做场景切分产出一份 m3u8 级别的片段清单。这里最容易踩的坑是很多同学直接用 ffmpeg 按固定时长切分比如每 10 分钟一刀。这种切法切出来的片段完全不顾内容语义后面挑高光的时候会非常痛苦。更好的切法是做“场景检测”在画面切换明显的地方切一刀这样每个片段内容相对完整。我设计的粗剪 Skill 模块核心流程如下用 ffmpeg 的 silencedetect 检测静音段把静音超过 3 秒的位置标记出来这些位置是自然断点。用 scene detection 计算画面差异在差异超过阈值的位置生成切点。合并两部分切点生成一个带时间戳的片段列表。输出 JSON 文件供下一个 Skill 读取。SKILL.md 的核心描述如下# 粗剪切分 将输入的长视频按照静音检测和场景检测结果切成多个片段 输出片段时间戳列表 JSON 文件。 使用场景 - 视频文件时长超过 20 分钟 - 需要先整理素材再进入高光提取 - 需要去除明显静音和头尾无意义内容 依赖命令 - ffmpeg - python3 输出文件 - segments.json片段列表scripts/split_scenes.py 是核心实现用 Python 调用 ffmpeg 完成切分#!/usr/bin/env python3 # 文件路径skills/rough-cut/scripts/split_scenes.py import json import subprocess import sys def run_cmd(cmd): 执行命令并返回 stdout 文本 result subprocess.run(cmd, shellTrue, capture_outputTrue, textTrue) if result.returncode ! 0: print(f命令执行失败: {cmd}\n{result.stderr}) sys.exit(1) return result.stdout def detect_silence(input_file, threshold-30, min_duration3.0): 检测静音区间 cmd ( fffmpeg -i {input_file} -af fsilencedetectnoise{threshold}dB:d{min_duration} f-f null - 21 ) output run_cmd(cmd) silences [] for line in output.splitlines(): if silence_start in line: start float(line.split(silence_start: )[1]) silences.append({start: start, end: None}) elif silence_end in line and silences: end float(line.split(silence_end: )[1]) silences[-1][end] end return [s for s in silences if s[end] is not None] def detect_scenes(input_file, threshold0.3): 检测场景切换点 cmd ( fffmpeg -i {input_file} -filter:v fselect\gt(scene,{threshold})\,showinfo f-f null - 21 ) output run_cmd(cmd) scenes [] for line in output.splitlines(): if pts_time: in line: pts line.split(pts_time:)[1].split()[0] scenes.append(float(pts)) return scenes def merge_cut_points(silences, scenes, video_duration): 把静音和场景检测得到的切点合并排序 cut_points [0.0, video_duration] for s in silences: mid (s[start] s[end]) / 2 cut_points.append(mid) for scene in scenes: cut_points.append(scene) cut_points sorted(set(round(p, 2) for p in cut_points)) return cut_points if __name__ __main__: input_file sys.argv[1] # 获取视频时长用于构造最后一段 duration_cmd fffprobe -v error -show_entries formatduration -of defaultnoprint_wrappers1:nokey1 {input_file} video_duration float(run_cmd(duration_cmd).strip()) silences detect_silence(input_file) scenes detect_scenes(input_file) cut_points merge_cut_points(silences, scenes, video_duration) segments [] for i in range(len(cut_points) - 1): start cut_points[i] end cut_points[i 1] if end - start 5: continue # 过滤掉太短的片段 segments.append({index: len(segments), start: start, end: end}) with open(segments.json, w, encodingutf-8) as f: json.dump({segments: segments, source_file: input_file}, f, ensure_asciiFalse, indent2) print(f完成共生成 {len(segments)} 个片段)这里做了两件关键的事一是用静音中点作为自然断点避免切在说话中间二是过滤掉时长不足 5 秒的片段避免出现大量碎片。运行方式cd skills/rough-cut python3 scripts/split_scenes.py /path/to/input.mp4成功运行后会在当前目录生成 segments.json。如果运行失败先看 ffmpeg 是否在 PATH 中再看输入文件路径是否有空格导致参数解析错误。5. Skill 2字幕与高光提取——让 AI 理解视频内容粗剪完成之后素材仍然是“一堆片段”AI 还不知道每一段在讲什么。第二个 Skill 的目标是把片段转成文字再用文字内容做判断挑出高光片段。这个环节是整个流程里最像“AI 剪辑师”的一步。我的做法分两步先做语音转写生成每段片段的文本和字幕再用规则和 AI 结合的方式提取高光。语音转写推荐用本地 Whisper 或者任意 ASR 接口。如果是本地运行转写命令类似whisper /path/to/segment.mp4 --language zh --task transcribe --output_format srt这条命令成功后会生成同名的 .srt 文件。需要注意转写是耗时操作视频越长越慢。如果素材很多建议先用 GPU 或者控制并行任务数量避免把机器跑死。拿到各片段的文本之后高光提取就有依据了。我借鉴了一个很小的策略把文本按句子切成单元给句子打分。分数来源有三部分关键词命中标题、摘要里的关键词视频的节目主题词以及“重点、核心、结论、最后、总结”这类高信息密度词。语义密度句子长度和数字序号等结构特征。情感强度语气词、重复词、加强语气的词汇。这个打分逻辑放在 extract_highlights.py 里可以灵活调整策略。核心代码如下#!/usr/bin/env python3 # 文件路径skills/subtitle-highlight/scripts/extract_highlights.py import json import sys import re # 配置区可自行调整关键词 KEYWORDS [核心, 结论, 重点, 注意, 总结, 关键] STRUCTURE_MARKS [第一, 第二, 第三, 首先, 然后, 最后, 一方面, 另一方面] EMOTION_WORDS [非常, 特别, 极其, 十分, 很明显, 毋庸置疑] def load_srt(srt_path): 解析 SRT 字幕文件为句子列表 with open(srt_path, r, encodingutf-8) as f: content f.read() blocks re.split(r\n\s*\n, content.strip()) sentences [] for block in blocks: lines block.strip().split(\n) if len(lines) 2: continue # 第一行是序号第二行是时间轴后面的行是文本 text .join(lines[2:]).strip() if not text: continue sentences.append({text: text}) return sentences def score_sentence(text): 给句子打高光分数 score 0 for kw in KEYWORDS: if kw in text: score 5 for mark in STRUCTURE_MARKS: if mark in text: score 3 for word in EMOTION_WORDS: if word in text: score 2 # 句子越长往往信息量越大但过长也可能是废话连篇 if 30 len(text) 120: score 2 return score def extract_highlights(segments_json, srt_dir, top_n10): with open(segments_json, r, encodingutf-8) as f: data json.load(f) segment_scores [] for seg in data[segments]: srt_file f{srt_dir}/segment_{seg[index]:03d}.srt try: sentences load_srt(srt_file) except FileNotFoundError: continue total_score sum(score_sentence(s[text]) for s in sentences) if sentences: total_score min(len(sentences) * 0.5, 5) # 鼓励信息密度适中的片段 segment_scores.append({ index: seg[index], start: seg[start], end: seg[end], score: round(total_score, 2), text_preview: .join(s[text] for s in sentences[:3]) }) segment_scores.sort(keylambda x: x[score], reverseTrue) return segment_scores[:top_n] if __name__ __main__: segments_json sys.argv[1] srt_dir sys.argv[2] output_json sys.argv[3] if len(sys.argv) 3 else highlights.json top_n int(sys.argv[4]) if len(sys.argv) 4 else 10 highlights extract_highlights(segments_json, srt_dir, top_n) with open(output_json, w, encodingutf-8) as f: json.dump({highlights: highlights}, f, ensure_asciiFalse, indent2) print(f完成共提取 {len(highlights)} 个高光片段) for h in highlights: print(f 片段 {h[index]:03d} 分数 {h[score]:.2f}{h[text_preview][:40]})运行命令cd skills/subtitle-highlight python3 scripts/extract_highlights.py ../rough-cut/segments.json ./srt_files highlights.json 10这个脚本的核心是分数可解释。当你发现某个片段被错误选入高光时可以直接看它的文本和分数构成调整关键词或权重即可不需要重写整个流程。这一步是 Skill 方案优于纯提示词方案的关键规则是代码可测试、可版本化管理。6. Skill 3成片合成——拼接、转场与导出高光片段确定之后最后一步是把这些片段拼成一个完整成片。这个 Skill 看起来最“机械化”但反而是最容易出问题的环节因为 ffmpeg 的拼接和转码参数一旦设置错误轻则画面黑屏重则整条视频导出失败。我的成片合成 Skill 分成两步第一步把高光片段从原视频里真正裁剪出来生成独立的小片段文件。裁剪时要注意ffmpeg 的-ss和-i的顺序有讲究。-ss放在-i前面是快速跳转关键帧速度快但可能不精确放在-i后面是逐帧解码精度高但慢。对最终成片来说建议用后者宁可慢一点也要保证不出现画面跳动。第二步把裁剪出来的小片段按顺序拼接。ffmpeg 有 concat filter 和 concat demuxer 两种方式。我推荐用 concat demuxer因为它不需要重新编码拼接速度快质量无损。concat 拼接需要一个列表文件# 文件路径skills/final-mix/concat_list.txt file clips/highlight_001.mp4 file clips/highlight_002.mp4 file clips/highlight_003.mp4然后执行拼接命令ffmpeg -f concat -safe 0 -i concat_list.txt -c copy final_no_audio.mp4这里-c copy表示不重新编码直接复制音视频流。但这里有一个坑如果裁剪出的多个片段编码参数不一致-c copy可能失败。为了稳妥可以在裁剪的时候就统一转成相同编码或者在拼接失败时去掉-c copy重新编码。完成基础拼接后我会根据预设模板给成片加上一个简单的开头标题和片尾再统一导出为 1080p、H.264 编码的 MP4方便直接上传到视频平台。这个逻辑封装在 export_final.sh 中#!/usr/bin/env bash # 文件路径skills/final-mix/scripts/export_final.sh set -e INPUT_FILE$1 OUTPUT_FILE$2 ffmpeg -y -i $INPUT_FILE \ -vf scale1920:1080:force_original_aspect_ratiodecrease,pad1920:1080:(ow-iw)/2:(oh-ih)/2 \ -c:v libx264 -preset medium -crf 20 \ -c:a aac -b:a 192k \ -movflags faststart \ $OUTPUT_FILE echo 导出完成$OUTPUT_FILE-movflags faststart是给网络播放优化的可以把 moov 元数据移到文件头部上传到视频平台后播放体验更好。把三个步骤封装起来之后Skill 3 的 SKILL.md 也很简单# 成片合成 将高光片段列表和原始视频合成为一个完整的成片文件。 使用场景 - 完成高光片段挑选之后 - 需要统一输出格式、分辨率和编码 - 需要自动添加片头片尾 流程 1. 读取 highlights.json 2. 从原始视频裁剪高光片段 3. 生成 concat_list.txt 并拼接 4. 统一导出为 1080p MP47. 把 3 个 Skill 串起来一条完整的自动剪辑流水线三个 Skill 单独都能跑通但它们要变成流水线还需要一个编排层。这一步我不建议写复杂的调度框架用一个简单的 shell 脚本或者 Makefile 就足够了。以 Makefile 为例# 文件路径Makefile INPUT_VIDEO : input.mp4 SEGMENTS_JSON : skills/rough-cut/segments.json SRT_DIR : srt_files HIGHLIGHTS_JSON : skills/subtitle-highlight/highlights.json OUTPUT_VIDEO : final_output.mp4 .PHONY: all rough-cut subtitle-highlight final-mix clean all: final-mix rough-cut: cd skills/rough-cut python3 scripts/split_scenes.py $(INPUT_VIDEO) subtitle-highlight: rough-cut mkdir -p $(SRT_DIR) cd skills/subtitle-highlight python3 scripts/extract_highlights.py \ ../rough-cut/segments.json ../../$(SRT_DIR) highlights.json 10 final-mix: subtitle-highlight bash skills/final-mix/scripts/build_final.sh $(INPUT_VIDEO) $(HIGHLIGHTS_JSON) $(OUTPUT_VIDEO) clean: rm -rf $(SRT_DIR) final_no_audio.mp4 $(OUTPUT_VIDEO)build_final.sh 的作用是读取 highlights.json 里的片段信息执行 ffmpeg 裁剪和拼接最后调用 export_final.sh 导出。这里就不贴完整脚本了逻辑和前面讲的裁剪、拼接保持一致。有了这个编排层你只需要在项目根目录执行make clean make就能从原始视频一路产出最终成片。中间任何一步失败Makefile 会停在出错的地方方便你单独调试。从实际使用体感看这套流水线最值钱的部分不是“全自动”而是“可干预”。如果哪一期视频的高光选得不准你只需要改 keywords 配置然后重跑 subtitle-highlight 和 final-mix不需要重新做粗剪。这种按 Skill 分步重跑的能力是单个大脚本很难提供的。8. 常见问题与排查思路自动剪辑流程里问题几乎都出在视频处理和脚本配置上。我把高频问题整理成了排查表问题现象可能原因排查方式解决方案ffmpeg 无法识别输入文件文件路径含有空格或特殊字符检查命令是否对路径加了引号统一用变量传参并在命令中加引号生成片段过碎场景检测阈值太低查看 scenes 列表中切点数量调高 scene 阈值比如从 0.3 调到 0.4转写字幕为空视频本身无音轨或音轨过小用 ffprobe 查看音轨信息检查转写时是否指定了语言调整音频增益确认 --language 参数concat 拼接失败片段编码参数不一致查看 ffmpeg 报错信息去掉 -c copy 改为重新编码或统一裁剪参数高光片段选错关键词设置不符合节目主题查看高光片段的 text_preview编辑 KEYWORDS 和 EMOTION_WORDS 权重导出视频播放黑屏scale/pad 参数处理不当用播放器打开看是否全程黑屏检查 filter 链确认 pad 颜色和尺寸Makefile 执行时找不到脚本工作目录不对检查 make 的输出路径统一用项目根目录执行脚本内部使用相对路径时注意切换目录其中最容易忽略的是“静音阈值”问题。不同视频的底噪差异很大录屏视频底噪低现场收音底噪高。如果静音检测设置成固定的 -30dB可能在底噪较高的素材上完全检测不出静音导致粗剪切点过少。建议在 SKILL.md 里把阈值参数暴露出来遇到特殊素材时通过 AI 对话直接调整。9. 最佳实践从玩具到流水线的工程建议跑通 3 个 Skill 只是第一步。如果你想把这套自动化剪辑流程用到真实的每周更新场景需要额外注意几点第一每个 Skill 的输出都要带索引和版本。我在 segments.json 和 highlights.json 里都保留了原始时间戳这样即使后续环节调整了策略也能追溯一个片段最初来自原视频的哪个位置。真实生产中素材可追溯比结果好看更重要。第二把规则写在代码里而不是写在提示词里。关键词、权重、阈值这类东西如果写在 SKILL.md 的提示词里AI 每次运行都有可能理解偏差写在配置区里AI 只会读取和使用不会随机发挥。Skill 里“代码负责逻辑、提示词负责定位”的分工是保持稳定性的关键。第三控制重跑成本。高光提取依赖语音转写这是整个流水线里最耗时的部分。建议把转写结果缓存下来文件名用视频文件名的哈希值加时间戳。如果只是调整了关键词权重不需要重新转写直接从缓存里读取 SRT 文件即可。第四尊重素材的合法授权。自动化剪辑不是让你随意抓取别人的视频来二创发布。使用歌手、讲师、直播主理人的内容做剪辑分发时务必确认你有相应的处理权和传播权。版权合规应该是自动化流水线里默认的一环不需要等到被投诉才开始考虑。第五参数配置要做到环境无关。我在本地跑通后把 ffmpeg 路径、转写模型路径、输出目录全部改成了环境变量或配置文件。这样可以方便地迁移到另一台机器也方便后续接 CI 或定时任务。第六用“影子模式”先试运行。别上来就全自动直接发布。建议先跑通流水线把成片截图和文字摘要发给团队或朋友人工过一遍。确认效果稳定后再把流程推到生产环境。从实际价值来看这套 Skill 方案最打动我的不是它省了多少时间而是它把剪视频这件事从“手动操作工具”变成了“调试一套代码”。每一次效果不满意我都是在调参数、调关键词、调 pipeline而不是重新拖一遍时间轴。这种工作方式的转变才是 AI 自动化剪辑真正值得投入的地方。下一步你可以先照着文中第 3、4、5、6 章的最小实现跑通一条视频把这三个 Skill 装进你的 AI 编程助手工作区里然后根据自己的素材类型调整关键词和阈值。跑通之后再考虑加入自动封面、多平台导出、素材归档等扩展 Skill。你会发现真正决定自动化剪辑上限的是你对剪辑流程本身的拆解能力。