Earlier today, I posted this post:
Listening to Mike Oldfield - Tubular Bells currently.
The gif in that post I created from a video taken with my phone using ffmpeg
and I really wasn't happy with the result. Which caused me to post this post:
I need some better settings to create a #gif from a #video…
ffmpeg
does alright but, just doing theffmpeg -i video.mp4 -r 10 video.gif
that I’ve been doing makes for some grainy gifs sometimes. It’s a simple and easy to remember command but, I know there has to be a better looking output…
After a bit of searching, I ran across this example and I wrote a bash script so I wouldn't have to try to remember the actual ffmpeg
commands. It's still a work in progress but, I think the end result is somewhat better than the basic command I was using. See the end of this post for a couple of examples.
#!/bin/bash
# mkgif
# v 0.1 - 2016.03.08
#
# License: WTFPL2
#
# From example found here: http://superuser.com/a/556031
# also: http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
# ffmpeg -y -ss 30 -t 3 -i input.flv -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
# ffmpeg -ss 30 -t 3 -i input.flv -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
#
# Requirements:
# ffmpeg
# imagemagick
## DEFAULT OPTIONS ##
palette=/tmp/palette.png
output=/tmp/output.gif
fps=12
size=320
## END DEFAULT OPTIONS ##
USAGE(){
cat << EOF
usage: $(basename $0) options
A wrapper script to convert a video file to a gif using ffmpeg
OPTIONS:
-h Show this message
REQUIRED:
-i Input file
OPTIONAL:
-b Beginning position from start of video (in seconds)
-f FPS (default is 12 frames per second)
-l Length of gif (in seconds)
-o Optimize gif
-s Size of gif in width (default is 320 px)
EOF
}
while getopts "b:f:hi:l:os:" OPTION
do
case $OPTION in
b)
if [[ $OPTARG ]]
then
begin="-ss $OPTARG"
else
begin=
fi
;;
f)
fps=$OPTARG
;;
i)
input="$OPTARG"
;;
h)
USAGE
;;
l)
if [[ $OPTARG ]]
then
length="-t $OPTARG"
else
length=
fi
;;
o)
opt=1
;;
s)
size="$OPTARG"
;;
esac
done
shift $(($OPTIND -1))
OPTIMIZE(){
echo ""
echo Optimizing...
convert -layers Optimize $output $input\.gif
}
CREATEGIF(){
if [[ $input ]]
then
ffmpeg -y $begin $length -i $input -vf fps=$fps,scale=$size:-1:flags=lanczos,palettegen $palette
ffmpeg -y -i $input -i $palette -filter_complex "fps=$fps,scale=$size:-1:flags=lanczos[x];[x][1:v]paletteuse" $begin $length $output
if [[ $opt -eq 1 ]]
then
OPTIMIZE
else
cp $output $input\.gif
fi
else
echo "Input file required!"
echo ""
USAGE
fi
}
CREATEGIF
rm -f $palette $output
exit 0
The source can also be found on my Gogs instance.
And if anyone has any improvements you'd like to pass on to me regarding this, shoot me a message please.