“一个30秒的打斗片段,5次有效击打,手动给每次击中加上黑白闪屏特效,差不多要花15分钟。”做过格斗混剪或者Anime AMV的人对这套流程并不陌生——在剪辑软件里一帧一帧地拖拽时间轴,对齐每一拳、每一脚的接触瞬间,然后叠加高对比度、反相或闪白效果,反复调整时长。如果不是重度剪辑爱好者,这种重复劳动足以磨掉所有创作欲。所以才有了这个想法:上传视频,其余交给AI,自动识别所有冲击帧,直接套好特效,把成品吐出来。
工具链没有绕弯子,全部围绕“一套API调用完成全流程”来搭建。HTTP服务用Go加Gin框架,所有与视频读打交道的操作——抽帧、标注、拼图、加特效——统一交给FFmpeg。真正充当“眼睛”判断击打瞬间的,是Google Gemini,通过genai SDK把帧画面送进模型;PostgreSQL配合sqlc生成类型安全的数据库层。项目整体用了六边形架构,端口、适配器、领域逻辑和服务各安其位,方便测试和未来扩展。
![]()
流程第一步是把视频抽成序列帧,并给每一帧打上肉眼可读的编号。实际做法是每秒钟均匀抽取10帧,缩放至宽度640像素,同时在左上角压上帧序号。这里一个不起眼但很关键的细节是FFmpeg drawtext滤镜中数字格式化字符串的选择。最初用%{expr\:n+1},烧出来的帧号总是带小数点——1.000000而不是单纯的1,这对后续让AI按数字指认帧会造成干扰。换成%{eif\:n+1\:d}以后,强制格式化为十进制整数,数字才干净。这段Go代码在执行时,一条ffmpeg命令就把抽帧和标注一步做完,然后按路径排序收集所有帧。按10fps计算,一个30秒视频会生成300张带编号的帧图像。
如果直接把300张图片喂给Gemini逐张分析,既慢又烧钱。所以第二步是把这些帧拼接成网格图——每张图5列4行,正好容纳20帧,30秒的视频从300张独立帧变成约15张网格图。拼接依旧靠FFmpeg完成:先使用concat demuxer将要拼成一组的20条帧路径喂进去,再接tile滤镜按5×4布局铺开。每张网格图都是对连续时段的帧进行压缩预览,没有丢失时序信息,又成倍拉低了API调用次数。
后续环节被设计成用同一套网格图输入,让Gemini根据画面内容快速定位哪些帧里出现了明显的击打动作,返回对应的帧编号。一旦确定了这些关键帧在时间轴上的位置,再由FFmpeg精确定位、套上定制化的黑白闪屏特效,整体输出一个完成度很高的视频。整个过程只需要最初的一次上传,中间没有手动画蒙版、拉曲线或者翻来覆去调整效果时长的负担,把那些经典的高对比度冲击瞬间,从反复打磨的体力活,变成一行调用的事。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.