75 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env bash
 | 
						|
 | 
						|
# Uses ffmpeg to convert a video file to a gif file. Optimizes the final result
 | 
						|
# with gifsicle.
 | 
						|
#
 | 
						|
# Requires: ffmpeg
 | 
						|
# Optional: gifsicle
 | 
						|
#
 | 
						|
# Example:
 | 
						|
#   vid2gif some-vid.mp4 output.gif
 | 
						|
#   vid2gif -f 10 -s 00:00:10 -t 00:00:05 some-vid.mp4 output.gif
 | 
						|
 | 
						|
set -e
 | 
						|
PALETTE="/tmp/palette.png"
 | 
						|
 | 
						|
usage() {
 | 
						|
    cat <<EOL
 | 
						|
Usage: $0 [-fsSth] SOURCE_FILE [destfile]
 | 
						|
 | 
						|
    -f [FPS]       set frames per second
 | 
						|
    -s [hh:mm:ss]  set starting time (like -ss in ffmpeg)
 | 
						|
    -S [W:H]       set width/height (either can be -1 for auto)
 | 
						|
    -t [hh:mm:ss]  set the duration to capture (like -t in ffmpeg)
 | 
						|
    -h             this help
 | 
						|
EOL
 | 
						|
}
 | 
						|
 | 
						|
cleanup() { rm -f "$PALETTE"; }
 | 
						|
trap cleanup EXIT
 | 
						|
 | 
						|
#
 | 
						|
fps=30
 | 
						|
while getopts hf:s:t:S: opt; do
 | 
						|
    case $opt in
 | 
						|
        f) fps="$OPTARG" ;;
 | 
						|
        s) start="-ss $OPTARG" ;;
 | 
						|
        S) scale=",scale=$OPTARG:flags=lanczos" ;;
 | 
						|
        t) duration="-t $OPTARG" ;;
 | 
						|
        h) usage
 | 
						|
            exit
 | 
						|
            ;;
 | 
						|
        :) >&2 echo "$OPTARG requires an argument"
 | 
						|
            usage
 | 
						|
            exit 1
 | 
						|
            ;;
 | 
						|
        *) >&2 echo "Not a valid arg: $opt"
 | 
						|
            usage
 | 
						|
            exit 1
 | 
						|
            ;;
 | 
						|
    esac
 | 
						|
done
 | 
						|
shift $((OPTIND-1))
 | 
						|
 | 
						|
#
 | 
						|
if (($# == 0)); then
 | 
						|
    >&2 echo "No movie file specified"
 | 
						|
    exit
 | 
						|
elif [[ ! -f $1 ]]; then
 | 
						|
    >&2 echo "$1 does not exist"
 | 
						|
    exit
 | 
						|
fi
 | 
						|
 | 
						|
src="$1"
 | 
						|
dest="${2:-${src%.*}.gif}"
 | 
						|
flags="fps=${fps}$scale"
 | 
						|
 | 
						|
# stats_mode=full favors motion, causing the resulting palette to better
 | 
						|
# accomodate fades and transitions.
 | 
						|
ffmpeg -v warning $start $duration -i "$src" -vf "$flags,palettegen=stats_mode=full" -y "$PALETTE"
 | 
						|
ffmpeg -v warning $start $duration -i "$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest"
 | 
						|
 | 
						|
if command -v gifsicle >/dev/null; then
 | 
						|
    gifsicle -O3 "$dest" -o "$dest"
 | 
						|
fi
 |