Skip to content

Instantly share code, notes, and snippets.

@mplewis
Last active November 10, 2017 21:58
Show Gist options
  • Save mplewis/62fb4868f92db166744f9a94ee12610d to your computer and use it in GitHub Desktop.
Save mplewis/62fb4868f92db166744f9a94ee12610d to your computer and use it in GitHub Desktop.
Turn screencasts into high-quality gifs with FFmpeg
#!/bin/bash
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
set -x
# http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
# Default settings work great for screencasts. For video from an actual camera, set MOTION=1.
MOTION=${MOTION:-}
if [ ! -z "${MOTION}" ]; then
DITHER=sierra2_4a
STATS_MODE=diff
NO_DIFF_RECT=1
fi
FPS=${FPS:-15}
WIDTH=${WIDTH:--1}
HEIGHT=${HEIGHT:--1}
DITHER=${DITHER:-none}
STATS_MODE=${STATS_MODE:-full}
START_TIME=${START_TIME:-0}
DURATION=${DURATION:-0}
NO_DIFF_RECT=${NO_DIFF_RECT:-}
AND_DIFF_MODE=${AND_DIFF_MODE:-:diff_mode=rectangle}
if [ ! -z "${NO_DIFF_RECT}" ]; then
AND_DIFF_MODE=''
fi
filters="fps=$FPS,scale=$WIDTH:$HEIGHT:flags=lanczos"
palette="/tmp/palette.png"
ffmpeg -ss "$START_TIME" -t "$DURATION" -i "$1" -vf "$filters,palettegen=stats_mode=$STATS_MODE" -y $palette
ffmpeg -ss "$START_TIME" -t "$DURATION" -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=$DITHER$AND_DIFF_MODE" -y "$2"
@davec-gusto
Copy link

On lines 28-29, what happens if $pallette has space in it? Always quote variable expansion unless you know for sure you don't need to. In this case, you do know for sure since it's defined 1 line above, so nevermind.

Except don't! Quote your ENV=${ENV:-default} stuff.

@davec-gusto
Copy link

davec-gusto commented Nov 10, 2017

Oh yeah, re: the ARR stuff, check this out:

✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:43 $ IFS=$'\t\n'; ARR=($'element\t1' $'element\n'2); printf -- '---%q---\n' "${ARR[@]}"
---$'element\t1'---
---$'element\n2'---

%q rules!

e: Not appropriate for your use-case right now, but I really like it for displaying "File not found: $(printf '%q' "$FILE")" so people can actually see what the value passed was.

✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4] 
14:58 $ printf 'File not found: %s\n' "File with a space at the end "
File not found: File with a space at the end 
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4] 
14:58 $ printf 'File not found: %q\n' "File with a space at the end "
File not found: File\ with\ a\ space\ at\ the\ end\ 

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