关于 ffmpeg-transitions-effects
这是面向视频编辑工作流的 FFmpeg 转场与效果参考指南,适合需要拼接片段、制作幻灯片或添加淡入淡出的创作者。内容涵盖内置转场、多个片段的偏移计算及自定义表达式。
主要功能
- 01使用 xfade 制作片段转场
- 02添加视频淡入淡出与音频交叉淡化
- 03计算多片段转场偏移量
- 04通过表达式和蒙版构建自定义效果
适用场景
- 01为多个视频片段添加转场
- 02从图片序列制作带转场的幻灯片
- 03同步处理视频与音频淡入淡出
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill ffmpeg-transitions-effects安装后在 Claude Code 中输入/ffmpeg-transitions-effects确认已加载。
详细介绍
关键指南
Windows 文件路径要求
强制要求:在 Windows 上始终使用反斜杠表示文件路径
在 Windows 上使用 Edit 或 Write 工具时,必须在文件路径中使用反斜杠(\),而不是正斜杠(/)。
文档指南
除非用户明确要求,否则绝不创建新的文档文件。
快速参考
| 转场 | 命令 |
|---|---|
| 交叉淡化 | [0:v][1:v]xfade=transition=fade:duration=1:offset=4[v] |
| 溶解 | xfade=transition=dissolve:duration=1:offset=4 |
| 向左擦除 | xfade=transition=wipeleft:duration=1:offset=4 |
| 圆形展开 | xfade=transition=circleopen:duration=1.5:offset=4 |
| 向左滑动 | xfade=transition=slideleft:duration=1:offset=4 |
| 淡入/淡出 | -vf "fade=t=in:d=1,fade=t=out:st=9:d=1" |
| 音频交叉淡化 | [0:a][1:a]acrossfade=d=1[a] |
| 偏移量公式 | 对于包含 N 个片段且转场时长为 T 的情况 |
|---|---|
| offset1 | clip1_duration - T |
| offset2 | 2*duration - 2*T |
| offsetN | N*duration - N*T |
何时使用此技能
适用于视频转场工作流:
- 通过专业转场拼接片段
- 从图像创建幻灯片
- 添加淡入/淡出效果
- 编辑多片段序列
- 自定义转场表达式
FFmpeg 转场与特效(2025)
使用 FFmpeg 处理视频转场、交叉淡化和创意特效的完整指南。
转场概览
可用方法
| 方法 | 使用场景 | 复杂度 |
|---|---|---|
| xfade 滤镜 | 两个片段之间 | 中等 |
| fade 滤镜 | 单个片段的淡入/淡出 | 简单 |
| blend 滤镜 | 帧混合 | 简单 |
| overlay + alpha | 自定义转场 | 高级 |
xfade 转场类型
FFmpeg 的 xfade 滤镜支持 40 多种内置转场:
| 类别 | 转场 |
|---|---|
| 淡化 | fade、fadeblack、fadewhite、fadegrays |
| 擦除 | wipeleft、wiperight、wipeup、wipedown、wipetl、wipetr、wipebl、wipebr |
| 滑动 | slideleft、slideright、slideup、slidedown |
| 揭示 | revealright、revealleft、revealup、revealdown |
| 推入 | horzopen、horzclose、vertopen、vertclose |
| 圆形 | circleopen、circleclose、circlecrop |
| 矩形 | rectcrop、hblur、radial |
| 对角线 | diagtl、diagtr、diagbl、diagbr |
| 像素特效 | dissolve、pixelize、hlslice、hrslice、vuslice、vdslice |
| 其他 | zoomin、squeezeh、squeezev、hlwind、hrwind、vuwind、vdwind、coverleft、coverright、coverup、coverdown |
基本淡化效果
淡入/淡出(单个片段)
# Fade in from black (first 2 seconds)
ffmpeg -i video.mp4 \
-vf "fade=t=in:st=0:d=2" \
-c:a copy \
fade_in.mp4
# Fade out to black (last 2 seconds)
ffmpeg -i video.mp4 \
-vf "fade=t=out:st=8:d=2" \
-c:a copy \
fade_out.mp4
# Both fade in and fade out
ffmpeg -i video.mp4 \
-vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" \
-c:a copy \
fade_both.mp4
# Fade to white instead of black
ffmpeg -i video.mp4 \
-vf "fade=t=out:st=8:d=2:color=white" \
-c:a copy \
fade_white.mp4
带音频淡化
# Video and audio fade in/out together
ffmpeg -i video.mp4 \
-vf "fade=t=in:st=0:d=2,fade=t=out:st=8:d=2" \
-af "afade=t=in:st=0:d=2,afade=t=out:st=8:d=2" \
fade_complete.mp4
# Audio crossfade between two files
ffmpeg -i audio1.mp3 -i audio2.mp3 \
-filter_complex "[0][1]acrossfade=d=3:c1=tri:c2=tri" \
crossfade.mp3
xfade 转场(片段之间)
xfade 基本用法
# Simple crossfade between two clips
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=fade:duration=1:offset=4[v];\
[0:a][1:a]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" \
output.mp4
参数:
transition:转场效果类型duration:转场时长,单位为秒offset:转场开始的时间(从第一个片段开始计算)
常见转场效果
# Dissolve (pixel-based crossfade)
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=dissolve:duration=1:offset=4[v]" \
-map "[v]" dissolve.mp4
# Wipe left to right
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=wipeleft:duration=1:offset=4[v]" \
-map "[v]" wipe_left.mp4
# Wipe right to left
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=wiperight:duration=1:offset=4[v]" \
-map "[v]" wipe_right.mp4
# Slide left
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=slideleft:duration=1:offset=4[v]" \
-map "[v]" slide_left.mp4
# Circle open (iris)
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=circleopen:duration=1.5:offset=4[v]" \
-map "[v]" circle_open.mp4
# Circle close
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=circleclose:duration=1.5:offset=4[v]" \
-map "[v]" circle_close.mp4
# Radial wipe
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=radial:duration=1.5:offset=4[v]" \
-map "[v]" radial.mp4
# Zoom in
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=zoomin:duration=1:offset=4[v]" \
-map "[v]" zoom_in.mp4
# Pixelize transition
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=pixelize:duration=1:offset=4[v]" \
-map "[v]" pixelize.mp4
# Diagonal wipe (top-left to bottom-right)
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=diagtl:duration=1:offset=4[v]" \
-map "[v]" diag_tl.mp4
# Horizontal blur
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=hblur:duration=1:offset=4[v]" \
-map "[v]" hblur.mp4
所有 xfade 转场类型
# Fades
fade # Standard crossfade
fadeblack # Fade through black
fadewhite # Fade through white
fadegrays # Fade through gray
# Wipes
wipeleft # Left to right wipe
wiperight # Right to left wipe
wipeup # Bottom to top wipe
wipedown # Top to bottom wipe
wipetl # Wipe from top-left corner
wipetr # Wipe from top-right corner
wipebl # Wipe from bottom-left corner
wipebr # Wipe from bottom-right corner
# Slides
slideleft # Slide new clip from right
slideright # Slide new clip from left
slideup # Slide new clip from bottom
slidedown # Slide new clip from top
# Reveals
revealleft # Reveal from right edge
revealright # Reveal from left edge
revealup # Reveal from bottom edge
revealdown # Reveal from top edge
# Open/Close
horzopen # Horizontal opening (curtain)
horzclose # Horizontal closing
vertopen # Vertical opening
vertclose # Vertical closing
circleopen # Circle iris open
circleclose # Circle iris close
# Shapes
circlecrop # Circle crop transition
rectcrop # Rectangle crop transition
radial # Radial/clock wipe
# Diagonals
diagtl # Diagonal from top-left
diagtr # Diagonal from top-right
diagbl # Diagonal from bottom-left
diagbr # Diagonal from bottom-right
# Pixel Effects
dissolve # Random pixel dissolve
pixelize # Pixelization effect
hlslice # Horizontal left slice
hrslice # Horizontal right slice
vuslice # Vertical up slice
vdslice # Vertical down slice
# Other
zoomin # Zoom into new clip
squeezeh # Horizontal squeeze
squeezev # Vertical squeeze
hlwind # Horizontal left wind
hrwind # Horizontal right wind
vuwind # Vertical up wind
vdwind # Vertical down wind
coverleft # Cover from right
coverright # Cover from left
coverup # Cover from bottom
coverdown # Cover from top
多片段转场
三个片段之间的转场
# Calculate offsets: clip1=5s, clip2=5s, clip3=5s, transition=1s
# offset1 = clip1_duration - transition = 5-1 = 4
# offset2 = clip1_duration + clip2_duration - 2*transition = 5+5-2 = 8
ffmpeg -i clip1.mp4 -i clip2.mp4 -i clip3.mp4 \
-filter_complex "\
[0:v][1:v]xfade=transition=fade:duration=1:offset=4[v1];\
[v1][2:v]xfade=transition=fade:duration=1:offset=8[v];\
[0:a][1:a]acrossfade=d=1[a1];\
[a1][2:a]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" \
three_clips.mp4
带转场的幻灯片
#!/bin/bash
# slideshow.sh - Create slideshow from images with transitions
DURATION=3 # Each image duration
TRANSITION=1 # Transition duration
FPS=30
# Generate input commands
inputs=""
for img in *.jpg; do
inputs="$inputs -loop 1 -t $DURATION -i $img"
done
# Calculate filter for 4 images
# Adjust offsets based on image count
ffmpeg $inputs \
-filter_complex "\
[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=$FPS[v0];\
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=$FPS[v1];\
[2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=$FPS[v2];\
[3:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=$FPS[v3];\
[v0][v1]xfade=transition=fade:duration=$TRANSITION:offset=$((DURATION-TRANSITION))[x1];\
[x1][v2]xfade=transition=wipeleft:duration=$TRANSITION:offset=$((2*DURATION-2*TRANSITION))[x2];\
[x2][v3]xfade=transition=circleopen:duration=$TRANSITION:offset=$((3*DURATION-3*TRANSITION))[v]" \
-map "[v]" -c:v libx264 -pix_fmt yuv420p \
slideshow.mp4
每个剪切点使用不同的转场
# Use different transitions between each clip
ffmpeg -i clip1.mp4 -i clip2.mp4 -i clip3.mp4 -i clip4.mp4 \
-filter_complex "\
[0:v][1:v]xfade=transition=fade:duration=1:offset=4[x1];\
[x1][2:v]xfade=transition=wipeleft:duration=1:offset=8[x2];\
[x2][3:v]xfade=transition=circleopen:duration=1.5:offset=12[v]" \
-map "[v]" \
varied_transitions.mp4
使用表达式自定义转场
自定义 xfade 表达式
# Custom diagonal wipe with easing
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=custom:duration=1:offset=4:\
expr='if(gt(X+Y,W+H*P),B,A)'[v]" \
-map "[v]" custom_diag.mp4
# Smooth custom fade
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=custom:duration=1:offset=4:\
expr='A*(1-P)+B*P'[v]" \
-map "[v]" smooth_fade.mp4
# Circular reveal with custom center
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=custom:duration=1.5:offset=4:\
expr='if(gt(sqrt(pow(X-W/2,2)+pow(Y-H/2,2)),P*sqrt(pow(W/2,2)+pow(H/2,2))),A,B)'[v]" \
-map "[v]" circle_reveal.mp4
表达式变量
| 变量 | 描述 |
|---|---|
| X | 当前像素的 X 坐标 |
| Y | 当前像素的 Y 坐标 |
| W | 帧宽度 |
| H | 帧高度 |
| P | 进度(0 到 1) |
| A | 第一个片段的像素值 |
| B | 第二个片段的像素值 |
高级转场技巧
亮度/Alpha 遮罩转场
# Using a gradient image as transition mask
ffmpeg -i clip1.mp4 -i clip2.mp4 -loop 1 -i gradient.png \
-filter_complex "\
[0:v]format=rgba[a];\
[1:v]format=rgba[b];\
[2:v]format=gray,scale=1920:1080[mask];\
[a][b][mask]maskedmerge[v]" \
-map "[v]" -t 5 \
luma_transition.mp4
动态模糊转场
# Add motion blur during transition
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]split[a1][a2];\
[1:v]split[b1][b2];\
[a1][b1]xfade=transition=fade:duration=1:offset=4[fade];\
[fade]tblend=all_mode=average:all_opacity=0.5[v]" \
-map "[v]" \
blur_transition.mp4
推入/揭示转场
# Push left (new clip pushes old off screen)
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]fps=30[a];\
[1:v]fps=30[b];\
[a][b]xfade=transition=slideleft:duration=0.5:offset=4.5[v]" \
-map "[v]" \
push_left.mp4
# Cover transition (new clip covers old)
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=coverright:duration=0.75:offset=4.25[v]" \
-map "[v]" \
cover_right.mp4
带 Ken Burns 效果的缩放
# Zoom transition with motion
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]scale=2*iw:-1,zoompan=z='min(zoom+0.0015,1.5)':d=150:s=1920x1080[a];\
[1:v][a]xfade=transition=zoomin:duration=1:offset=4[v]" \
-map "[v]" -t 6 \
zoom_transition.mp4
带文字/图形的转场
标题卡转场
# Fade to title card, then fade to next clip
ffmpeg -i clip1.mp4 \
-f lavfi -i "color=c=black:s=1920x1080:d=3" \
-i clip2.mp4 \
-filter_complex "\
[1:v]drawtext=text='Chapter 2':fontsize=72:fontcolor=white:x=(w-tw)/2:y=(h-th)/2[title];\
[0:v][title]xfade=transition=fadeblack:duration=1:offset=4[x1];\
[x1][2:v]xfade=transition=fadeblack:duration=1:offset=6[v]" \
-map "[v]" \
title_transition.mp4
下三分之一字幕转场
# Animate lower third with clip transition
ffmpeg -i clip1.mp4 -i clip2.mp4 -i lower_third.png \
-filter_complex "\
[0:v][1:v]xfade=transition=fade:duration=1:offset=4[bg];\
[2:v]format=rgba[lt];\
[bg][lt]overlay=x=50:y=H-h-50:enable='between(t,1,4)'[v]" \
-map "[v]" \
lower_third_trans.mp4
性能优化
硬件加速转场
# Use NVENC for faster encoding after transition
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=fade:duration=1:offset=4[v]" \
-map "[v]" \
-c:v h264_nvenc -preset fast \
output.mp4
# Hardware decode + CPU transition + hardware encode
ffmpeg -hwaccel cuda -i clip1.mp4 -hwaccel cuda -i clip2.mp4 \
-filter_complex "[0:v][1:v]xfade=transition=dissolve:duration=1:offset=4[v]" \
-map "[v]" \
-c:v h264_nvenc \
output.mp4
优化预览效果
# Lower resolution preview
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]scale=640:360[a];\
[1:v]scale=640:360[b];\
[a][b]xfade=transition=fade:duration=1:offset=4[v]" \
-map "[v]" \
-c:v libx264 -preset ultrafast \
preview.mp4
故障排除
常见问题
“分辨率不一致”错误
# Ensure both clips have same resolution
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[a];\
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[b];\
[a][b]xfade=transition=fade:duration=1:offset=4[v]" \
-map "[v]" output.mp4
“输入流的帧率不同”警告
# Normalize frame rates
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v]fps=30[a];\
[1:v]fps=30[b];\
[a][b]xfade=transition=fade:duration=1:offset=4[v]" \
-map "[v]" output.mp4
多个片段的偏移量计算
For clips of duration D with transition T:
- offset1 = D - T
- offset2 = 2D - 2T
- offset3 = 3D - 3T
- offsetN = N*D - N*T
音频与视频转场不匹配
# Sync audio crossfade with video xfade
ffmpeg -i clip1.mp4 -i clip2.mp4 \
-filter_complex "\
[0:v][1:v]xfade=transition=fade:duration=1:offset=4[v];\
[0:a][1:a]acrossfade=d=1:c1=tri:c2=tri[a]" \
-map "[v]" -map "[a]" \
output.mp4
验证命令
# Check clip durations before creating transitions
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 clip1.mp4
# Check frame rate
ffprobe -v error -select_streams v -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 clip1.mp4
# Check resolution
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 clip1.mp4
最佳实践
时间安排
- 标准转场时长:0.5-1.5 秒
- 根据内容氛围选择转场风格
- 在同一序列中使用一致的转场
- 避免转场时间过长(>2 秒)
质量
- 在转场前统一分辨率和帧率
- 最终渲染时使用高质量预设
- 批量处理前,以全分辨率测试转场效果
- 考虑片段之间的色彩匹配
风格指南
- 淡入淡出/叠化:通用、专业
- 擦除:充满活力,适合动作内容
- 滑动/推入:现代、动感
- 圆形/光圈:戏剧化、富有舞台感
- 像素化/模糊:有创意、富有艺术感
本指南介绍 FFmpeg 转场。有关绘制形状和图形,请参阅 shapes-graphics skill。
评论
支持 Markdown