How to prepare nice animation of CLI commands

Recently, I have decided to make my Github profile landing page more pleasing to the eye. At some point, I have decided that animated GIF with a terminal commands will look nice. And here, the trouble started.

At first, I have decided to simply type in commands by hand. But it was terrible. First of all, the keystrokes were inconsistent, delays between commands were also inconsistent, and lots of post processing in the ScreenFlow was required (cutting the movie here and there). This was also completely irreproducible approach. I wanted something better.

— tmux to the rescue —

It turned out, I can automate the whole process with a super easy approach – tmux sending keys to other tmux session. This is extremely simple. All I had to do was running tmux session in one terminal window (I have used Cathode application to get the retro look of the terminal).

tmux new-session -d -s SESSION
tmux attach -t SESSION

(source: link)

and then, in another terminal window, all I had to do was to run the script that was passing keys to my SESSION running under tmux.

#!/bin/bash

declare -a arr=("get-ready-set-go" "bash" "vim" "javac" "mvn" \
  "gcc" "g++" "python" "git" "docker" "docker-compose")

for word in "${!arr[@]}"; do
  to_process=${arr[word]}
  for i in $(seq 1 ${#to_process}); do
    tmux send-keys -t SESSION: "${to_process:i-1:1}"; sleep 0.2;
  done
  sleep 0.5
  tmux send-keys -t SESSION: "C-a C-k"
  sleep 0.5
done

This way, I was able to capture perfect and consistent typing experience. With a ScreenFlow capturing the whole thing I was able to move on to the next step.

— ScreenFlow —

Inside ScreenFlow I had to make all the proper layout, shadow of the terminal, etc. This is however, extremely simple to achieve once you know how to use ScreenFlow. The last piece of the process was to generate GIF.

— ffmpeg —

Unfortunately, ScreenFlow produces a little bit scattered animated GIFs. You can read about my past experience with ScreenFlow and animated GIFs here. This is why, last step requires two elements: (1) generation of mp4 movie, (2) conversion to animated GIF. Once you have your movie generated, you can easily convert it to animated GIF with ffmpeg.

> ffmpeg -y -i terminal.mp4 \
    -vf palettegen palette.png
> ffmpeg -y -i terminal.mp4 \
    -i palette.png \
    -filter_complex paletteuse \
    -r 15 terminal.gif

With this, I had all I wanted to have. But, there was still one issue. It turned out that animated GIF flickers at the last frame. This was unacceptable.

— Photoshop to the rescue —

It turned out that just before looping the animated GIF flickers. I had to alter the GIF a little bit to make it perfect

Import GIF into Photoshop.
Go to Window > Timeline
Go to last frame of the GIF and delete it.
Then, File > Export > Save for Web (Legacy) and save it as a GIF.

(source: link)

And, eventually, I got my perfect CLI animation, one that you can see on my Github homepage.