Skip to content

Instantly share code, notes, and snippets.

@YclepticStudios
Last active March 3, 2026 06:28
Show Gist options
  • Select an option

  • Save YclepticStudios/bf8fc41c4074217fe741286a2359e82b to your computer and use it in GitHub Desktop.

Select an option

Save YclepticStudios/bf8fc41c4074217fe741286a2359e82b to your computer and use it in GitHub Desktop.
Helper script for recording Pebble watch emulator GIFs on Linux (tested on Ubuntu 24)
#!/bin/bash
# =============================================================================
# record_pebble.sh
#
# DESCRIPTION:
# Records the selected Pebble emulator window and converts the captured
# output to a minimal, pixel perfect animated GIF.
#
# USAGE:
# ./record_pebble.sh [output.gif]
#
# DEPENDENCIES:
# sudo apt install xdotool ffmpeg xwininfo
#
# TIPS:
# - Call 'light_enable(true)' in your app's startup handler to keep the
# backlight at full brightness throughout the recording.
# - Disable vibrations, if your app has them, to prevent the emulator screen
# from shaking and interfering with the recording.
# =============================================================================
set -euo pipefail
# Variables
OUTPUT="${1:-output.gif}"
TMP_DIR=$(mktemp -d)
MP4="$TMP_DIR/recording.mp4"
DECIMATED="$TMP_DIR/decimated.mp4"
PALETTE="$TMP_DIR/palette.png"
FPS=15
# Error handling
trap 'echo "Error on line $LINENO" >&2; rm -rf "$TMP_DIR"' ERR
trap 'rm -rf "$TMP_DIR"' EXIT
# Get targeted window information
echo "Click the emulator window to record..."
WIN_INFO=$(xwininfo)
WIN_ID=$(echo "$WIN_INFO" | grep "Window id:" | awk '{print $4}')
X=$(echo "$WIN_INFO" | grep "Absolute upper-left X" | awk '{print $NF}')
Y=$(echo "$WIN_INFO" | grep "Absolute upper-left Y" | awk '{print $NF}')
W=$(echo "$WIN_INFO" | grep "Width:" | awk '{print $NF}')
H=$(echo "$WIN_INFO" | grep "Height:" | awk '{print $NF}')
# Remove padding from basalt emulator (better way to do this?)
if [[ "$W" -eq 148 && "$H" -eq 172 ]]; then
X=$((X + 2))
Y=$((Y + 2))
W=$((W - 4))
H=$((H - 4))
fi
# Transfer focus from the terminal to the selected window
xdotool windowactivate --sync "$WIN_ID"
# Capture the screen as a lossless video to the temp directory
echo "Capturing window. Press Ctrl+C to stop recording..."
ffmpeg -f x11grab -draw_mouse 0 -framerate $FPS -i "$DISPLAY" \
-vf "crop=${W}:${H}:${X}:${Y}" -c:v libx264rgb -crf 0 "$MP4" -v error || true
# Strip out unused frames, maintaining the lossless quality
echo "Processing recording..."
ffmpeg -i "$MP4" -vf "mpdecimate,fps=$FPS" -c:v libx264rgb -crf 0 \
"$DECIMATED" -v error
# Generate a minimal color pallet
ffmpeg -i "$DECIMATED" -vf "palettegen=max_colors=64:reserve_transparent=0" \
"$PALETTE" -v error
# Encode the video as a gif
ffmpeg -i "$DECIMATED" -i "$PALETTE" \
-filter_complex "[0:v][1:v]paletteuse=dither=none" -y "$OUTPUT" -v error
echo "GIF saved to: $OUTPUT"
@ericmigi
Copy link

ericmigi commented Mar 3, 2026

Thanks, I just pushed a fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment