☰
AI视频剪辑自动化实战:基于Whisper、LLM与ffmpeg的智能粗剪工具全解析
2026/10/26 16:33:54 网站建设 项目流程

搞视频剪辑的人一定懂这种痛苦:一条口播录了 25 分钟,回放一看,开头“嗯”“那个”占了 3 分钟,中间有两段反复讲同一个观点,结尾还拖了 1 分多钟的收尾废话。手动剪吧,来回拖进度条,一帧一帧找切割点,剪完一条片子眼睛都快瞎了;不剪吧,观众划走的速度比你剪片还快。

我年初做了一个开源小工具 Video AI Cutter,核心功能一句话就能说清楚:把视频里“不该留”的片段自动找出来,按语义完整度拼出成片。它不需要你手工标记任何剪切点,只需要给一个输入视频,工具会自己完成语音转写、句子筛选、静音对齐、视频拼接的全流程。这篇文章既是 Video AI Cutter 的 Readme,也是我整个开发过程的踩坑记录。想自己复刻一个、或者直接拿来改造成自己工作流的同学,跟着这篇走就够了。

先说结论:这个项目本质上不是“剪辑工具”,而是一个“判断工具”。剪辑的手艺活还是留给人,但它能把最耗时的“素材通读、标记、粗切”这三大步全部自动化。它适合口播视频、直播切片、会议录播、课程回放、播客视频化这几类场景,核心用户是内容创作者和想折腾自动化工作流的开发者。如果你想给团队搭一套“自动出粗剪”的流水线,这个项目也能当底座。

1. 这个工具到底在干什么

先给一个整体定位。市面上已有的“AI 剪辑”工具多半是套壳,本质还是把视频扔进去,由云端模型做分析,你只能在黑盒里点“生成”。Video AI Cutter 走的是另一条路:全部环节本地化,每一步都可以看到中间产物,每一个判断逻辑都可以调参。

整套流程拆开看是这样:

  1. 输入一条视频,先抽音频,转成 16kHz 单声道 WAV。
  2. 用 Whisper 系模型做语音识别,拿到带时间戳的逐句文本。
  3. 把逐句文本交给大模型,让它标记哪些句子是冗余内容。
  4. 用静音检测找到真正的“可切割点”,把 LLM 的标记对齐到这些切割点附近。
  5. 算出保留时间区间,先生成一个带可视化预览的 JSON 清单。
  6. 确认后交给 ffmpeg 拼接,输出成片。

这个设计的核心思路是“把大问题拆成小问题,每一个小问题都能单独验证”。语音识别错了,可以单独调 Whisper 的模型和提示词;冗余判断太激进,可以单独改 LLM 的温度和阈值;拼接有问题,可以单独查 ffmpeg 的参数。不会出现黑盒里跑了一小时、最后不知道错在哪的情况。

为什么不用现成的“智能剪辑 API”?最直接的原因是隐私和成本。口播视频和会议录播往往涉及未公开的内容,把整段素材传到第三方服务,本身就过不了我这道心理关。而且一次调用 API 的价格,本地 CPU 跑半小时的电费就能覆盖。本地方案的另一个好处是完全可复现——今天调出来的参数,三个月后依然能跑出一模一样的结果。

这个工具的定位也从一开始就定死了:不做特效、不转场、不调色,只做一件事——“把视频修剪成更紧凑的版本”。输出的是粗剪,不是精剪。想靠它一条龙出成品是不现实的,但用它把 25 分钟素材变成 18 分钟干净初剪,效率提升是肉眼可见的。

2. 拆解三条核心链路:转录、判断、切片

2.1 为什么要用 Whisper 而不是传统字幕工具

“AI 裁剪”的前提是必须知道每一句话在什么时间点出现。传统字幕工具依赖音字对齐算法,对中文的断句能力一般,而且很多工具只输出字幕文件,不给你足够稳定的逐句时间戳。Whisper 系的模型天然输出带时间戳的 segments,每个 segment 包含 start、end、text 三个核心字段,这正好是裁剪逻辑需要的三要素。

