用 Skill 封装 AI 视频转场:从 SKILL.md 到 FFmpeg 自动化生成
2026/9/1 9:27:09 网站建设 项目流程

把 AI 生成视频转场特效封装成一个 Skill,是短视频创作者和 AI 工程实践者都应该掌握的用法。所谓 Skill,简单说就是给 AI 助手准备的一套能力包:用户描述“我要让两段视频之间做一个 1 秒的交叉溶解”时,AI 不再靠泛泛的对话猜测转场参数,而是读取目录里写好的 SKILL.md,按固定步骤调用脚本,最终生成可验证的 FFmpeg 命令或直接产出视频。下面从 Skill 概念讲起,逐步搭建一个名为video-transition-skill的最小能力包,并给出运行验证、常见问题排查和扩展建议。

我会按“理解 Skill 机制 -> 准备环境 -> 编写 Skill -> 运行验证 -> 排错 -> 最佳实践”的顺序展开。如果你已经写过 Agent 插件,可以重点看第 3 章和第 4 章的脚本实现;如果你刚接触 Skill,建议从第 1 章开始读,避免后面配置失败时不知道问题出在哪一层。

1. 先搞清楚 Skill 到底是什么,再决定要不要自己写

1.1 Skill 解决的是“让 AI 按固定套路干活”的问题

大模型本身能聊天,但没法可靠地执行“读取视频时长、计算转场偏移、生成 FFmpeg 命令”这套固定流程。普通提示词可以让模型“大概知道”要做什么,却无法保证每次都能按同一套参数规范操作。Skill 的作用,是把这套流程变成 AI 可读取、可调用、可校验的能力包。

一个 Skill 通常是一个目录,里面至少包含一份说明文件和一些可执行资源。说明文件告诉 AI:这个技能在什么场景下使用,有哪些输入参数,应该按什么顺序执行,最后输出什么结果。AI 收到用户请求后,先判断当前任务是否匹配某个 Skill,如果匹配,就按照说明调用脚本、读取示例或运行命令。

在视频转场场景里,Skill 的核心价值是稳定。跨场转场涉及xfadezoompanfade等滤镜,参数稍有偏差就会得到黑屏、闪帧或偏移错误。把参数说明和生成逻辑写进 Skill,AI 就不需要回忆“上个视频是怎么做的”,而是直接查找能力包里的模板。

1.2 Skill、Agent、插件和普通脚本的边界

这几个概念经常混在一起。先看它们的分工:

概念核心作用在视频转场场景中的例子
Skill给 AI 提供一套可复用的操作流程和工具说明video-transition-skill,包含 SKILL.md 和生成 FFmpeg 命令的脚本
Agent负责拆解任务、调用多个工具、根据结果决定下一步用户说“生成转场并发送到工作群”,Agent 先调用 Skill 生成视频,再调用上传脚本
插件通常指扩展 IDE 或 CLI 功能的程序模块编辑器中集成视频预览面板,不属于 AI 能力包
普通脚本能独立完成一个具体操作,但 AI 不知道它存在单独运行的make_transition.py,只能由人手动执行

Skill 和 Agent 的关系,可以理解为“职业手册”和“管理层”的关系。Agent 负责决策和编排,Skill 负责提供标准作业程序。如果只有脚本,AI 不知道该怎么用;如果只有提示词,执行结果不够稳定。Skill 正好把两者结合起来。

1.3 视频转场特效为什么适合封装成 Skill

视频转场是典型的高重复、高参数化任务。每一次转场都需要指定输入文件、转场类型、持续时间、开始时间和输出路径。参数组合很多,但规律固定。用户往往不会说“用 xfade 滤镜,transition=fade,duration=1.0,offset=3.2”,而是说“在第二个片段开始前做一个柔和过渡”。

封装成 Skill 后,AI 能完成一次“自然语言转结构化参数”的转换。它先把用户描述映射成 JSON 配置,再调用脚本生成命令,最后执行并反馈结果。这样用户不需要记住 FFmpeg 滤镜语法,AI 也不需要依赖记忆生成命令,整个链路更接近工程化。

2. 环境准备:一个能跑通的最小组合

2.1 需要准备哪些工具

要复现下面的示例,建议准备一个最小环境:

工具用途最低建议
Python 3运行脚本,解析 JSON 配置3.8 及以上
FFmpeg执行视频滤镜和编码支持xfade滤镜的版本
ffprobe读取视频时长等元数据随 FFmpeg 安装
支持 Skill 机制的 AI 编程助手让模型能读取 SKILL.md 并调用脚本任选你已使用的工具

