问题
I am using ffmpeg to convert high quality videos to gif, most of the videos are 60fps and over 720p
, but when I use the code below, to convert the video to gif, I get very low fps for the gif output,
#!/usr/bin/env
palette=/tmp/pallete.png
filter="fps=50,scale=480:-1:flags=lanczos"
ffmpeg -y -i test.mov -vf $filter,palettegen=stats_mode=diff $palette
ffmpeg -y -i test.mov -i $palette -lavfi "$filter [x]; [x][1:v] paletteuse" test.gif
another issue I have noted is - as the width increases e.g 720
instead of 480
I get even lower fps.
here is output log example, the output fps is lower than the assigned 50fps
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/tmp/201631203815.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.36.100
Duration: 00:00:05.48, start: 0.016000, bitrate: 1579 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1334x1334, 1576 kb/s, 60.18 fps, 60 tbr, 1000k tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Input #1, png_pipe, from '/tmp/pallete.png':
Duration: N/A, bitrate: N/A
Stream #1:0: Video: png, rgba(pc), 16x16 [SAR 1:1 DAR 1:1], 25 tbr, 25 tbn, 25 tbc
Output #0, gif, to '/tmp/201631203815.gif':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.40.101
Stream #0:0: Video: gif, pal8, 480x480, q=2-31, 200 kb/s, 50 fps, 100 tbn, 50 tbc (default)
Metadata:
encoder : Lavc56.60.100 gif
Stream mapping:
Stream #0:0 (h264) -> fps
Stream #1:0 (png) -> paletteuse:palette
paletteuse -> Stream #0:0 (gif)
Press [q] to stop, [?] for help
frame= 275 fps= 32 q=-0.0 Lsize= 2480kB time=00:00:05.50 bitrate=3693.5kbits/s
How do I ensure that the output fps is always whats set by the user? Any resource on this is highly appreciated.
UPDATE
i have also noticed that the use of a higher fps eg filter="fps=90,scale=480:-1:flags=lanczos"
has the effect of slowing down the gif,like a slow motion effect, the output fps is still lower around 15fps,
回答1:
setting the fps value explicitly gave the same lower fps output results frame= 346 fps= 24 q=-0.0 Lsize= 6506kB time=00:00:06.92 bitrate=7701.8kbits/s
This is not the output fps! It's the encoding speed. Most players don't properly play GIFs with a fps higher than 50
. See the demo showing this behaviour.
回答2:
I'm not experienced in making GIF files with FFmpeg, but as far as I know, the fps
filter has an idividual "fps" parameter for the actual framerate value, so I think it may not work correctly if you omit that.
Just to make sure the filter gets the correct value, you should explicitly set the fps value:
filter="fps=fps=50,scale=480:-1:flags=lanczos"
If it doesn't working, I'd try the regular "rate" option too:
ffmpeg -y -i test.mov -i $palette -lavfi "$filter [x]; [x][1:v] paletteuse" -r 50 test.gif
Otherways, your console output looks good (it indicates the output will be 50fps), so the phenomena is a little bit mysterious.
Working Solution:
All you need to do is to break the process into three individual steps, and use the "-framerate" demux-option.
First, let's generate the palette file:
ffmpeg -i <input_file> -filter_complex "scale=w=480:h=-1:flags=lanczos, palettegen=stats_mode=diff" palette.png
Secondly, break the video frames into image files:
ffmpeg -i <input_file> -r 50 -f image2 image_%06d.png
And finally, join said images into one GIF sequence: (the important part here is the image2 demuxer's framerate option!)
ffmpeg -framerate 50 -i img_%06d.png -i palette.png -filter_complex "[0]scale=w=400:h=-1[x];[x][1:v] paletteuse" -pix_fmt rgb24 output.gif
Edit: Finally find the answer!
You need to use image2 demuxer's -framerate option! (answer edited accordingly)
Alternative methods:
- gifsickle - convert images to gif, can set frame delay
- ImageMagic - can convert video to gif directly, excellent gif quality control options.
来源:https://stackoverflow.com/questions/37558504/lower-fps-when-using-ffmpeg-to-convert-mp4-to-gif