2

截至 2020 年,ffmpeg 具有xfade 过滤器,可以将视频与过渡相结合。组合两个视频很容易:

ffmpeg -i vid1.mp4 -i vid2.mp4 \
  -filter_complex [0][1]xfade=transition=pixelize:duration=1:offset=4,format=yuv420p" \
  out.mp4

但我不明白如何组合三个视频(以便 v1 淡入 v2 和 v2 然后淡入 v3。我尝试过这样的事情:

ffmpeg -i vid1.mp4 -i vid2.mp4 -i vid3.mp4 \
  -filter_complex [0][1]xfade=transition=pixelize:duration=1:offset=4,format=yuv420p[0n1];[0n1][2]xfade=transition=pixelize:duration=1:offset=9,format=yuv420p" \
  out.mp4

但这不起作用。我的想法是,0 和 1,或 vid1 和 vid2,将通过 xfade 转换为 [0n1] 流,然后可以将 0n1 流与 vid3 与另一个过滤器组合。据我所知,这包括前两个视频,但不包括第三个。这当然意味着我不明白如何正确指定过滤器图!

我应该如何使用 xfade 将 3 个或更多视频与它们之间的过渡结合起来?

一个完整的例子如下。在这里,我将使用三张图像(因为这样可以避免以不同帧速率组合视频的问题),并将它们全部粉碎到 500x500 以方便使用(在最终版本中,它们将被信箱化以保持分辨率等)。

ffmpeg \
  -loop 1 -t 5 -i tests/p1.jpg \
  -loop 1 -t 5 -i tests/p2.jpg \
  -loop 1 -t 5 -i tests/p3.jpg \
  -filter_complex "[0]scale=500:500[s0];[1]scale=500:500[s1];[2]scale=500:500[s2];[s0][s1]xfade=transition=pixelize:duration=1:offset=4,format=yuv420p[s01];[s01][s2]xfade=transition=pixelize:duration=1:offset=9,format=yuv420p" out.mp4

我希望这会创建一个视频:

  • 4 秒的 p1.jpg
  • 像素化过渡到 p2.​​jpg 持续 1 秒
  • 4 秒的 p2.jpg
  • 像素化过渡到 p3.jpg 持续 1 秒
  • 4 秒的 p3.jpg

但我实际上得到的是

  • 4 秒的 p1.jpg
  • 像素化过渡到 p2.​​jpg 持续 1 秒
  • 4 秒的 p2.jpg

然后视频结束。p3 根本不包括在内。

输出如下:

ffmpeg version N-53546-g5eb4405fc5-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 56.100 / 56. 56.100
  libavcodec     58. 97.100 / 58. 97.100
  libavformat    58. 49.100 / 58. 49.100
  libavdevice    58. 11.101 / 58. 11.101
  libavfilter     7. 87.100 /  7. 87.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Input #0, image2, from 'tests/p1.jpg':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 44845 kb/s
    Stream #0:0: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 820x1270 [SAR 150:150 DAR 82:127], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, image2, from 'tests/p2.jpg':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 22325 kb/s
    Stream #1:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 960x600 [SAR 1:1 DAR 8:5], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #2, image2, from 'tests/p3.jpg':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 15266 kb/s
    Stream #2:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 728x669 [SAR 96:96 DAR 728:669], 25 fps, 25 tbr, 25 tbn, 25 tbc
File 'out.mp4' already exists. Overwrite? [y/N] y
Stream mapping:
  Stream #0:0 (mjpeg) -> scale
  Stream #1:0 (mjpeg) -> scale
  Stream #2:0 (mjpeg) -> scale
  format -> Stream #0:0 (libx264)
Press [q] to stop, [?] for help
[swscaler @ 0x8228040] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x8258640] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x827df40] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x829f800] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x82c13c0] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x82e8340] deprecated pixel format used, make sure you did set range correctly
[libx264 @ 0x77b7600] using SAR=82/127
[libx264 @ 0x77b7600] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x77b7600] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 0x77b7600] 264 - core 161 r3018 db0d417 - H.264/MPEG-4 AVC codec - Copyleft 2003-2020 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out.mp4':
  Metadata:
    encoder         : Lavf58.49.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 500x500 [SAR 82:127 DAR 82:127], q=-1--1, 25 fps, 12800 tbn, 25 tbc (default)
    Metadata:
      encoder         : Lavc58.97.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame=  101 fps=100 q=28.0 size=       0kB time=00:00:01.92 bitrate=   0.2kbits/s speed=[swscaler @ 0x8291d80] deprecated pixel format used, make sure you did set range correctly
    Last message repeated 2 times
