用FFmpeg进行视频淡入淡出的有效方法是什么?


11

在FFmpeg中,在两个视频内容之间进行淡入淡出实际上非常复杂。没有像音频一样的“交叉淡入淡出”过滤器。

什么是有效的方法?


很好的自我解答问题!
JakeGould 2015年

这个答案需要更多的支持...马克,如果您也为音频添加了交叉渐变功能,我将永远爱您...
Merc

一旦确定了方法,就将其添加。我认为音频交叉淡入淡出很简单,但确实有一个简单的过滤器。
Mark Gerolimatos 2015年

我只是简单地添加[0:a][1:a] acrossfade=d=1 [audio]到过滤器,然后添加到-map "[audio]" 命令,它就可以了。如果您愿意,请进行测试并更新答案!
Merc 2015年

Answers:


17

TL; DR版本:

本示例仅执行视频,并假定两个视频剪辑的分辨率,帧频等相同。这将在fadeoutclip和fadeinclip之间创建1秒的淡入。假设fadeoutclip长10秒。请注意,此文件的格式是为了清楚起见:它实际上是一行代码。

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an \
-filter_complex "\
    [0:v]trim=start=0:end=9,setpts=PTS-STARTPTS[firstclip]; \
    [1:v]trim=start=1,setpts=PTS-STARTPTS[secondclip]; \
    [0:v]trim=start=9:end=10,setpts=PTS-STARTPTS[fadeoutsrc]; \
    [1:v]trim=start=0:end=1,setpts=PTS-STARTPTS[fadeinsrc]; \
    [fadeinsrc]format=pix_fmts=yuva420p, \
                fade=t=in:st=0:d=1:alpha=1[fadein]; \
    [fadeoutsrc]format=pix_fmts=yuva420p, \
                fade=t=out:st=0:d=1:alpha=1[fadeout]; \
    [fadein]fifo[fadeinfifo]; \
    [fadeout]fifo[fadeoutfifo]; \
    [fadeoutfifo][fadeinfifo]overlay[crossfade]; \
    [firstclip][crossfade][secondclip]concat=n=3[output] \
    " \
-map "[output]" <add in encoding part here>

完整版本:

这是关于这一切的解释:

输入规格...明显

ffmpeg -i fadeoutclip.mp4 -i fadeinclip.mp4 -an

创建一个filter_complex 假设您已经了解过滤器组合:

-filter_complex

首先,我们使用修整滤镜将两个流分成两部分:内容和交叉淡入淡出部分。淡入分为内容和淡入淡出部分,而淡入被分为淡入淡出部分和内容。共有四个部分。

请注意,严格来说,我们不具备打破淡入淡出部分指出:我们可以只指定淡出淡入时间的两个视频剪辑。但是,通过这样做,我们:

  • 遵循GUI视频编辑人员通常使用的方法
  • 避免使用令人沮丧的overlay过滤器复杂性
  • 确保解决方案尽可能通用(即可重用的代码)
  • 让我们根据需要对交叉淡入淡出部分进行预处理和后处理(此处未完成)

这四个部分分别指定:开始时间(秒),结束时间(秒)和神秘setpts=PTS-STARTPTS过滤器,从本质上讲,每个视频子剪辑都从0秒开始。重新组合它们时,这一点至关重要。

请注意,这些s=0说明符是多余的,而这些说明符的setpts过滤器s=0也是多余的。但是,都冗余地指定了两者,以允许启动时间从0开始变化,而不会破坏滤波器的复杂度。另外,第二个内容剪辑将运行到末尾,因此e=未指定部分(end =)。

    [0:v]trim=s=0:e=9,setpts=PTS-STARTPTS[firstclip];
    [1:v]trim=s=1,setpts=PTS-STARTPTS[secondclip];
    [0:v]trim=s=9:e=10,setpts=PTS-STARTPTS[fadeoutsrc];
    [1:v]trim=s=0:e=1,setpts=PTS-STARTPTS[fadeinsrc];

接下来,我们指定淡入和淡出:首先,通过将像素格式指定为,yuva420p向两个淡出部分添加一个alpha(透明)通道。实际上,您可以使用提供Alpha通道的任何格式。

接下来,在此过滤器子复合物中,我们指定一个淡入淡出,然后指定一个淡入淡入。alpha=1意味着视频本身不会变暗,只有透明度会“淡入淡出”。st表示开始,d表示持续时间。

    [fadeinsrc]format=pix_fmts=yuva420p,      
                fade=t=in:st=0:d=1:alpha=1[fadein];
    [fadeoutsrc]format=pix_fmts=yuva420p,
                fade=t=out:st=0:d=1:alpha=1[fadeout];

这是什么? fifo筛选器确保筛选器组合中有可用的缓冲区空间。令人惊讶的是,这不是默认设置。如果不这样做,则如果上一阶段的输出超出了下面的叠加层滤镜,则淡入淡出可能会失败。是的,我知道您现在在想什么。这确实是FFMPEG错误

    [fadein]fifo[fadeinfifo];
    [fadeout]fifo[fadeoutfifo];

现在,叠加两个淡入淡出部分:通过确保两个淡入淡出部分的大小相同,我们不必担心叠加滤镜采用的相当讨厌的选项(因此我们在这里忽略它们):

    [fadeoutfifo][fadeinfifo]overlay[crossfade];

最后,我们使用concat过滤器将我们的三个部分对齐

    [firstclip][crossfade][secondclip]concat=n=3[output]

现在,将输出面板映射为您的视频源。

不要忘记将像素格式设置为您通常使用的格式(通常为yuv420p),因为淡入淡出部分会将其设置yuv420为输出通道!(因为我们没有指定它,所以您可以使用overlay参数)当然,如果您想要yuv420,那么就可以了:-)

-map "[output]" <add your normal encoding part here>

然后,您可以稍后重新组合音频(不在本问答的范围之内)


1
在最新的ffmpeg中,它必须为trim=start=0:end=9,(而不是trim=st=0:e=9,..
Merc 2015年

但认真的说,这将是我见过的FFMPEG的最佳答案,也是有史以来最清晰的ffmpeg解释。
Merc 2015年

伙计,这将成为我的头绪:-)谢谢你的道具!!!
Mark Gerolimatos 2015年

别担心。请更新答案,尤其是= trim = start = 0,因为它现在不适用于最新的ffmpeg
Merc

最新的ffmpeg版本给我这个错误:Filter setpts has an unconnected output对于脚本。我已经将修整参数更改为开始和结束。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.