ffmpeg在动画GIF的最后一帧上丢弃时间延迟

时间:2014-08-12 07:32:17

标签: ffmpeg animated-gif

我正在尝试使用ffmpeg和x264将动画GIF转换为MP4文件。但是,我似乎在ffmpeg中受到this bug的影响,导致忽略GIF最后一帧的延迟时间。对于非常短的GIF,这是一个很大的问题。

作为一种解决方法,我认为我应该能够手动告诉ffmpeg冻结最后一帧一段时间,特别是该帧的正确持续时间(我可以从GIF中提取)。但是,我似乎无法找到一个好方法来做到这一点。有什么建议?我真的希望能够做到这一点,而不必在将它放入ffmpeg之前将其拆分为GIF,因为这会使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 个答案:

答案 0 :(得分:2)

因此我设法修改了this answer,建议将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的尺寸和正确的持续时间(这可以用图像magick完成)。

此外,原始命令我们使用缩放滤镜来确保GIF在每条边上具有偶数个像素(因为yuv420p需要这样)。新命令使用color尺寸自动处理,因此在设置尺寸时,您必须将GIF尺寸向下舍入到最接近的偶数。