我在项目里优先推荐的是 faster-whisper,而不是官方原版 Whisper。原因很实际:官方 Whisper 在 CPU 上跑 small 模型处理 1 分钟音频可能要 2 到 5 分钟,而 faster-whisper 用的是 CTranslate2 后端,配合 int8 量化,速度能快 3 到 4 倍。我用一台 i5-12400F 的 CPU 机器实测,处理 25 分钟视频的音频,faster-whisper small int8 大约 4 分钟跑完,官方版要跑到 12 分钟以上。对“本地跑”这个目标来说,速度就是体验。

模型选型我给了一张表,直接写在 README 里:

模型参数量中文识别效果CPU 速度(分钟音频/分钟处理)显存建议
tiny39M能听出大概,断句乱极快1GB 以下
base74M句子基本正确,名字爱错快1GB
small244M中文可用,语气词识别不错中2GB
medium769M中文效果明显提升慢4GB
large-v31550M接近人工转写很慢6GB 起

我默认配的是 small。理由是:裁剪不需要 100% 正确的文字,只需要正确的时间戳和大致准确的句子边界。small 在“句子边界”上的表现已经够用,而且速度快。如果你剪的是会议录播这种对文字精度要求高的场景,换 medium,代价是处理时间增加 2 到 3 倍。

还有一个细节:喂给 Whisper 的音频必须是 16kHz 单声道。ffmpeg 抽音频时默认输出是原采样率,直接喂进去也不是不行,但 Whisper 内部会重采样,长视频可能出现时间戳轻微偏移。更稳的做法是显式转一下:

ffmpeg -i input.mp4 -vn -ac 1 -ar 16000 -f wav audio_16k.wav

这个操作几乎瞬时完成,但能省掉后面一大堆时间戳对齐的麻烦。

2.2 LLM 负责“判断”,但别让它替你做决定

转写完成之后,手上是一堆带起止时间的话。现在要回答的核心问题是:哪些话该留,哪些话该剪。

这个判断我用的是 LLM。判断依据不是“这句话语法对不对”,而是“这句话对观众有没有信息增量”。我把每条句子拼成这样的 JSON 喂给模型:

[ {"index": 0, "start": 1.2, "end": 8.5, "text": "今天我们聊一聊如何搭建一个自动化剪辑流水线"}, {"index": 1, "start": 9.0, "end": 11.2, "text": "嗯,就是,那个,其实内容不是特别复杂"}, {"index": 2, "start": 11.8, "end": 23.4, "text": "首先你需要准备一台能跑得动语音识别的电脑"} ]

提示词大致是这样:

你是视频编辑助手。下面是一段视频的逐句文本,请判断每个句子是否冗余。 冗余标准包括:口头禅、与主题无关的离题内容、前后重复的表达、纯粹的语气词填充。 请只输出 JSON 数组,每个元素包含 index、keep(true/false)、reason 三个字段。 注意:宁可漏判,不要误删。拿不准的句子一律 keep。

注意最后两句:“宁可漏判,不要误删。拿不准的一律 keep”。这句话决定了整个工具的使用体验。LLM 一旦误删关键句,成片语义就断了,用户对工具的信任感会瞬间崩塌;而漏判几句废话,成片只是不够紧凑,用户还能接受。我把这个原则直接写进了默认提示词,同时在 judge 参数里暴露了一个threshold字段,默认 0.5,数值越大裁得越激进。

本地跑 LLM,我用的是 Ollama 加载 qwen 系 7B 模型,用 CPU 也能跑,单条 25 分钟视频约 200 句文本,分 3 批喂完,耗时 2 分钟左右。如果你的机器有显卡,这个环节几乎是秒级。如果你不想本地折腾 LLM,也可以把 judge 模块替换成 OpenAI 兼容接口,代码里留了LLM_API_BASE这个配置项,指向任意兼容服务都行。

