I wanted to right-click a video file and instantly turn it into a GIF without opening a video editor or typing long ffmpeg commands (I have no idea how to use ffmpeg btw).

This is for me to remember in the future how to do this if I ever lose the configuration that I have at the moment, so it’s more like a memento than a tutorial.


🧰 What You’ll Need

We’ll use three small tools:

  • FFmpeg – does the actual conversion
  • Zenity – provides a small graphical prompt for options
  • libnotify-bin – sends a desktop notification when the GIF is ready

Install them with:

sudo apt update
sudo apt install -y ffmpeg zenity libnotify-bin

⚙️ Step 1 — Create the conversion script

Create a folder for user scripts (if it doesn’t exist):

mkdir -p ~/.local/bin

Then create the script file:

nano ~/.local/bin/mp4-to-gif

Paste the following:

#!/usr/bin/env bash
set -euo pipefail

have() { command -v "$1" >/dev/null 2>&1; }
notify_ok() { have notify-send && notify-send "GIF created" "$1"; }

FPS_DEFAULT=12
WIDTH_DEFAULT=640
START_DEFAULT=0
DUR_DEFAULT=""

USE_ZENITY=false
if have zenity; then
  CHOICE=$(zenity --list --radiolist --width=420 --height=260 \
    --title="MP4 → GIF options" \
    --text="Choose a preset (you can tweak values after picking one):" \
    --column="" --column="Preset" --column="Details" \
    TRUE "Standard" "FPS 12, width 640, full clip" \
    FALSE "First 10s" "FPS 12, width 640, duration 10s" \
    FALSE "Smooth" "FPS 24, width 720" 2>/dev/null || echo "")

  case "$CHOICE" in
    "First 10s") DUR_DEFAULT=10 ;;
    "Smooth") FPS_DEFAULT=24; WIDTH_DEFAULT=720 ;;
  esac

  FPS=$(zenity --entry --title="FPS" --text="Frames per second" --entry-text="$FPS_DEFAULT" 2>/dev/null || echo "$FPS_DEFAULT")
  WIDTH=$(zenity --entry --title="Width" --text="Output width" --entry-text="$WIDTH_DEFAULT" 2>/dev/null || echo "$WIDTH_DEFAULT")
  START=$(zenity --entry --title="Start time (sec)" --entry-text="$START_DEFAULT" 2>/dev/null || echo "$START_DEFAULT")
  DUR=$(zenity --entry --title="Duration (sec)" --entry-text="$DUR_DEFAULT" 2>/dev/null || echo "$DUR_DEFAULT")
  USE_ZENITY=true
else
  FPS="$FPS_DEFAULT"; WIDTH="$WIDTH_DEFAULT"; START="$START_DEFAULT"; DUR="$DUR_DEFAULT"
fi

if [ $# -lt 1 ]; then
  echo "Usage: mp4-to-gif file1.mp4 [file2.mp4 ...]" >&2
  exit 1
fi

for inpath in "$@"; do
  [ ! -f "$inpath" ] && continue
  base="${inpath%.*}"
  outgif="${base}.gif"
  palette="$(mktemp --suffix=.png)"
  vf="fps=${FPS},scale=${WIDTH}:-1:flags=lanczos"
  ss_args=(); t_args=()
  [ "$START" != "0" ] && ss_args=(-ss "$START")
  [ -n "$DUR" ] && t_args=(-t "$DUR")

  ffmpeg -v warning "${ss_args[@]}" "${t_args[@]}" -i "$inpath" \
    -vf "$vf,palettegen=stats_mode=full" -y "$palette"

  ffmpeg -v warning "${ss_args[@]}" "${t_args[@]}" -i "$inpath" -i "$palette" \
    -lavfi "$vf [x]; [x][1:v] paletteuse=dither=sierra2_4a" \
    -y "$outgif"

  rm -f "$palette"
  notify_ok "$outgif"
  have xclip && printf "%s" "$outgif" | xclip -selection clipboard
done

$USE_ZENITY && zenity --info --text="GIF conversion complete!" --timeout=2 2>/dev/null || true

Make it executable:

chmod +x ~/.local/bin/mp4-to-gif

🖱️ Step 2 — Add the Thunar Context Menu Action

  1. Open Thunar → Edit → Configure Custom Actions → “+”
  2. Name: Convert to GIF
  3. Command:
    mp4-to-gif %F
  4. Switch to Appearance Conditions tab:
    • File pattern: *.mp4;*.mov;*.mkv
    • Check “Video files” (and optionally “Other files”)

🚀 Step 3 — Test It!

Right-click any video file in Thunar and choose Convert to GIF.

You’ll see a Zenity dialog to set FPS, width, and duration. When done, you’ll get a desktop notification and your new .gif will appear next to the original file.


💡 Optional Enhancements

  • Add a “Convert to WebP” action for smaller, modern animated files.
  • Add an “Extract Clip” action to trim videos.
  • Add a “Mute Video” action to strip audio tracks.

Each action can reuse this same structure with a different ffmpeg command.


🧠 Why Palettegen?

Using FFmpeg’s palettegen + paletteuse creates the highest-quality GIFs possible, because it generates a custom 256-color palette for each video frame range. This avoids the grainy, banded look typical of single-pass conversions.


✨ Final Thoughts

This tiny workflow turns Thunar into a lightweight media studio. With a bit of shell scripting, Linux gives you power, automation, and simplicity — no heavy apps are needed.

Save this guide for your future self. The next time you reinstall your system, you’ll have your “Convert to GIF” shortcut ready in minutes.

Happy converting 🎥✨

PS
This page was generated by ChatGPT because I want to keep this on my blog, and I don’t have time to write a proper old-school fancy blog post. So get off my shoulders; it’s 2025.