Skip to content

Instantly share code, notes, and snippets.

@anisse
Last active August 20, 2025 15:53
Show Gist options
  • Save anisse/ffc7dc7b3301ea11a0e5fc8155889b21 to your computer and use it in GitHub Desktop.
Save anisse/ffc7dc7b3301ea11a0e5fc8155889b21 to your computer and use it in GitHub Desktop.
Script to do the optimal compression of a gif or video into a slack emoji. Cropping or limiting the number of frames should be done separately.
#!/bin/bash
set -euo pipefail
INPUT="$1"
DIMENSION="${2:-128}"
QUALITY=100
TARGET_SIZE=130278 # Not the real value, but I'm too lazy to really test the slack limits
TMPOUT=$(mktemp gifski-slack.XXXXXXX)
TMPYUV=$(mktemp gifski-slack-yuv.XXXXXXX)
MIN=1
MAX=100
trap 'rm -f -- "$TMPOUT" "$TMPYUV"' EXIT
ffmpeg -loglevel warning -i "$INPUT" -vf "format=yuv420p" -f yuv4mpegpipe -y "$TMPYUV"
while true
do
echo "Trying quality = $QUALITY..."
gifski --quiet --width "$DIMENSION" --height "$DIMENSION" --quality "$QUALITY" --output "$TMPOUT" "$TMPYUV"
SIZE=$(stat -c %s "$TMPOUT")
if [ "$QUALITY" = 100 ]; then
if [ "$SIZE" -lt "$TARGET_SIZE" ]; then
echo "Target size reached with maximum quality. Nothing to do"
break
fi
QUALITY=1
continue
fi
if [ "$SIZE" -gt "$TARGET_SIZE" ]; then
if [ "$QUALITY" = 1 ]; then
echo "Target size cannot be reached even with minimum quality. Sorry"
break
fi
MAX="$QUALITY"
fi
if [ "$SIZE" -lt "$TARGET_SIZE" ]; then
MIN="$QUALITY"
fi
if [ "$SIZE" -eq "$TARGET_SIZE" ] || [ "$SIZE" -le "$TARGET_SIZE" ] && [ $((MAX-MIN)) = 1 ]; then
break
fi
QUALITY=$((MIN + (MAX-MIN) / 2 ))
done
INPUT_FILE="${INPUT##*/}"
mv "$TMPOUT" "${INPUT_FILE%.*}-gifslack.gif"
@anisse
Copy link
Author

anisse commented Aug 20, 2025

Update: I'm not sure this works if you are close to the limit: it seems slack always reencodes and might be much worse than gifski in some edge cases. Anyway, it at least helps getting close to the limit.

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