video-steal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVideo Steal
视频风格仿制
Someone's edit works and you want it on your own videos. This skill measures their edit, writes it down as a style, and proves it on one of your takes before you use it.
Output:
- : the style, read by
video-agent/styles/<name>.md./video-edit <take> style <name> - : its stills, sound effects and stickers.
video-agent/styles/<name>/ - : the test video.
video-agent/edits/<slug>-<name>/final.mp4
Read references/learnings.md before you start. Each rule in it comes from a copy that got rejected.
某位创作者的剪辑效果很出色,而你希望在自己的视频中复现它。这个 skill 会测量对方的剪辑,将其记录成一种风格,并先在你的一段素材上验证效果,之后你再正式使用。
输出:
- :风格文件,可由
video-agent/styles/<name>.md读取。/video-edit <take> style <name> - :该风格的静帧、音效和贴纸。
video-agent/styles/<name>/ - :测试视频。
video-agent/edits/<slug>-<name>/final.mp4
开始前先阅读 references/learnings.md。其中每条规则都源自一个被拒绝的仿制版本。
How to run it
如何运行
- Preflight: . Missing:
ffmpeg -version && yt-dlp --version./video-setup tools - Talk in the creator's language. Say what you do in one line before each long step.
- : the creator's handle in lowercase with dashes, unless the user names the style.
<name> - Scratch files go in (
video-agent/.tmp/steal-<name>/below).W
- 预检:。如有缺失,运行:
ffmpeg -version && yt-dlp --version。/video-setup tools - 用创作者的语言交流。每个长步骤前用一行说明你要做什么。
- :默认使用创作者账号名的小写形式并以短横线分隔,除非用户为该风格指定了名称。
<name> - 临时文件放在 (下文记为
video-agent/.tmp/steal-<name>/)。W
1. Get the reel
1. 获取 reel
- A local file: use it.
- A YouTube link: .
yt-dlp -o "W/reel.%(ext)s" "<url>" - Instagram or TikTok: try first. If it is blocked (login wall), and Treg is set up (
yt-dlpanswers),treg balance, thentreg catalog search "download an Instagram reel video file"for the price, thentreg catalog get <id>and download the video URL it returns. Otherwise ask the user to save the video and give you the file.treg call <id> --query url=<url> - When you can, study 2 or 3 reels of the same format. One reel can be the exception.
- 本地文件:直接使用。
- YouTube 链接:。
yt-dlp -o "W/reel.%(ext)s" "<url>" - Instagram 或 TikTok:先尝试 。如果被拦截(登录墙),且已配置 Treg(
yt-dlp有响应),则执行treg balance,再通过treg catalog search "download an Instagram reel video file"查询价格,然后执行treg catalog get <id>并下载其返回的视频 URL。否则,请让用户保存视频并提供文件。treg call <id> --query url=<url> - 条件允许时,研究同一格式的 2 或 3 条 reel。只有一条 reel 的情况可以作为例外。
2. Measure
2. 测量
Do all three passes. A style copied from the frames alone misses half of it: the sound and the rhythm.
完成全部三遍分析。仅从画面帧复制风格会遗漏一半信息:声音和节奏。
Frames and cuts
画面帧与剪切点
bash
ffmpeg -v error -y -i W/reel.mp4 -vf "fps=2,scale=270:480,tile=8x3:padding=4:color=black" W/sheet-%02d.jpg
ffmpeg -hide_banner -i W/reel.mp4 -vf "scdet=threshold=12" -an -f null - 2>&1 | grep -o "scd.time: [0-9.]*" | cut -d' ' -f2 > W/cuts.txt
ffprobe -v error -show_entries format=duration -of csv=p=0 W/reel.mp4- Each sheet holds 24 tiles at 2 per second. Sheet N, tile i (from 0) shows second 12(N-1) + i/2.
- Seconds per shot = duration / (number of lines in + 1).
cuts.txt
Read EVERY sheet and write down:
- Layouts: full camera, split screen (where the seam sits), flat color with text, cut-out person on a color, B-roll, screenshots.
- Captions, per layout: font feel (condensed, rounded, serif), case, weight, size, where they sit on the body, how a word appears, which word gets emphasised and how.
- Stickers and images: type, border, size, when they land (on the word that names them?), whether they stack.
- Hook (first 2 s), CTA (last 3 s), color grade (bright and flat, or contrasty and dark).
Save 6 to 10 key stills to :
video-agent/styles/<name>/bash
ffmpeg -v error -y -ss <seconds> -i W/reel.mp4 -frames:v 1 video-agent/styles/<name>/t<seconds>.jpgbash
ffmpeg -v error -y -i W/reel.mp4 -vf "fps=2,scale=270:480,tile=8x3:padding=4:color=black" W/sheet-%02d.jpg
ffmpeg -hide_banner -i W/reel.mp4 -vf "scdet=threshold=12" -an -f null - 2>&1 | grep -o "scd.time: [0-9.]*" | cut -d' ' -f2 > W/cuts.txt
ffprobe -v error -show_entries format=duration -of csv=p=0 W/reel.mp4- 每张接触表包含 24 个图块,每秒采样 2 帧。第 N 张表中的第 i 个图块(从 0 开始)显示第 12(N-1) + i/2 秒的画面。
- 每个镜头的秒数 = 时长 /(中的行数 + 1)。
cuts.txt
务必查看每一张接触表,并记录:
- 布局:全屏镜头、分屏(接缝位置)、纯色背景配文字、人物抠像置于纯色背景、B-roll、屏幕截图。
- 字幕,按布局分别记录:字体风格(紧凑、圆润、衬线)、大小写、字重、字号、相对于人物身体的位置、单词如何出现,以及哪个词被强调及强调方式。
- 贴纸和图片:类型、边框、尺寸、出现时机(是否出现在点明它名称的那个词上)、是否叠加。
- Hook(前 2 秒)、CTA(后 3 秒)、调色(明亮平调,或高对比暗调)。
将 6 到 10 张关键静帧保存到 :
video-agent/styles/<name>/bash
ffmpeg -v error -y -ss <seconds> -i W/reel.mp4 -frames:v 1 video-agent/styles/<name>/t<seconds>.jpgSound
声音
bash
ffmpeg -v error -y -i W/reel.mp4 -lavfi "showspectrumpic=s=3000x500:legend=0:scale=log:stop=11000" W/spectrum.png- The image is 3000 px wide, so a cut at t seconds sits at x = 3000 × t / duration. Read it next to .
cuts.txt - A bright thin vertical stroke high up = a click. Wide and low = a boom. A rising smear = a whoosh. A dark gap across the steady music band = the beat drops out.
- Zoom on one cut to see its hit: .
ffmpeg -v error -y -ss <cut - 1> -t 2 -i W/reel.mp4 -lavfi "showspectrumpic=s=1000x500:legend=0:scale=log:stop=11000" W/cut-<n>.png - Beat: count the regular low strokes over 10 s on the spectrogram (or tap along while it plays): strokes per 10 s × 6 = BPM.
Music level under the voice (optional, needs in , uses a few credits, say so first):
ELEVENLABS_API_KEYvideo-agent/.envbash
set -a; . video-agent/.env; set +a
ffmpeg -v error -y -i W/reel.mp4 -vn -ac 1 -ar 44100 W/full.wav
curl -s -X POST https://api.elevenlabs.io/v1/audio-isolation -H "xi-api-key: $ELEVENLABS_API_KEY" -F audio=@W/full.wav -o W/voice.mp3
ffmpeg -v error -y -i W/voice.mp3 -ac 1 -ar 44100 W/voice.wav
for f in full voice; do ffmpeg -v error -i W/$f.wav -af "asetnsamples=882,astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.RMS_level:file=-" -f null - | grep -o "RMS_level=.*" | cut -d= -f2 > W/rms-$f.txt; done
paste W/rms-voice.txt W/rms-full.txt | awk '$1<-40{print $2}' | sort -n | awk '{a[NR]=$1}END{print "music while the voice is silent:", a[int(NR/2)+1], "dB over", NR/50, "s"}'
awk '$1>-30' W/rms-voice.txt | sort -n | awk '{a[NR]=$1}END{print "voice while talking:", a[int(NR/2)+1], "dB"}'- These commands measure the level every 20 ms. The music is the full mix in the moments the isolated voice is silent.
- Music under the voice = the voice level minus the music level.
- Under 1 s of silence (an edit with every pause cut) is too little to trust: judge it on the spectrogram.
- Never subtract the isolated voice from the mix: it is not in phase with the original, so the result comes out louder than the voice.
- Without a key, judge the level on the spectrogram.
Write down where the music starts and which event gets which sound: cut, sticker, zoom, impact.
bash
ffmpeg -v error -y -i W/reel.mp4 -lavfi "showspectrumpic=s=3000x500:legend=0:scale=log:stop=11000" W/spectrum.png- 图像宽度为 3000 px,因此 t 秒处的剪切点在横轴上的位置为 x = 3000 × t / duration。结合 阅读频谱图。
cuts.txt - 位于高处、细而明亮的竖线 = click(点击声)。又宽又低的竖线 = boom(低频冲击声)。向上扩散的拖影 = whoosh(呼啸声)。稳定音乐频带中出现横向暗色缺口 = 节拍短暂消失。
- 放大某个剪切点以查看其命中音效:。
ffmpeg -v error -y -ss <cut - 1> -t 2 -i W/reel.mp4 -lavfi "showspectrumpic=s=1000x500:legend=0:scale=log:stop=11000" W/cut-<n>.png - 节拍:在频谱图上统计 10 秒内规律出现的低位竖线(也可以在播放时跟着打拍子):每 10 秒的竖线数 × 6 = BPM。
人声下的音乐电平(可选,需要在 中配置 ,会消耗少量 ElevenLabs credits,执行前先告知用户):
video-agent/.envELEVENLABS_API_KEYbash
set -a; . video-agent/.env; set +a
ffmpeg -v error -y -i W/reel.mp4 -vn -ac 1 -ar 44100 W/full.wav
curl -s -X POST https://api.elevenlabs.io/v1/audio-isolation -H "xi-api-key: $ELEVENLABS_API_KEY" -F audio=@W/full.wav -o W/voice.mp3
ffmpeg -v error -y -i W/voice.mp3 -ac 1 -ar 44100 W/voice.wav
for f in full voice; do ffmpeg -v error -i W/$f.wav -af "asetnsamples=882,astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.RMS_level:file=-" -f null - | grep -o "RMS_level=.*" | cut -d= -f2 > W/rms-$f.txt; done
paste W/rms-voice.txt W/rms-full.txt | awk '$1<-40{print $2}' | sort -n | awk '{a[NR]=$1}END{print "music while the voice is silent:", a[int(NR/2)+1], "dB over", NR/50, "s"}'
awk '$1>-30' W/rms-voice.txt | sort -n | awk '{a[NR]=$1}END{print "voice while talking:", a[int(NR/2)+1], "dB"}'- 这些命令每 20 ms 测量一次电平。在分离出的人声处于静音状态的时刻,完整混音反映的就是音乐。
- 人声下的音乐 = 人声电平减去音乐电平。
- 静音区间不足 1 秒(剪辑中每次停顿都被剪掉)时,结果不足以作为可靠依据:请结合频谱图判断。
- 绝不要从混音中减去分离出的人声:它与原始人声并不同相,因此结果会显得比真实人声更响。
- 没有 key 时,请根据频谱图判断电平。
记录音乐从何处开始,以及每个事件对应哪种声音:剪切、贴纸、变焦、冲击。
Zooms
变焦
On the sheets, measure the face height as a share of the frame height on 10 tiles or so, and list the jumps in face size from one tile to the next:
- a jump at a cut = a change of framing between two shots
- a jump inside a shot = a punch-in
- a slow growth over a shot = a push
Write the range (e.g. face 12 to 25 % of the frame), the punch-ins per 10 s, and whether there is a push. These numbers are the ceiling for your copy.
在接触表上选取大约 10 个图块,测量人脸高度占画面高度的比例,并列出相邻图块之间人脸尺寸的跳变:
- 剪切点处发生尺寸跳变 = 两个镜头之间的构图或景别发生变化
- 镜头内部发生尺寸跳变 = punch-in(快速推近)
- 镜头内缓慢增大 = push(缓慢推进)
记录范围(例如,人脸占画面高度的 12% 至 25%)、每 10 秒的 punch-in 次数,以及是否存在 push。这些数值是仿制时的上限。
3. Write the style
3. 编写风格
video-agent/styles/<name>.mdvideo-editmarkdown
undefinedvideo-agent/styles/<name>.mdmarkdown
undefinedStyle: <name>
Style: <name>
Copied from <link>, measured on <date>. Applied on top of video-edit's style.md: what is not here stays as there.
Copied from <link>, measured on <date>. Applied on top of video-edit's style.md: what is not here stays as there.
Cuts
Cuts
- hard cut every 1.4 s on average (35 cuts in 50 s); no fade, no transition
- hard cut every 1.4 s on average (35 cuts in 50 s); no fade, no transition
Framing
Framing
- face 12 to 25 % of the frame; punch-in 1.1 at most, about every 4 s, held until the next cut; slow push 0.6 %/s
- face 12 to 25 % of the frame; punch-in 1.1 at most, about every 4 s, held until the next cut; slow push 0.6 %/s
Captions
Captions
- ...
- ...
Stickers and images
Stickers and images
- ...
- ...
Sound
Sound
- boom bap beat ~90 BPM from the hook impact, 12 dB under the voice, drops out 0.3 s on punch-ins
- a dry high click on most cuts (sfx/cut.wav), a pop on each sticker (sfx/pop.wav)
- boom bap beat ~90 BPM from the hook impact, 12 dB under the voice, drops out 0.3 s on punch-ins
- a dry high click on most cuts (sfx/cut.wav), a pop on each sticker (sfx/pop.wav)
Grade
Grade
- ffmpeg: eq=contrast=1.08:saturation=0.9,vignette=PI/5,unsharp=5:5:0.4
- ffmpeg: eq=contrast=1.08:saturation=0.9,vignette=PI/5,unsharp=5:5:0.4
Left out
Left out
- the AI video clips: replaced by your own footage or a callout
- the AI video clips: replaced by your own footage or a callout
How video-edit applies it
How video-edit applies it
- the components to add to the composition and the props they take
**Sound effects** (in `video-agent/styles/<name>/sfx/`):
- With an ElevenLabs key, generate 2 or 3 takes per sound and keep the one closest to the original on the spectrogram:
```bash
curl -s -X POST https://api.elevenlabs.io/v1/sound-generation -H "xi-api-key: $ELEVENLABS_API_KEY" -H "content-type: application/json" -d '{"text":"single dry short high click, tight transient, no reverb","duration_seconds":0.5}' -o video-agent/styles/<name>/sfx/cut-a.mp3- Otherwise, use a royalty-free library.
Stickers:
- Generate them with . Use the user's REAL photos as the face reference, never a generated face. Ask for a flat #00FF00 background, no shadow, no text.
/codex-images - Key the background out to a transparent PNG:
bash
ffmpeg -v error -y -i sticker.png -vf "colorkey=0x00FF00:0.3:0.08,despill=type=green" -pix_fmt rgba sticker-cut.png
Logos: every app named on screen shows its real logo, never a letter in a circle.
- the components to add to the composition and the props they take
**音效**(位于 `video-agent/styles/<name>/sfx/`):
- 配置 ElevenLabs key 后,为每种音效生成 2 或 3 个版本,并保留在频谱图上最接近原片的一个:
```bash
curl -s -X POST https://api.elevenlabs.io/v1/sound-generation -H "xi-api-key: $ELEVENLABS_API_KEY" -H "content-type: application/json" -d '{"text":"single dry short high click, tight transient, no reverb","duration_seconds":0.5}' -o video-agent/styles/<name>/sfx/cut-a.mp3- 否则,使用免版税素材库。
贴纸:
- 使用 生成。只能使用用户的真实照片作为人脸参考,绝不能使用生成的人脸。要求使用纯 #00FF00 背景,不要阴影,不要文字。
/codex-images - 抠除背景并输出透明 PNG:
bash
ffmpeg -v error -y -i sticker.png -vf "colorkey=0x00FF00:0.3:0.08,despill=type=green" -pix_fmt rgba sticker-cut.png
Logo:屏幕中提及的每个应用都显示其真实 Logo,绝不能只用圆圈里的字母代替。
4. Test it
4. 测试
- Pick a 10 to 20 s take of the user from .
video-agent/takes/ - Run . It reads the style file and adds what it describes to the composition: stickers on the word that names them, sound effects on the cuts, the grade.
/video-edit <take> style <name> - The slug is .
<take slug>-<name>
- 从 中选择一段用户素材,时长为 10 到 20 秒。
video-agent/takes/ - 运行 。该命令会读取风格文件,并将其中描述的内容加入画面合成:贴纸出现在点明其名称的单词上,音效落在剪切点上,并应用调色。
/video-edit <take> style <name> - slug 为 。
<take slug>-<name>
5. Compare before showing
5. 展示前比较
Put the original on top and the copy below, at the same seconds:
bash
ffmpeg -v error -y -i W/reel.mp4 -i video-agent/edits/<slug>/final.mp4 -filter_complex "[0:v]fps=1,scale=216:384,trim=end_frame=15,tile=15x1[a];[1:v]fps=1,scale=216:384,trim=end_frame=15,tile=15x1[b];[a][b]vstack" -frames:v 1 W/compare.jpgGo tile by tile:
- type size and weight
- sticker and logo size (they fill the space like in the original)
- grade
- no fade where the original cuts hard
- captions off the mouth
- nothing upside down
Run the spectrogram on the copy too: the hits must land on the cuts, the beat must sit at the same level under the voice. Measure the face size on its sheets: no more zooms than the original, the face never bigger.
Fix every gap before showing. The user should never be the one to spot it.
将原片放在上方、仿制版本放在下方,在相同秒数处进行对比:
bash
ffmpeg -v error -y -i W/reel.mp4 -i video-agent/edits/<slug>/final.mp4 -filter_complex "[0:v]fps=1,scale=216:384,trim=end_frame=15,tile=15x1[a];[1:v]fps=1,scale=216:384,trim=end_frame=15,tile=15x1[b];[a][b]vstack" -frames:v 1 W/compare.jpg逐个图块检查:
- 字号和字重
- 贴纸和 Logo 的尺寸(应像原片一样填满对应空间)
- 调色
- 原片采用硬切的位置不得出现淡入淡出
- 字幕不得遮挡嘴部
- 不得出现上下颠倒的内容
对仿制版本也要运行频谱图分析:音效命中必须落在剪切点上,节拍在人声下的电平必须与原片一致。测量仿制版本接触表中的人脸尺寸:变焦次数不得多于原片,人脸也绝不能比原片更大。
展示前修复每一处差距。用户不应该由自己来发现问题。
6. Deliver
6. 交付
Open , then tell the user in a few lines:
final.mp4- what was measured (seconds per shot, BPM, music level, zooms)
- what was copied, and what was left out and why
- where the style lives
From now on, uses it. Each time the user rejects something, write it in the style file. When the lesson is general, add it to references/learnings.md.
/video-edit <take> style <name>打开 ,然后用几行告诉用户:
final.mp4- 测量了哪些内容(每个镜头的秒数、BPM、音乐电平、变焦)
- 复制了哪些内容,以及省略了哪些内容及其原因
- 风格文件存放在哪里
从现在起, 会使用该风格。每次用户拒绝某些内容时,都将其写入风格文件。如果经验具有普适性,则添加到 references/learnings.md。
/video-edit <take> style <name>