2.3 切片为什么选 ffmpeg concat 而不是直接剪

拿到“哪些句子保留”之后,面临的最后一个技术问题是:怎么把这些保留片段拼起来。

最直觉的答案是:根据句子时间戳,把不保留的区间剪掉,保留的区间直接拼接。但这里有个隐藏陷阱:句子的 start、end 是由语音识别的,精度虽然不错,但不会精确落在画面帧上。如果你直接按句子的 end 去硬切,裁出来的画面很可能会切断一个完整动作,观感上会有“跳了一下”的生硬感。

我的解法是引入“静音对齐”。在正式切割前,用 ffmpeg 的 silencedetect 找出所有静音段:

ffmpeg -i audio_16k.wav -af silencedetect=noise=-30dB:d=1.5 -f null -

-30dB是静音判定阈值,d=1.5是最小静音持续秒数。输出日志里会出现:

silence_start: 8.6 silence_end: 10.2

然后把 LLM 标记的“冗余句子的边界”吸附到最近的静音段上。这样切点永远落在“没声音”的地方,成片的节奏是完整的,不会出现一句话说到一半突然被切断的窒息感。

至于最终拼接,我用的是 ffmpeg 的 concat demuxer:

ffmpeg -f concat -safe 0 -i seglist.txt -c copy output.mp4

-c copy的意思是流复制,不重新编码,速度极快,画质零损失。但用 concat 有一个铁律:所有输入片段的编码参数必须一致。如果原始视频是可变帧率,或者不同片段来自不同来源,-c copy拼接出来会花屏或者音画不同步。所以我在 pipeline 里加了一个环境变量FORCE_REENCODE,默认关闭;如果拼接出问题,打开后会把所有片段统一重编码为 H.264 + AAC 再拼接:

ffmpeg -i seg_%d.mp4 -c:v libx264 -preset veryfast -crf 20 -c:a aac -b:a 128k ...

3. 目录结构和 Readme 里的核心配置

3.1 项目目录怎么组织最顺手

这个项目我采用了非常典型的“入口 + 核心模块”结构,不搞花活,好处是新人拿到仓库 5 分钟就能定位到想改的代码:

video-ai-cutter/ ├── app.py # 命令行入口(也支持 Streamlit 模式) ├── cutter/ │ ├── __init__.py │ ├── transcribe.py # 音频抽取 + Whisper 转写 │ ├── judge.py # LLM 冗余判断 │ ├── segment.py # 静音对齐 + 区间计算 + ffmpeg 拼接 │ └── utils.py # 文件处理、日志、时间戳转换 ├── config.yaml # 全部可调参数 ├── requirements.txt └── README.md

你可能注意到我把所有逻辑按照流水线阶段切分,而不是按照“模型”“算法”切分。这是刻意的。因为实际调试时,你通常只会遇到一个阶段的问题:要么转录结果差,要么判断不精准,要么拼接出错。按阶段切分,定位问题的半径最小。比如你要调 LLM 的提示词,只需要打开 judge.py,别的一行都不用碰。

3.2 config.yaml 里最关键的四个参数

配置文件我尽量精简到 8 个字段,但真正决定了裁剪效果的只有下面四个,这里展开讲讲。

model_size: small # Whisper 模型档位 min_silence_ms: 1500 # 静音最短持续时间(毫秒) keep_threshold: 0.5 # LLM 判断保留的置信阈值 max_segment_duration: 300 # 单个片段最大时长(秒)

model_size前面讲过了,不展开。

min_silence_ms是静音检测的最小持续毫秒数。设太短(比如 300ms),正常人说话的换气停顿都会被识别成剪切点,结果就是画面频繁跳动;设太长(比如 3000ms),很多冗余语段后面没有这么长的空白,切点吸附不上去,裁剪力度不够。我在不同素材上试下来,1500ms 是一个比较通用且安全的默认值。演讲类素材可以提到 2000ms,Vlog 这种语速快的素材用 1200ms 会更跟手。