这里不绑定某一个具体平台。常见的编程助手对 Skill 的目录约定可能略有差异,有的放在项目.agents/skills下,有的放在用户级~/.claude/skills~/.codex/skills下。落地前先查一下当前工具的文档,确认它读取的是哪个目录。

2.2 确认 Skill 目录约定

如果你的 AI 助手已经支持 Skill 机制,通常会有一个约定的查找路径。比如:

项目根目录/ .agents/ skills/ video-transition-skill/ SKILL.md scripts/ make_transition.py

有些平台使用.claude/skills.codex/skills~/.codex/skills。还有的会把 Skill 放在用户级目录,方便所有项目共用。为了不对版本下结论,建议你按当前工具的文档确认关键词:SKILL.md、skills 目录、是否支持项目级配置。

确认目录时可以做一次最简测试:在候选目录下新建一个hello-skill/SKILL.md,写入“当用户说 hello 时,回复 skill ok”,然后让 AI 触发。如果助手能引用这个文件,说明目录路径正确。

2.3 准备测试视频片段

示例脚本需要两段输入视频。为了快速验证,可以用 FFmpeg 生成两个带颜色的测试片段:

ffmpeg -f lavfi -i color=c=red:size=640x360:duration=5 -c:v libx264 -pix_fmt yuv420p clip1.mp4 ffmpeg -f lavfi -i color=c=blue:size=640x360:duration=5 -c:v libx264 -pix_fmt yuv420p clip2.mp4

执行完后检查:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 clip1.mp4

如果能看到类似5.000000的输出,说明测试片段可用。注意生成测试片段时建议指定-pix_fmt yuv420p,否则后续视频拼接可能因为像素格式不一致报错。

3. 创建 video-transition-skill:目录结构与核心文件

3.1 目录结构先定下来

一个最小的 Skill 可以只有SKILL.md,但做视频转场建议把“说明”和“可执行脚本”分开:

video-transition-skill/ SKILL.md scripts/ make_transition.py examples/ crossfade.json fadeblack.json

每个文件的作用:

  • SKILL.md:给 AI 看的说明书,描述技能用途、参数、执行步骤和注意事项。
  • scripts/make_transition.py:读取 JSON 配置,自动计算转场偏移,输出 FFmpeg 命令。
  • examples/:存放不同转场类型的示例配置,方便 AI 快速复制。

目录结构不要写成多级嵌套。Skill 本身应该是独立、单一职责的能力包,目录越简单越容易被读取。

3.2 编写 SKILL.md,告诉 AI 什么时候用、怎么用

下面是一份可用的 SKILL.md 示例,你需要根据自己平台的 frontmatter 要求做调整:

# video-transition-skill 为两段视频生成转场特效。支持 crossfade、fadeblack、wipeleft、 slideleft、circleopen 等基于 xfade 滤镜的转场。 ## 适用场景 用户提供两段视频路径,并希望合成一个带转场效果的新视频时, 使用本技能。 ## 使用步骤 1. 确认两个输入视频文件存在,且可以被 ffprobe 读取。 2. 将用户需求整理成 JSON 配置,写入临时文件或直接作为命令行参数。 3. 先执行 dry-run 生成命令并展示给用户确认。 4. 用户确认后,使用 --run 执行生成。 ## 命令示例 python scripts/make_transition.py --config examples/crossfade.json --dry-run python scripts/make_transition.py --config examples/crossfade.json --run ## 配置字段 - input1: 第一段视频路径。 - input2: 第二段视频路径。 - transition: 转场类型,默认 crossfade。 - duration: 转场时长,单位秒,默认 1.0。 - offset: 可选,转场开始时间。不填时脚本会尝试自动计算。 - output: 输出视频路径,默认 output.mp4。 ## 注意事项 - duration 必须小于第一段视频的时长。 - 不要覆盖输入文件。 - 执行前先 dry-run,避免 ffmpeg 参数错误导致输出文件损坏。

关键点在于“适用场景”要具体。AI 判断是否调用 Skill 时,依赖这份描述来判断匹配度。如果写得太宽泛,AI 可能在不合适的时候调用;写得太窄,又会漏掉真实需求。最好在真实助手环境中测试几轮,再补充边界情况。

3.3 编写 make_transition.py,把转场参数变成 FFmpeg 命令