[swscaler @ 0x82b3000] deprecated pixel format used, make sure you did set range correctly
    Last message repeated 2 times
[swscaler @ 0x82fc200] deprecated pixel format used, make sure you did set range correctly
    Last message repeated 2 times
frame=  153 fps=101 q=28.0 size=       0kB time=00:00:04.00 bitrate=   0.1kbits/s speed=[swscaler @ 0x82fc200] deprecated pixel format used, make sure you did set range correctly
    Last message repeated 2 times
frame=  225 fps=111 q=28.0 size=     256kB time=00:00:06.88 bitrate= 304.9kbits/s dup=0 frame=  225 fps= 95 q=-1.0 Lsize=     267kB time=00:00:08.88 bitrate= 245.9kbits/s dup=0 drop=125 speed=3.74x    
video:263kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.293847%
[libx264 @ 0x77b7600] frame I:2     Avg QP:21.03  size: 19928
[libx264 @ 0x77b7600] frame P:66    Avg QP:21.18  size:  2453
[libx264 @ 0x77b7600] frame B:157   Avg QP:29.72  size:   427
[libx264 @ 0x77b7600] consecutive B-frames:  5.3%  4.4%  1.3% 88.9%
[libx264 @ 0x77b7600] mb I  I16..4: 29.0% 27.8% 43.2%
[libx264 @ 0x77b7600] mb P  I16..4: 10.8%  3.2%  7.5%  P16..4:  2.6%  0.9%  0.3%  0.0%  0.0%    skip:74.8%
[libx264 @ 0x77b7600] mb B  I16..4:  1.1%  0.5%  1.6%  B16..8:  1.0%  0.5%  0.1%  direct: 0.3%  skip:94.9%  L0:37.4% L1:43.5% BI:19.1%
[libx264 @ 0x77b7600] 8x8 transform intra:16.5% inter:55.3%
[libx264 @ 0x77b7600] coded y,uvDC,uvAC intra: 31.4% 71.7% 31.8% inter: 1.1% 1.4% 0.1%
[libx264 @ 0x77b7600] i16 v,h,dc,p: 45% 46%  9%  1%
[libx264 @ 0x77b7600] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 30% 27%  6%  1%  1%  2%  1%  7%
[libx264 @ 0x77b7600] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 56% 31%  9%  1%  1%  1%  1%  1%  1%
[libx264 @ 0x77b7600] i8c dc,h,v,p: 46% 27% 23%  4%
[libx264 @ 0x77b7600] Weighted P-Frames: Y:10.6% UV:7.6%
[libx264 @ 0x77b7600] ref P L0: 61.9% 17.1% 13.9%  6.8%  0.3%
[libx264 @ 0x77b7600] ref B L0: 76.3% 22.8%  0.9%
[libx264 @ 0x77b7600] ref B L1: 97.6%  2.4%
[libx264 @ 0x77b7600] kb/s:238.88
4

1 回答 1

2

第二个 xfade 的偏移量是错误的。对于 5 秒剪辑和每个剪辑尾部的 1 秒过渡,第二个剪辑从 4 秒开始到 9 秒结束,因此第二个 xfade 的偏移量应该是 8,而不是 9。

所以,

ffmpeg \
  -loop 1 -t 5 -i tests/p1.jpg \
  -loop 1 -t 5 -i tests/p2.jpg \
  -loop 1 -t 5 -i tests/p3.jpg \
  -filter_complex "[0]scale=500:500[s0];[1]scale=500:500[s1];[2]scale=500:500[s2];[s0][s1]xfade=transition=pixelize:duration=1:offset=4,format=yuv420p[s01];[s01][s2]xfade=transition=pixelize:duration=1:offset=8,format=yuv420p" out.mp4
于 2020-07-26T10:56:27.333 回答