keep_threshold是 LLM 判断的后处理阈值。LLM 返回每个句子的原始置信分,如果 keep 的概率低于这个值,才判定为冗余。默认 0.5 是严格模式,只有模型很确定是废话才剪;调到 0.7 以上,裁剪会更激进,适合本身废话特别多的直播切片。

max_segment_duration是针对“直播切片”场景加的防呆参数。有时候整段视频说话太密集,几乎没有静音,每段保留片段会连成七八分钟的超长块。设置这个参数后,segment.py 会自动在超长块内部找相对安静的点强切。这属于“宁可切碎也不让成片拖沓”的兜底策略,但注意切割点仍会吸附到静音位置,不会硬生生切断人声。

4. 实操:从命令行把一条 25 分钟视频剪成 18 分钟

下面这条完整链路我不只写在 README 里,也实际跑过很多遍。就用一条 25 分钟的 1080p 口播视频做演示,机器配置是 i5-12400F + 16GB 内存 + 核显,纯 CPU 跑。

4.1 第一步:转录和句子时间戳

环境准备部分只说三件事。第一,Python 版本建议 3.10 以上,装 faster-whisper、streamlit、pyyaml、openai 库(用于兼容 LLM API)。第二,ffmpeg 必须存在于系统 PATH 中。第三,如果要用本地 LLM,确认 Ollama 在跑。

准备好之后,命令行执行:

python app.py --input demo.mp4 --output demo_cut.mp4 --model small

app.py 的第一段逻辑会调用transcribe.py,流程就是先抽音频,再调 faster-whisper 识别。实测在 CPU 上,25 分钟音频耗时约 4 分钟。识别完成后,工作目录下会生成一个transcript.json,里面每一段长这样:

{ "start": 11.8, "end": 23.4, "text": "首先你需要准备一台能跑得动语音识别的电脑" }

我建议你在这一步先停下来,打开 transcript.json 看一遍。为什么?因为这一步直接决定后续裁剪质量。如果识别出来的句子断句全乱,先别急着往下跑,回去换更大的模型,或者检查音频是不是有严重回声。反正转录只花 4 分钟,多跑几次也不心疼。

4.2 第二步:让 LLM 标记冗余句子

transcript.json 生成后,judge.py会按每 50 条句子一组,批量发给 LLM。这里有一个小优化:发送之前先把句子按时间戳排序,并给每条句子一个全局唯一的 index,LLM 返回后按 index 归位。这样即使某一组句子返回顺序不对,也不会污染全局结果。

LLM 判断结果会合并进同一份 JSON,变成:

{ "start": 11.8, "end": 23.4, "text": "首先你需要准备一台能跑得动语音识别的电脑", "keep": true, "reason": "核心信息句,说明前置条件" }

跑完这步后会打印一行统计:

[Info] 共识别 143 句,建议保留 112 句,建议裁剪 31 句

看到这个统计,我通常会先不急着切片,而是打开 JSON 扫一眼“建议裁剪”的句子。LLM 的 reason 会告诉你它为什么裁,比如“口头禅填充”“重复前句观点”“离题闲聊”。如果你觉得某个 reason 明显不靠谱,就去调提示词,或者调低 keep_threshold。这个环节非常建议反复迭代几次,因为你的视频内容风格,直接决定了什么样的判断标准最合适。

4.3 第三步:生成保留区间并预览

拿到了每句话的 keep 布尔值之后,segment.py开始干活。它先把连续的 keep=true 句子合并成若干保留区间,然后调用 ffmpeg silencedetect 拿到所有静音段。接着做的是对齐:每个保留区间的边缘,向最近的大于 1.5 秒的静音段吸附。

对齐完成后,会生成一份preview.json,里面是一个个数组:

[ {"start": 0.0, "end": 25.6, "keep": true}, {"start": 25.6, "end": 40.2, "keep": false}, {"start": 40.2, "end": 88.3, "keep": true} ]