脚本不需要处理像素级算法,FFmpeg 已经帮我们做好了。脚本的职责是把 JSON 配置转换成合理的 FFmpeg 命令,并在执行前校验参数。

先创建一个scripts/make_transition.py

#!/usr/bin/env python3 import argparse import json import subprocess import sys from pathlib import Path TRANSITIONS = { "crossfade": "fade", "fadeblack": "fadeblack", "wipeleft": "wipeleft", "slideleft": "slideleft", "circleopen": "circleopen", } def get_duration(path: str) -> float: cmd = [ "ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", str(path), ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise RuntimeError(f"无法读取视频时长: {path} -> {result.stderr}") return float(result.stdout.strip()) def build_command(config: dict): input1 = config.get("input1") input2 = config.get("input2") if not input1 or not input2: raise ValueError("配置中必须包含 input1 和 input2") transition = config.get("transition", "crossfade") if transition not in TRANSITIONS: raise ValueError(f"不支持的转场类型: {transition}") duration = float(config.get("duration", 1.0)) output = config.get("output", "output.mp4") duration1 = None try: duration1 = get_duration(input1) except RuntimeError: print("警告:无法读取第一段视频时长,将依赖配置中的 offset。", file=sys.stderr) if duration1 and duration >= duration1: raise ValueError("转场时长必须小于第一段视频时长") offset = config.get("offset") if offset is None: if duration1: offset = max(duration1 - duration, 0) else: raise ValueError("无法自动计算 offset,请在配置中提供 offset") else: offset = float(offset) filter_complex = ( f"[0:v][1:v]xfade=transition={TRANSITIONS[transition]}" f":duration={duration}:offset={offset}[v]" ) return [ "ffmpeg", "-i", input1, "-i", input2, "-filter_complex", filter_complex, "-map", "[v]", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-y", output, ] def main(): parser = argparse.ArgumentParser(description="生成视频转场 FFmpeg 命令") parser.add_argument("--config", required=True, help="JSON 配置文件路径") parser.add_argument("--dry-run", action="store_true", help="只打印命令,不执行") args = parser.parse_args() config = json.loads(Path(args.config).read_text(encoding="utf-8")) cmd = build_command(config) print("生成的命令:") print(" ".join(cmd)) if args.dry_run: return print("开始执行……") subprocess.run(cmd, check=True) print("转场视频已生成:", config.get("output", "output.mp4")) if __name__ == "__main__": main()

这段脚本有几个设计点。

get_duration用 ffprobe 获取第一段视频时长,目的是自动计算offset。在xfade滤镜中,offset表示转场开始的时间点,通常等于第一段视频时长减去转场时长。例如第一段视频 5 秒,转场 1 秒,offset 应为 4 秒,这样第二段视频从第 4 秒开始混合进入。

build_command返回的是字符串列表,而不是直接拼成 shell 字符串。这样执行时不需要经过 shell,可以减少特殊字符带来的问题。FFmpeg 命令中可能包含中文路径、空格、括号,使用参数列表更安全。

--dry-run是安全边界。脚本默认行为只打印命令,用户确认后再通过--run实际执行。如果 AI 直接执行未经确认的命令,一旦输出路径写错或参数异常,可能会覆盖已有文件。

4. 用 JSON 配置驱动转场生成

4.1 配置字段说明

为了让 AI 能稳定生成配置,建议在SKILL.md和示例文件里把字段写仔细。

以一个交叉溶解示例为例,创建examples/crossfade.json

{ "input1": "clip1.mp4", "input2": "clip2.mp4", "transition": "crossfade", "duration": 1.0, "output": "output_crossfade.mp4" }

字段含义如下表:

字段是否必填默认值说明
input1第一段视频路径
input2第二段视频路径
transitioncrossfade转场类型
duration1.0转场时长,单位秒
offset自动计算转场开始时间,单位秒
outputoutput.mp4输出视频路径

4.2 自动计算 offset 的原理

xfade滤镜要求两个输入视频在时间轴上重叠。它的时间轴逻辑是:第二段视频从offset秒处开始与第一段视频混合,混合持续duration秒。如果第一段视频总长为 5 秒,duration 为 1 秒,offset 应该是 4 秒。

如果 offset 设置过小,转场会在第一段视频还很亮时就开始出现第二段画面;如果 offset 过大,转场结束后第一段可能已经结束,画面会黑场。更严重的是,offset 加 duration 超过第一段视频总时长时,FFmpeg 会报错或输出异常。

