blob: 3221e979572aac5b37d300473ded88794477b340 (
plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#!/usr/bin/env zsh
# export a clip from a video as a gif
local callstr="$0"
local hasgsic=$(whence gifsicle)
usage() {
[[ "$1" != "" ]] && echo -e "\e[1;31merror:\e[0m $1\n"
echo "Usage: $callstr [OPTIONS...] <infile> <outfile>"
echo ""
echo " description option default val"
echo " start time -s <time> 00:00:00"
echo " length in seconds -t <int> full length"
echo " gif fps -f <int> 10"
echo " gif pixel width -w <int> 480"
echo " use subtitles -b"
echo " use subtitle track -n <int> 0"
[[ $hasgsic ]] && echo "optimise with gifsicle -g"
echo " print this help -h"
exit 1
}
local start="00:00:00"
local length=""
local fps=10
local width=480
local subs=""
local strack=0
local gsic=""
local timepat='^(([0-9][0-9]:){1,2}[0-9][0-9]|[0-9]+)$'
local intpat='^[0-9]+$'
# tmp var used to old '-t' if length is used
local t=""
# really annoying, but no other good way to do this
if [[ $hasgsic ]]; then
while getopts s:t:f:w:bhn:g opt; do
case "$opt" in
s)
[[ ! $(echo $OPTARG | grep -oE "$timepat") ]] \
&& usage "malformed start timestamp"
start="$OPTARG"
;;
t)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "length must be an integer"
length=$OPTARG
t="-t"
;;
f)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "start time must be an integer"
fps=$OPTARG
;;
w)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "fps must be an integer"
width=$OPTARG
;;
b) subs=true ;;
n)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "sub track specifier must be an integer"
strack=$OPTARG
;;
g) gsic=true ;;
h) usage ;;
[?]) usage ;;
esac
done
else
while getopts s:t:f:w:bhn: opt; do
case "$opt" in
s)
[[ ! $(echo $OPTARG | grep -oE "$timepat") ]] \
&& usage "malformed start timestamp"
start="$OPTARG"
;;
t)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "length must be an integer"
length=$OPTARG
t="-t"
;;
f)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "start time must be an integer"
fps=$OPTARG
;;
w)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "fps must be an integer"
width=$OPTARG
;;
b) subs=true ;;
n)
[[ ! $(echo $OPTARG | grep -oE "$intpat") ]] \
&& usage "sub track specifier must be an integer"
strack=$OPTARG
;;
h) usage ;;
[?]) usage ;;
esac
done
fi
shift $OPTIND-1
[[ ${#@} -gt 2 ]] && usage "trailing arguments detected"
[[ ${#@} -lt 2 ]] && usage "no output file specified"
[[ "${2:e}" != "gif" ]] && usage "output file must have a .gif file extension"
[[ ! -f "$1" ]] && usage "input file not found"
local paltmp="make-gif"
while [[ -f "${paltmp}-palette.png" ]] || [[ -f "${paltmp}-in" ]]; do
paltmp="${paltmp}-1"
done
ln -s "$1" "${paltmp}-in"
local fferr
if [[ $subs ]]; then
echo "pass 1..."
ffmpeg -loglevel 16 -y -ss $start $t $length -i "$1" -copyts \
-vf "subtitles=${paltmp}-in:si=$strack,fps=$fps,scale=$width:-1:flags=lanczos,palettegen" \
${paltmp}-palette.png
[[ $? -ne 0 ]] && fferr=true
[[ ! $fferr ]] && echo "pass 2..." && ffmpeg -loglevel 24 \
-ss $start $t $length -i "$1" -i ${paltmp}-palette.png \
-copyts -filter_complex \
"subtitles=${paltmp}-in:si=$strack,fps=$fps,scale=$width:-1:flags=lanczos[x];[x][1:v]paletteuse" \
"$2"
else
echo "pass 1..."
ffmpeg -loglevel 16 -y -ss "$start" $t $length -i "$1" \
-vf "fps=$fps,scale=$width:-1:flags=lanczos,palettegen" \
${paltmp}-palette.png
[[ $? -ne 0 ]] && fferr=true
[[ ! $fferr ]] && echo "pass 2..." && ffmpeg -loglevel 24 \
-ss $start $t $length -i "$1" -i ${paltmp}-palette.png -filter_complex \
"fps=$fps,scale=$width:-1:flags=lanczos[x];[x][1:v]paletteuse" \
"$2"
fi
rm -f ${paltmp}-palette.png
rm -f ${paltmp}-in
if [[ -f "$2" ]] && [[ ! $fferr ]]; then
if [[ $gsic ]]; then
local gsictmp="$2.out"
while [[ -f "$gsictmp" ]]; do
gsictmp="$gsictmp.out"
done
echo "optimising..."
gifsicle -O3 -i "$2" -o "$gsictmp"
[[ $? -eq 0 ]] && rm -f "$2" && mv "$gsictmp" "$2"
fi
fi
|