这个 preview.json 是整个项目里我最看重的部分。因为它是“可审查的中间产物”,你可以在不跑任何视频剪辑软件的情况下,快速核对裁剪方案是否合理。如果你不想走命令行,可以加--ui参数启动 Streamlit 界面,界面上会列出每个区间的起止时间、保留/裁剪状态、对应的文字内容。鼠标点一下就能临时改 keep 状态,改完重新生成 preview.json,然后一键导出。

这种“先审查方案,再执行渲染”的模式,实际体验下来比直接出一版成片再返工舒服太多了。毕竟成片渲染一次少说 3 分钟,审查 JSON 只要 30 秒。

4.4 第四步:ffmpeg 输出成片

最后一步,segment.py 根据 preview.json 里所有 keep=true 的区间,先去切割出碎片文件:

ffmpeg -i input.mp4 -ss 0.0 -to 25.6 -c:v libx264 -preset veryfast -crf 20 -c:a aac -b:a 128k seg_001.mp4

这里为什么不用-c copy?因为切割点经过静音吸附后,往往不落在关键帧上,直接流复制会导致片段开头花屏或卡顿。所以我默认走一次轻量重编码,preset veryfast+crf 20能在画质和速度之间取得平衡。1080p 视频实测重编码速度约 3 倍实时,25 分钟素材编码 18 分钟成片,耗时大约 3 分半。

所有碎片生成后,写入 seglist.txt:

file 'seg_001.mp4' file 'seg_002.mp4' file 'seg_003.mp4'

再执行拼接:

ffmpeg -f concat -safe 0 -i seglist.txt -c copy demo_cut.mp4

提示:concat 拼接时所有碎片已经是统一编码格式,所以这一步用-c copy是安全的,速度很快,20 秒内完成。输出完还会顺手生成一个自动字幕文件demo_cut.srt,如果发布平台需要字幕,这一步等于白赚的。

整个流程实测下来,从裸视频到 18 分钟成片,总耗时约 10 分钟,其中真正人工介入的只有“审查 preview.json”这一步,大约 1 到 2 分钟。相比手动剪辑至少 1 小时起步,效率提升是数量级的。

5. 避坑指南:我在开发中踩过的几个坑

5.1 Whisper 长音频漏句和漂移

项目开发初期,我用官方 Whisper 直接转写 40 分钟的长视频,结果中段有连续 2 分钟没有任何输出,第二次换一小段音频测试又能识别出来。排查发现是长音频的 VAD(语音活动检测)把一段低音量人声当成了静音,导致整段漏掉。

解决办法是在转写前关闭官方 Whisper 自带的 VAD 过滤,改用独立的silero-vad先做一次音频切分,把超过 30 分钟的长音频切成片段,每段之间保留 0.5 秒重叠,再交给 Whisper 转写。转写完成后按时间戳拼接回完整序列。加了这层逻辑之后,长视频漏句的问题基本消失。

时间戳漂移则是另一个坑。现象是转写出来的文字和画面声音不同步,越到后面偏差越大。根因是输入音频的采样率不是标准的 16kHz。现在我在 transcribe.py 里强制先把音频转成 16kHz 单声道 WAV,漂移问题再也没有复现过。

5.2 ffmpeg 关键帧和 -c copy 的坑

这是新手最容易踩的坑。我第一次尝试输出成片时,为了追求速度,直接用-c copy切割所有保留区间,结果前三个片段正常,第四个片段开头花屏,第五个片段直接黑屏几秒。

原因前面也提到了:切割点不在关键帧上。ffmpeg 做流复制时,遇到第一个关键帧之前的非关键帧数据只能丢弃,导致画面从花屏或黑屏开始。解决方案有两个:

  1. 切割时强制最近关键帧对齐:-ss放在-i前面,ffmpeg 会先 seek 到前一个关键帧,再丢弃多余帧直到精确位置。这样可以用-c copy做切割。
  2. 放弃流复制,统一重编码。

