From d953121bbba1229330e7d7dad725e4c6dcacf333 Mon Sep 17 00:00:00 2001
From: katherine <shmibs@shmibbles.me>
Date: Sun, 19 Feb 2017 05:08:57 -0700
Subject: add gifsicle support to make-gif

also allow selecting specific subtitle tracks
---
 .config/init/funcs/make-gif | 168 ++++++++++++++++++++++++++++++--------------
 1 file changed, 117 insertions(+), 51 deletions(-)

(limited to '.config/init')

diff --git a/.config/init/funcs/make-gif b/.config/init/funcs/make-gif
index 7b3145c..3221e97 100755
--- a/.config/init/funcs/make-gif
+++ b/.config/init/funcs/make-gif
@@ -2,18 +2,21 @@
 # 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 "print this help   -h"
+	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
 }
 
@@ -22,40 +25,86 @@ 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][0-9]*$'
+local intpat='^[0-9]+$'
 
+# tmp var used to old '-t' if length is used
 local t=""
 
-while getopts s:t:f:w:bh 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 ;;
-		h) usage ;;
-		[?]) usage ;;
-	esac
-done
+# 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"
@@ -66,32 +115,49 @@ shift $OPTIND-1
 
 [[ ! -f "$1" ]] && usage "input file not found"
 
+local paltmp="make-gif"
+while [[ -f "${paltmp}-palette.png" ]] || [[ -f "${paltmp}-in" ]]; do
+	paltmp="${paltmp}-1"
+done
 
-rm -f make-gif-palette.png
-rm -f make-gif-in
+ln -s "$1" "${paltmp}-in"
 
-ln -s "$1" make-gif-in
+local fferr
 
 if [[ $subs ]]; then
 	echo "pass 1..."
 	ffmpeg -loglevel 16 -y -ss $start $t $length -i "$1" -copyts \
-		-vf "subtitles=make-gif-in,fps=$fps,scale=$width:-1:flags=lanczos,palettegen" \
-		make-gif-palette.png
-	[[ $? -eq 0 ]] && echo "pass 2..." && ffmpeg -loglevel 24 \
-		-ss $start $t $length -i "$1" -i make-gif-palette.png \
+		-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=make-gif-in,fps=$fps,scale=$width:-1:flags=lanczos[x];[x][1:v]paletteuse" \
-		out.gif
+		"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" \
-		make-gif-palette.png
-	[[ $? -eq 0 ]] && echo "pass 2..." && ffmpeg -loglevel 24 \
-		-ss $start $t $length -i "$1" -i make-gif-palette.png -filter_complex \
+		${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" \
-		out.gif
+		"$2"
 fi
 
-rm -f make-gif-palette.png
-rm -f make-gif-in
+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
-- 
cgit v1.2.3