-
Notifications
You must be signed in to change notification settings - Fork 47
/
gifify.sh
executable file
·94 lines (77 loc) · 2.34 KB
/
gifify.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/bash
set -euo pipefail
function printHelpAndExit {
echo 'Usage:'
echo ' gifify [options] filename'
echo ''
echo 'Options: (all optional)'
echo ' c CROP: The x and y crops, from the top left of the image, i.e. 640:480'
echo ' o OUTPUT: The basename of the file to be output (default "output")'
echo ' l LOOP: The number of times to loop the animnation. 0 (default)'
echo ' for infinity.'
echo ' r FPS@SPEED: With 60@1.5, output at 60FPS at a speed of 1.5x the'
echo ' source material. NOTE: It is best to keep FPSxSPEED'
echo ' below approximately 60.'
echo ' p SCALE: Rescale the output, e.g. 320:240'
echo ' x: Remove the original file and resulting .gif once the script is complete'
echo ''
echo 'Example:'
echo ' gifify -c 240:80 -o my-gif my-movie.mov'
exit $1
}
crop=
output=
loop=0
fpsspeed='10@1'
scale=
OPTERR=0
while getopts 'c:o:l:p:r:s:' opt; do
case $opt in
c) crop=$OPTARG;;
h) printHelpAndExit 0;;
o) output=$OPTARG;;
l) loop=$OPTARG;;
r) fpsspeed=$OPTARG;;
p) scale=$OPTARG;;
*) printHelpAndExit 1;;
esac
done
shift $(( OPTIND - 1 ))
filename=$1
if [ -z ${output} ]; then
output=$filename
fi
if [ -z "$filename" ]; then printHelpAndExit 1; fi
if [ $crop ]; then
crop="crop=${crop}:0:0"
else
crop=
fi
if [ $scale ]; then
scale="scale=${scale}"
else
scale=
fi
if [ $scale ] || [ $crop ]; then
filter="-vf $scale$crop"
else
filter=
fi
# -delay uses time per tick (a tick defaults to 1/100 of a second), so 60fps ==
# -delay 1.666666 which is rounded to 2 because convert apparently stores this
# as an integer.
#
# To animate faster than 60fps, you must drop frames, meaning you must specify
# a lower -r. This is due to the GIF format as well as GIF renderers that cap
# frame delays < 3 to 3 or sometimes 10. Source:
# http://humpy77.deviantart.com/journal/Frame-Delay-Times-for-Animated-GIFs-214150546
fps=$(echo $fpsspeed | cut -d'@' -f1)
speed=$(echo $fpsspeed | cut -d'@' -f2)
if [ ! -z "$speed" ]; then
speed=1
fi
delay=$(bc -l <<< "100/$fps/$speed")
temp=$(mktemp /tmp/tempfile.XXXXXXXXX)
ffmpeg -loglevel panic -i "$filename" $filter -r $fps -f image2pipe -vcodec ppm - >> $temp
cat $temp | convert +dither -layers Optimize -loop $loop -delay $delay - "${output}.gif"
echo "${output}.gif"