我在项目里默认选了方案 2,因为方案 1 在部分素材上仍会出现首帧微卡。如果你想追求无损和速度,可以切到方案 1,但发布前一定把成片从头到尾扫一遍。另外一个相关经验:如果原视频是从网上下载的,帧率经常是 VFR(可变帧率),这种素材无论如何都要重编码一次,否则后续任何拼接操作都容易出问题。

5.3 LLM 过度裁剪的问题

第一次跑通全链路后,我拿一条自己录的视频测试,发现成片确实短了很多,但中间有一段逻辑完全接不上。打开 preview.json 一看,LLM 把“因为所以”里的“因为”句给裁了,只留下了“所以”句。语义断层就是这么来的。

这不是模型能力问题,而是提示词缺少对“逻辑关联词”的保护。后来我在提示词里加了这么一条规则:

如果句子中包含因果、转折、递进关系的关联词(如“因为”“所以”“但是”“而且”),默认保留。

加了这条之后,误删逻辑关键句的情况大幅减少。另外一个有效手段是给 LLM 看上下文——不要把每条句子单独发出去判断,而是每批带上前后各 1 条的上下文,模型更容易判断“这句话是不是在承接前文”。

如果你的素材本身就比较跳跃,还有一个兜底参数:context_penalty,默认 0.2,表示相邻两句中只有一句被标记为裁剪时会自动放行,只有当连续两句以上都是冗余标记时才真的剪。这个参数简单粗暴但非常有效,强烈建议开启。

5.4 大视频上传与运行性能优化

Streamlit 版本上线后,有朋友传了一个 2GB 的 4K 素材,结果上传到一半页面报错。查了半天才发现 Streamlit 默认单文件上传上限是 200MB,需要改.streamlit/config.toml:

[server] maxUploadSize = 2048

注意单位是 MB,写成 2048 就是 2GB。但就算能上传,处理 4K 素材对本地 CPU 也是灾难。我的建议是:处理前先用 ffmpeg 把输入统一压成 1080p,因为裁剪判断只需要音频和画面内容,4K 分辨率对判断结果没有任何帮助,反而让重编码时间翻好几倍。合并在工具里做成了默认选项--pre-transcode,处理 4K 素材时会先转成 1080p 再走流水线。

性能优化方面,有一个经验值得分享:不要对整段音频做完整的 Whisper 转写后再判断,而是先用 VAD 把有效语音段抽出来,静音部分跳过处理。口播视频一般有 15% 的时间是空白,跳过这些空白能让转写时间缩短接近 15%。此外,faster-whisper 的batch_size默认 8,如果你的显存吃紧,把它调到 4;CPU 用户则建议直接开compute_type=int8,识别的精度几乎不掉,速度能快接近一倍。

6. 一点后续扩展想法

工具第一版跑通之后,我又在这个框架上加了一个非常实用的子功能:按“句子完整度”自动生成字幕烧录版。流程是转录、判断、切片之后,把保留片段的字幕用 ass 格式烧进画面,省掉剪辑软件里二次加字幕的工序。这个功能对发短视频的人来说特别实用,成片直接就能发布。

另外,裁剪的判定维度目前只用了文本语义和静音,其实还可以加一个画面维度。比如固定机位的直播,画面长时间静止但人声在说话,这种片段可以通过画面相似度检测,在保留语义的同时把“黑屏画面”单独剪掉或替换成插屏图。维度多了之后,整个系统的可玩性会再上一个台阶,但目前第一版的“语义 + 静音”两维组合,已经能覆盖绝大多数口播内容的裁剪需求了。

按我这一百多次运行的经验,这个工具最适合的工作流是:录完视频先让机器出粗剪版,人只负责在 preview.json 阶段做审查,改动量通常不会超过 5%。真正的精剪还是需要人工的,但精剪时有了一版干净的材料,效率比从原始素材开始剪高太多了。如果你也是被粗剪折磨的内容创作者,花一晚上搭起来,第二天就能感受到“让机器先剪一遍”的快乐。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询