Creating gameplay gifs that look decent on Twitter can be a bit of a challenge, so we thought we would share a few things we learned while making them for our own game.
So first a quick note on the process of creating a gif:
- You record footage from your game, say a 5 minute video.
- You extract a 10 second clip to show.
- You convert this clip into a gif.
- You upload this gif to twitter.
At each stage in this process, you want to ensure not to lose any quality in the footage. This is very important, as Twitter will heavily compress your gif on upload, and any loss of quality that already exists will be amplified.
Sample gif we created using this process - see it on twitter
Setup Kazam to record as Lossless JPEG so no quality is lost, and with at least 30 frames per second (any lower and gameplay may appear choppy).
To extract a clip from gameplay footage we use ffmpeg.
ffmpeg -i gameplay.avi -ss 30 -t 10 -codec copy -y gameplay-cut.avi
This basically says input the gameplay.avi video, then start the clip at 30s and cut out a 10s segment, and save that segment as gameplay-cut.avi. It is important to use the -codec copy option, as this ensures no conversion or changes are made to the actual video, and its quality is kept intact.
Creating the GIF
To create a gif from our extracted clip we again use ffmpeg. As gifs are limited to 256 colors, and we want to use colors from our footage, we need to first create a color palette from our clip.
ffmpeg -i gameplay-cut.avi -vf "fps=30,palettegen=stats_mode=diff" -y /tmp/palette.png
An important setting here is palettegen=stats_mode=diff - this tells ffmpeg to give priority to the moving parts of the gif (which will be your player, enemies, etc.) and less priority to static elements (such as backgrounds).
Now we can use this palette to generate the actual gif:
ffmpeg -i gameplay-cut.avi -i /tmp/palette.png -lavfi "fps=30 [x]; [x][1:v] paletteuse=dither=none" -y gameplay.gif
Another important setting here is paletteuse=dither=none - since a gif can only have 256 colors, by default it will try to use dithering to fake more colors. This can ruin pixelart, so we tell it not to do that. If your game is not pixelart you can change this to simply paletteuse.
One final step we will take is to optimize the gif using gifsicle:
gifsicle -O3 gameplay.gif -o gameplay-opt.gif
This reduces the size of the gif usually by about 20%.
Using a Bash Script
To simplify this process, we made a bash script so you can do:
./make_gif.sh 00005 30 10
Kazam saves its files as kazam__00005.avi, so we just use the id of the video (00005), then provide a start time (30) and length (10).
Here's the full script:
#!/bin/bash # bash script to create gif from avi # usage: # ./make_gif.sh filename start_time length id=$1 file=kazam__$1 start=$2 length=$3 palette="/tmp/palette.png" filters="fps=30" # echo params to terminal echo "$file $start $length" # cut avi to segment we want ffmpeg -ss $start -i $file.avi -t $length -codec copy -y $file-cut.avi # make palette for gif ffmpeg -i $file-cut.avi -vf "$filters,palettegen=stats_mode=diff" -y $palette # create gif from cut segment ffmpeg -i $file-cut.avi -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=none" -y $id-s$start-t$length-raw.gif # optimize gif gifsicle -O3 $id-s$start-t$length-raw.gif -o $id-s$start-t$length-opt.gif # delete work files rm $file-cut.avi