FFmpeg删除了动画GIF的最后一帧上的时间延迟

5
我正在尝试使用ffmpeg和x264将动态GIF转换为MP4文件。然而,我似乎遭受了ffmpeg中this bug的影响,这会导致GIF的最后一帧的延迟时间被忽略。对于非常短的GIF来说,这是一个相当大的问题。
作为解决方法,我认为我应该能够手动告诉ffmpeg在最后一帧上冻结一定的时间,特别是我可以从GIF中提取出该帧的正确持续时间。但是,我似乎找不到一个好的方法来做到这一点。有什么建议吗?我真的很想能够在不必将GIF拆分成帧之前就将其放入ffmpeg中进行处理,因为这将破坏具有非恒定帧速率的GIF(除了速度更慢)。
我正在使用ffmpeg版本2.3,尽管我也尝试过使用最新的git代码,但没有任何改进。我使用的完整ffmpeg命令如下:
ffmpeg -i animation.gif -vf "scale=trunc(in_w/2)*2:trunc(in_h/2)*2" -c:v libx264 -b:v 2000k -y -pix_fmt yuv420p -f mp4 animation.mp4

这里是一些控制台输出:
ffmpeg version 2.3 Copyright (c) 2000-2014 the FFmpeg developers
  built on Aug 11 2014 21:19:46 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --enable-gpl --enable-libass --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libx264
  libavutil      52. 92.100 / 52. 92.100
  libavcodec     55. 69.100 / 55. 69.100
  libavformat    55. 48.100 / 55. 48.100
  libavdevice    55. 13.102 / 55. 13.102
  libavfilter     4. 11.100 /  4. 11.100
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 19.100 /  0. 19.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, gif, from 'animation.gif':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: gif, bgra, 500x375, 100 tbr, 100 tbn, 100 tbc
[libx264 @ 0x239ea00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x239ea00] profile High, level 3.1
[libx264 @ 0x239ea00] 264 - core 142 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - 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=abr mbtree=1 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'animation.mp4':
  Metadata:
    encoder         : Lavf55.48.100
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 500x374, q=-1--1, 2000 kb/s, 100 fps, 12800 tbn, 100 tbc
    Metadata:
      encoder         : Lavc55.69.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (gif (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=    7 fps=0.0 q=-1.0 Lsize=       7kB time=00:00:00.05 bitrate=1222.1kbits/s dup=5 drop=0    
video:7kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 13.542441%
[libx264 @ 0x239ea00] frame I:1     Avg QP:34.86  size:  3657
[libx264 @ 0x239ea00] frame P:3     Avg QP:30.86  size:   744
[libx264 @ 0x239ea00] frame B:3     Avg QP:33.33  size:    49
[libx264 @ 0x239ea00] consecutive B-frames: 42.9%  0.0%  0.0% 57.1%
[libx264 @ 0x239ea00] mb I  I16..4: 10.2% 78.3% 11.6%
[libx264 @ 0x239ea00] mb P  I16..4:  1.2%  5.0%  0.8%  P16..4: 11.7%  3.3%  1.2%  0.0%  0.0%    skip:76.8%
[libx264 @ 0x239ea00] mb B  I16..4:  0.0%  0.1%  0.0%  B16..8:  3.7%  0.0%  0.0%  direct: 0.0%  skip:96.2%  L0:23.5% L1:76.5% BI: 0.0%
[libx264 @ 0x239ea00] final ratefactor: 20.31
[libx264 @ 0x239ea00] 8x8 transform intra:77.0% inter:79.4%
[libx264 @ 0x239ea00] coded y,uvDC,uvAC intra: 39.5% 0.0% 0.0% inter: 2.7% 0.0% 0.0%
[libx264 @ 0x239ea00] i16 v,h,dc,p: 38% 27%  7% 28%
[libx264 @ 0x239ea00] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 35% 12% 13%  7%  6% 10%  4%  8%  5%
[libx264 @ 0x239ea00] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 38% 11% 14%  5%  8% 10%  5%  7%  2%
[libx264 @ 0x239ea00] i8c dc,h,v,p: 100%  0%  0%  0%
[libx264 @ 0x239ea00] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x239ea00] ref P L0: 99.1%  0.7%  0.3%
[libx264 @ 0x239ea00] ref B L0: 85.0% 15.0%
[libx264 @ 0x239ea00] ref B L1: 95.4%  4.6%
[libx264 @ 0x239ea00] kb/s:689.83
1个回答

3

我成功修改了这个答案,建议使用覆盖过滤器和nullsrc。然而,nullsrc会对透明GIF造成问题,因此我使用了color代替:

ffmpeg -i animation.gif -filter_complex "color=c=white:s=340x240:d=0.300 [base]; [base][0:v] overlay" -c:v libx264 -b:v 2000k -y -pix_fmt yuv420p -f mp4 animation.mp4

由于叠加滤镜的默认操作是在基础源耗尽之前保持覆盖层的最后一帧,这有效地欺骗了FFmpeg以正确获取最后一帧的持续时间。但是,这样做的缺点是需要预先知道GIF的尺寸和正确的持续时间(可以使用ImageMagick完成此操作)。
此外,原始命令使用缩放滤镜来确保GIF每边有偶数个像素(因为yuv420p需要这样做)。新命令使用“color”维度自动处理这一点,因此在设置尺寸时需要将GIF尺寸向下舍入到最接近的偶数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接