因此,代码优先用 ffprobe 读取真实时长,再自动计算 offset。只有在读取失败时才要求用户在配置中手动填写 offset。实际项目中,如果输入视频来自剪辑软件,时长信息通常可靠;如果来自网络下载或录屏,最好保留手动 offset 覆盖能力。

4.3 从用户一句话到 Skill 执行的完整链路

当 AI 支持 Skill 机制后,完整链路可以这样理解:

  1. 用户说:“把 clip1.mp4 和 clip2.mp4 拼起来,中间用一个 1 秒的淡入淡出转场。”
  2. AI 识别到“两段视频”“转场”等关键词,判定匹配video-transition-skill
  3. AI 读取 SKILL.md,看到使用步骤和参数说明。
  4. AI 把用户描述整理成 JSON 配置,甚至可以自动创建临时配置,也可以参考examples/crossfade.json
  5. AI 先执行 dry-run,得到 FFmpeg 命令并展示。
  6. 用户确认后,AI 去掉--dry-run执行脚本。

这个链路的关键是“结构化参数”。如果 AI 没有把用户描述转换成 JSON,而是直接生成 FFmpeg 命令,就不能复用脚本的校验和 offset 计算逻辑。Skill 的价值不是替代 FFmpeg,而是让 AI 的每一步都可复现、可校验。

5. 运行与验证:不能只看命令输出了

5.1 先跑 dry-run

在 AI 助手环境中,建议先运行:

cd video-transition-skill python scripts/make_transition.py --config examples/crossfade.json --dry-run

预期输出类似:

生成的命令: ffmpeg -i clip1.mp4 -i clip2.mp4 -filter_complex [0:v][1:v]xfade=transition=fade:duration=1.0:offset=4.0[v] -map [v] -c:v libx264 -pix_fmt yuv420p -y output_crossfade.mp4

这里offset=4.0是脚本自动计算出来的。如果 clip1 的时长不是 5 秒,这里会显示实际计算值。看到这段输出后,不要急着执行,先确认三件事:

  • 路径是否正确。
  • 转场类型是否匹配用户描述。
  • offset 是否大于 0 且小于第一段视频时长。

5.2 实际执行生成视频

dry-run 确认无误后执行:

python scripts/make_transition.py --config examples/crossfade.json --run

执行过程中会看到 FFmpeg 的日志。如果正常结束,命令行最后会显示:

转场视频已生成: output_crossfade.mp4

此时先检查文件是否存在:

ls -lh output_crossfade.mp4

文件大小不能是 0。如果文件非常小,很可能是 FFmpeg 阶段失败或者输出为空。

5.3 验证输出视频

验证不能只看文件存在。建议用 ffprobe 检查输出文件:

ffprobe -v error -show_entries format=duration,size:stream=codec_name,width,height -of default=noprint_wrappers=1 output_crossfade.mp4

正常情况下能看到:

duration=9.000000 size=... codec_name=h264 width=640 height=360

两个 5 秒视频通过 1 秒交叉溶解合成,总时长约为 9 秒。如果是 10 秒,可能没有真正实现转场,而是把两个视频直接拼接了。常见问题里会提到这个判断方法。

如果条件允许,再用播放器打开输出文件,肉眼确认画面过渡是否平滑。颜色测试片段比较适合验证:红蓝两个片段交叉溶解时,中间会出现红蓝色混合的紫色过渡,说明转场生效。

6. 常见问题排查:从现象倒推根因

6.1 SKILL.md 没有被 AI 识别

现象是:用户触发了转场需求,但 AI 不读取 SKILL.md,也没有调用脚本。

排查顺序:

  1. 确认 Skill 放在 AI 助手要求的目录下。不同的工具可能读取.agents/skills.claude/skills.codex/skills
  2. 确认文件名严格为SKILL.md,大小写不能错。
  3. 确认 SKILL.md 里的描述足够清晰。如果“适用场景”太模糊,AI 可能不会匹配。
  4. 确认工具是否开启了 Skill 权限。有些 CLI 工具有自动批准或手动确认的权限模型。

可以先做一个最小 hello-skill 测试。如果最小用例能跑通,问题往往出在描述文本或路径上。

6.2 FFmpeg 报 No such filter

执行命令后出现:

No such filter: 'xfade'

原因是 FFmpeg 版本太旧。xfade滤镜在 FFmpeg 4.3 之后才提供。你的机器上可能使用系统软件源安装的旧版本。

处理方式:

ffmpeg -version

