关于 media-composition
用于将分别生成的 GIF、视频和图像合成为教程或文档素材的 Skill。它通过 YAML 清单校验输入,并使用 FFmpeg 按堆叠、网格、叠加或画中画等布局合成。
主要功能
- 01解析 YAML 清单
- 02校验组件文件是否存在
- 03使用 FFmpeg 合成媒体
- 04支持堆叠、网格与叠加布局
- 05验证输出并记录指标
适用场景
- 01合并终端与浏览器录屏
- 02制作并排媒体对比
- 03构建画中画演示
- 04为教程和文档组合媒体素材
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ athola/ claude-night-market --skill media-composition安装后在 Claude Code 中输入/media-composition确认已加载。
详细介绍
媒体合成技能
将多个媒体资源(GIF、视频、图像)合并为复合输出,用于制作详尽的教程和文档。
适用场景
- 将多个媒体输出合并为复合内容
- 从终端和浏览器录制内容制作复合演示
不适用场景
- 无需合成的单格式输出
- 简单的终端录制——直接使用 scry:vhs-recording
概述
此技能负责将分别生成的媒体资源合成为统一输出。它会读取定义组件及其合成规则的清单文件,验证所有输入均存在,并执行 FFmpeg 命令以生成最终的复合媒体。
前置条件
使用此技能前,以下工具必须在 PATH 中可用:
ffmpeg:用于媒体合成和编码yq:用于解析 YAML 清单
运行 ffmpeg -version 和 yq --version,以确认工具可用。
必需的进度项
- Parse composition manifest file
- Validate all component outputs exist
- Determine composition layout and parameters
- Execute FFmpeg composition command
- Verify combined output file created
- Report composition metrics (file size, dimensions)
清单格式
清单用于定义要合并的组件及其排列方式:
# Example manifest: tutorials/mcp.manifest.yaml
name: mcp
title: "MCP Server Integration"
components:
- type: tape
source: mcp.tape
output: assets/gifs/mcp-terminal.gif
- type: playwright
source: browser/mcp-browser.spec.ts
output: assets/gifs/mcp-browser.gif
requires:
- "skrills serve"
combine:
output: assets/gifs/mcp-combined.gif
layout: vertical
options:
padding: 10
background: "#1a1a2e"
清单架构
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
name | string | 是 | 合成内容的标识符 |
title | string | 否 | 便于阅读的标题 |
components | array | 是 | 要合并的媒体组件列表 |
components[].type | string | 是 | 源类型:tape、playwright、static |
components[].source | string | 是 | 源文件路径 |
components[].output | string | 是 | 生成的输出路径 |
components[].requires | array | 否 | 生成前要运行的命令 |
combine.output | string | 是 | 合并后输出的路径 |
combine.layout | string | 是 | 布局模式(见下表) |
combine.options | object | 否 | 布局专属选项 |
分步流程
1. 解析清单文件
# Read and validate manifest structure
yq eval '.' manifest.yaml
# Extract component outputs
yq eval '.components[].output' manifest.yaml
2. 验证组件输出
# Check all required files exist
for output in $(yq eval '.components[].output' manifest.yaml); do
if [[ ! -f "$output" ]]; then
echo "ERROR: Missing component: $output"
exit 1
fi
done
3. 执行 FFmpeg 合成
根据清单中指定的布局,执行相应的 FFmpeg 命令。
4. 验证合并后的输出
# Verify output exists and has content
if [[ -f "$output" && -s "$output" ]]; then
echo "Composition successful: $output"
ls -lh "$output"
else
echo "ERROR: Composition failed"
exit 1
fi
FFmpeg 合成命令
垂直堆叠
将 GIF/视频从上到下堆叠:
ffmpeg -i top.gif -i bottom.gif \
-filter_complex "[0:v][1:v]vstack=inputs=2" \
-y output.gif
添加间距:
ffmpeg -i top.gif -i bottom.gif \
-filter_complex "[0:v]pad=iw:ih+10:0:0:color=black[top];[top][1:v]vstack=inputs=2" \
-y output.gif
水平堆叠
将 GIF/视频并排堆叠:
ffmpeg -i left.gif -i right.gif \
-filter_complex "[0:v][1:v]hstack=inputs=2" \
-y output.gif
顺序拼接
依次播放 GIF/视频:
# Create concat list file
cat > concat_list.txt << EOF
file 'first.gif'
file 'second.gif'
file 'third.gif'
EOF
# Concatenate
ffmpeg -f concat -safe 0 -i concat_list.txt \
-y output.gif
网格布局(2x2)
ffmpeg -i tl.gif -i tr.gif -i bl.gif -i br.gif \
-filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2" \
-y output.gif
添加背景颜色
ffmpeg -i top.gif -i bottom.gif \
-filter_complex "color=c=#1a1a2e:s=800x600[bg];[bg][0:v]overlay=0:0[tmp];[tmp][1:v]overlay=0:300" \
-y output.gif
布局选项
| 布局 | 描述 | 选项 |
|---|---|---|
vertical | 从上到下堆叠 | padding、background、align |
horizontal | 从左到右堆叠 | padding、background、align |
sequential | 按顺序播放 | transition、duration |
grid | N x M 网格排列 | rows、cols、padding |
overlay | 相互叠加 | position、opacity |
pip | 画中画 | corner、scale、margin |
布局选项详情
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
padding | int | 0 | 组件之间的像素间距 |
background | string | "black" | 背景颜色(十六进制值或名称) |
align | string | "center" | 对齐方式:left、center、right |
transition | string | "none" | 转场类型:fade、wipe、none |
scale | float | 0.25 | PiP 缩放比例 |
corner | string | "br" | PiP 角落位置:tl、tr、bl、br |
合成示例
终端和浏览器教程
name: plugin-demo
components:
- type: tape
source: demo.tape
output: terminal.gif
- type: playwright
source: browser.spec.ts
output: browser.gif
combine:
output: demo-combined.gif
layout: vertical
options:
padding: 5
background: "#0d1117"
并排对比
name: before-after
components:
- type: static
source: before.gif
output: before.gif
- type: static
source: after.gif
output: after.gif
combine:
output: comparison.gif
layout: horizontal
options:
padding: 10
画中画
name: pip-demo
components:
- type: tape
source: main.tape
output: main.gif
- type: playwright
source: overlay.spec.ts
output: overlay.gif
combine:
output: pip-demo.gif
layout: pip
options:
corner: br
scale: 0.3
margin: 20
完成标准
- 成功解析清单文件
- 验证所有组件输出均已存在
- FFmpeg 合成命令执行成功,未发生错误
- 合并后的输出文件存在且大小不为零
- 已记录输出尺寸和时长
- 已清理临时文件
评论
支持 Markdown