aboutsummaryrefslogtreecommitdiffstats
path: root/ffmpeg/resize-and-transcode
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/resize-and-transcode')
-rwxr-xr-xffmpeg/resize-and-transcode126
1 files changed, 126 insertions, 0 deletions
diff --git a/ffmpeg/resize-and-transcode b/ffmpeg/resize-and-transcode
new file mode 100755
index 0000000..f3fe017
--- /dev/null
+++ b/ffmpeg/resize-and-transcode
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+set -u
+
+MAX_MIN_DIM=720
+
+if test $# -lt 2 || test $# -gt 3; then
+ printf 'usage: %s input-file output-file [max-min-dim]' "$0" >&2
+ exit 3
+fi
+
+err () {
+ colour="$1"
+ format="$2"
+ shift 2
+ printf '\x1b['"${colour}m${format}"'\x1b[m\n' "$@" >&2
+}
+
+alert () { err "1;31" "$@"; }
+header () { err "1;34" "$@"; }
+subheader () { err "34" "$@"; }
+red () { err "31" "$@"; }
+green () { err "32" "$@"; }
+yellow () { err "33" "$@"; }
+magenta () { err "35" "$@"; }
+cyan () { err "36" "$@"; }
+
+input="$1"
+output="$2"
+if test $# -ge 3; then
+ MAX_MIN_DIM="$3"
+fi
+
+if test ! -f "$input" || test ! -r "$input"; then
+ red 'Input file %s does not exist or is not a readable file, skipping'
+ exit 2
+fi
+if test -e "$output" || test -L "$output"; then
+ red 'Output file %s already exists, skipping'
+ exit 2
+fi
+
+header 'Transcoding %s' "$input"
+subheader 'Outputing to %s' "$output"
+
+dimensions=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 -- "$input")
+if test -z "$dimensions"; then
+ red 'An error occured, skipping'
+ exit 2
+fi
+
+oldwidth=$(printf '%s\n' "$dimensions" | cut -d 'x' -f 1)
+oldheight=$(printf '%s\n' "$dimensions" | cut -d 'x' -f 2)
+if test -z "$oldwidth" || test -z "$oldheight"; then
+ red 'An error occured, skipping'
+ exit 2
+fi
+
+scale=
+if test "$oldwidth" -lt "$oldheight"; then
+ if test "$oldwidth" -gt "${MAX_MIN_DIM}"; then
+ magenta 'The smaller dimension (width) was %i, downscaling to %i' "$oldwidth" "${MAX_MIN_DIM}"
+ newwidth="${MAX_MIN_DIM}"
+ newheight=-2
+ scale="-vf scale=$newwidth:$newheight"
+ else
+ cyan 'The smaller dimension (width) was %i, keeping as it does not exceed %i' "$oldwidth" "${MAX_MIN_DIM}"
+ fi
+else
+ if test "$oldheight" -gt "${MAX_MIN_DIM}"; then
+ magenta 'The smaller dimension (height) was %i, downscaling to %i' "$oldheight" "${MAX_MIN_DIM}"
+ newwidth=-2
+ newheight="${MAX_MIN_DIM}"
+ scale="-vf scale=$newwidth:$newheight"
+ else
+ cyan 'The smaller dimension (height) was %i, keeping as it does not exceed %i' "$oldheight" "${MAX_MIN_DIM}"
+ fi
+fi
+
+if test -z "$scale"; then
+ codec="$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 -- "$input")"
+ if test -z "$codec"; then
+ red 'An error occured, skipping'
+ exit 2
+ fi
+ if test "$codec" = hevc; then
+ cyan 'Already encoded with HEVC, keeping video codec'
+ codec="-c:v copy"
+ else
+ magenta 'Encoded with %s, transcoding to HEVC' "$codec"
+ codec="-c:v libx265"
+ fi
+else
+ codec="-c:v libx265"
+fi
+
+if test -z "$scale" && test "$codec" = '-c:v copy'; then
+ yellow 'The video is already small and encoded in HEVC, skipping'
+ exit 1
+fi
+
+ffmpeg -i "$input" $scale $codec -c:a copy -- "$output"
+ret=$?
+
+if test $ret = 0; then
+ oldsize=$(stat -c '%s' -- "$input")
+ newsize=$(stat -c '%s' -- "$output")
+ if test $newsize -ge $oldsize; then
+ p=$(( 100 * (newsize - oldsize) / oldsize ))
+ yellow 'The transcoded video was larger than the original (would increase by %i%%), skipping' $p
+ if ! rm -- "$output"; then
+ alert 'Failed to remove old file: %s' "$output"
+ fi
+ exit 1
+ else
+ p=$(( 100 * (oldsize - newsize) / oldsize ))
+ green 'The transcoded video was smaller than the original (reduced by %i%%), keeping' $p
+ exit 0
+ fi
+else
+ red 'An error occured, skipping'
+ if ! rm -- "$output"; then
+ alert 'Failed to remove old file: %s' "$output"
+ fi
+ exit 2
+fi