查看版本号。如果版本过低,需要更新 FFmpeg 或下载新版静态构建包。如果无法更新,最简单的方式是换用fade滤镜实现简单的淡入淡出,但两段视频拼接的逻辑会变复杂,建议优先升级 FFmpeg。

6.3 输出视频总时长等于两个片段时长之和

如果 output 总时长是 10 秒,而不是约 9 秒,通常说明xfade没有真正生效,或者命令被 Fallback 成了 concat。

检查点:

  • 命令中是否包含-filter_complexxfade字样。
  • 是否能看到转场过程。颜色片段中是否有混合色。
  • 如果 AI 工具没有调用脚本,而是自己拼了命令,可以用 dry-run 输出的命令手动执行对比。

这个问题的根源是 AI 绕过了 Skill 脚本。遇到时不要继续调整 FFmpeg,先回到“有没有走 Skill 脚本”这条路径排查。

6.4 JSON 解析失败或 offset 报错

现象是脚本执行后报:

ValueError: 不支持的转场类型: crossfade

或:

ValueError: 无法自动计算 offset,请在配置中提供 offset

前者通常说明输入配置里写了不支持的类型,检查TRANSITIONS字典和 JSON 拼写。后者说明 ffprobe 无法读取第一段视频时长,可能输入文件路径错误、文件损坏或 ffprobe 未安装。

先手动运行:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 clip1.mp4

如果没有任何输出且返回值非 0,说明文件读不了,换一下输入视频,或在 config 中手写offset绕过自动计算。

6.5 输出画面花屏或绿屏

可能是像素格式问题。FFmpeg 某些滤镜链输出可能是 yuv420p,也可能是其他格式。脚本里已经加了-pix_fmt yuv420p,但如果手动执行命令时漏掉,播放兼容性会变差。另外,输入视频尺寸不一致时也容易出现异常。建议先把输入视频统一为相同分辨率再合成。

7. 最佳实践与扩展方向

7.1 编写 Skill 时的可复用清单

不要只把上面的例子复制到项目里就结束,建议按这份清单检查:

  • 是否有独立的 SKILL.md,且文件名为全大写。
  • 描述里是否说明了适用场景和禁用场景。
  • 是否有明确的参数表,包含默认值。
  • 是否区分 dry-run 和实际执行。
  • 是否有示例配置,方便 AI 复制。
  • 脚本是否使用参数列表调用子进程,而不是拼 shell 字符串。
  • 输入输出路径是否做了校验。
  • 是否检查了错误码并给出人可读的提示。
  • 是否有针对输出文件的长度或内容验证方法。

这份清单可以复用到图片合成、音频处理、字幕生成等类似 Skill 开发中。Skill 越规范,AI 越不容易误用。

7.2 生产环境使用建议

在本地试验可以直接运行脚本,但进入生产或半自动流程时要注意:

  • 加入日志:记录输入配置、生成的命令、执行结果、耗时和错误信息。
  • 加入并发控制:FFmpeg 是大资源任务,多个任务同时执行会抢占 CPU。
  • 对视频大小和时长做限制,防止输出巨大文件。
  • 输出文件不要覆盖原片,建议写入独立输出目录并带时间戳。
  • 对 AI 调用设置权限边界,不要让模型随意执行任意命令。脚本内部只暴露白名单参数,不要透传成 shell。

如果要在服务器上提供接口供前端调用,建议把 Skill 脚本封装成 REST API,而不是让前端直接触发命令行。这样既能做参数校验,也能统一记录操作日志。

7.3 扩展:更多转场、批量处理和其他 Agent 平台

当前脚本只支持xfade滤镜的几种转场。实际可扩展方向包括:

  • 增加xfade支持的其他转场名,比如fadewhiteslideupsmoothupdissolve
  • 增加对单视频内部镜头的zoompan推进效果,适合 vlog 节奏感。
  • 增加批量处理,遍历一个目录下所有片段,两两拼接。
  • 增加音频交叉淡化,使用acrossfade滤镜。
  • 把 Skill 迁移到支持相似机制的其他 AI 平台,只需保留脚本,调整 SKILL.md 的约定格式。

对于刚入门的读者,建议先不做太多转场类型,而是把“配置 -> dry-run -> 执行 -> 验证”这条链路跑熟。视频处理最容易出现的问题不是滤镜不会写,而是参数上下文没有对齐:时长、分辨率、帧率、像素格式都可能影响最终结果。把 Skill 当成一个受约束的工程组件来对待,AI 生成视频转场特效这条路就能走得更稳。

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

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

立即咨询