From 8a8cf03861ef3ebc3911cf2fb2cf6c039861334d Mon Sep 17 00:00:00 2001 From: Ray Lyon Date: Wed, 25 Nov 2020 15:04:51 -0500 Subject: [PATCH 1/3] error function and for loop fix --- ffmpeg/ffmpeg-batch-encode.sh | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/ffmpeg/ffmpeg-batch-encode.sh b/ffmpeg/ffmpeg-batch-encode.sh index 1ef6776..fcd4e5b 100755 --- a/ffmpeg/ffmpeg-batch-encode.sh +++ b/ffmpeg/ffmpeg-batch-encode.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Help function +### Help function ### Help() { @@ -14,14 +14,36 @@ Help() echo "Learn more about FFmpeg's quality settings: https://trac.ffmpeg.org/wiki/Encode/H.264" } +### Error function ### + +PROGNAME="$(basename $0)" + +error_exit() +{ + +# ---------------------------------------------------------------- +# Function for exit due to fatal program error +# Accepts 1 argument: +# string containing descriptive error message +# ---------------------------------------------------------------- + + + echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2 + exit 1 +} + +# Example call of the error_exit function. Note the inclusion +# of the LINENO environment variable. It contains the current +# line number. + ### Script ### DIRECTORY=$1 -QUALITY_HD=22 -QUALITY_4K=24 +QUALITY_HD=23 +QUALITY_4K=22 -# Basic error handling -if [ -z "$1" ]; then +# Check if source directory is provided +if [ -z "$1" ] || [ ! -d "$1" ]; then printf "ERROR: You must specify a source directory\n\n" 1>&2 Help exit 1 @@ -32,17 +54,16 @@ if [ ! -d "$DIRECTORY/output" ]; then mkdir "$DIRECTORY/output" fi + # Encode each file in the directory with different CRF setting based on resolution -for FILE in "$DIRECTORY"/*; do +for FILE in "$DIRECTORY"/*.*; do RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$FILE") FILENAME=$(basename "$FILE") if [[ $RES -gt 1920 ]]; then ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$DIRECTORY"/output/"$FILENAME" elif [[ $RES -le 1920 ]]; then ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$DIRECTORY"/output/"$FILENAME" - else - echo "$FILENAME is not a valid filetype" fi -done +done || error_exit "$LINENO: An error has occurred." exit 0 \ No newline at end of file From 2217c1d7736da8686657c24efaec68a8e28a64e7 Mon Sep 17 00:00:00 2001 From: Ray Lyon Date: Wed, 25 Nov 2020 16:31:14 -0500 Subject: [PATCH 2/3] added file input option, broke into functions --- ffmpeg/ffmpeg-batch-encode.sh | 95 ++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/ffmpeg/ffmpeg-batch-encode.sh b/ffmpeg/ffmpeg-batch-encode.sh index fcd4e5b..6ccf105 100755 --- a/ffmpeg/ffmpeg-batch-encode.sh +++ b/ffmpeg/ffmpeg-batch-encode.sh @@ -1,10 +1,20 @@ #!/bin/bash -### Help function ### +### VARIABLES ### + +PROGNAME="$(basename "$0")" +INPUT_SOURCE=$1 +QUALITY_HD=23 +QUALITY_4K=22 +FILEDIR=$(dirname "$INPUT_SOURCE") + + +### FUNCTIONS### + +### Function: Help Help() { - # Display Help echo "This script uses sensible ffmpeg options to batch encode MKV files in a directory to compressed H264 MKVs." echo "You can change the CRF parameters in the script, defaults are 24 for HD and 22 for 4K." echo @@ -14,56 +24,69 @@ Help() echo "Learn more about FFmpeg's quality settings: https://trac.ffmpeg.org/wiki/Encode/H.264" } -### Error function ### - -PROGNAME="$(basename $0)" +### Funtion: Error error_exit() { - -# ---------------------------------------------------------------- -# Function for exit due to fatal program error -# Accepts 1 argument: -# string containing descriptive error message -# ---------------------------------------------------------------- - - echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2 exit 1 } -# Example call of the error_exit function. Note the inclusion -# of the LINENO environment variable. It contains the current -# line number. -### Script ### +# Function: encode each file in the directory with different CRF setting based on resolution -DIRECTORY=$1 -QUALITY_HD=23 -QUALITY_4K=22 +folder_encode () { + if [ ! -d "$INPUT_SOURCE/output" ]; then + mkdir "$INPUT_SOURCE/output" + fi -# Check if source directory is provided -if [ -z "$1" ] || [ ! -d "$1" ]; then + for FILE in "$INPUT_SOURCE"/*.*; do + RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$FILE") + FILENAME=$(basename "$FILE") + if [[ $RES -gt 1920 ]]; then + echo "File is 4K or higher, encoding using CRF $QUALITY_4K" + ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" + elif [[ $RES -le 1920 ]]; then + echo "File is HD or lower, encoding using CRF $QUALITY_HD" + ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" + fi + done +} + +# Function: encode single file with different CRF setting based on resolution + +file_encode () { + if [ ! -d "$FILEDIR/output" ]; then + mkdir "$FILEDIR/output" + fi + + FILENAME=$(basename "$INPUT_SOURCE") + RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$INPUT_SOURCE") + if [[ $RES -gt 1920 ]]; then + ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$FILEDIR"/output/"$FILENAME" + elif [[ $RES -le 1920 ]]; then + ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$FILEDIR"/output/"$FILENAME" + fi +} + +### SCRIPT ### + +# Check if source input is provided +if [ -z "$1" ]; then printf "ERROR: You must specify a source directory\n\n" 1>&2 Help exit 1 fi -# Create output folder within source directory -if [ ! -d "$DIRECTORY/output" ]; then - mkdir "$DIRECTORY/output" +# Run function based on file or folder input +if [ -f "$1" ]; then + file_encode || error_exit "$LINENO: An error has occurred." 1>&2 +elif [ -d "$1" ]; then + folder_encode || error_exit "$LINENO: An error has occurred." 1>&2 +else + error_exit "$LINENO: Not a valid source" 1>&2 fi +exit 0 -# Encode each file in the directory with different CRF setting based on resolution -for FILE in "$DIRECTORY"/*.*; do - RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$FILE") - FILENAME=$(basename "$FILE") - if [[ $RES -gt 1920 ]]; then - ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$DIRECTORY"/output/"$FILENAME" - elif [[ $RES -le 1920 ]]; then - ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$DIRECTORY"/output/"$FILENAME" - fi -done || error_exit "$LINENO: An error has occurred." -exit 0 \ No newline at end of file From d914434618bf654944ac033eec30dbcd3f137f7f Mon Sep 17 00:00:00 2001 From: Ray Lyon Date: Wed, 25 Nov 2020 17:03:16 -0500 Subject: [PATCH 3/3] More error handling, input file check --- ffmpeg/ffmpeg-batch-encode.sh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/ffmpeg/ffmpeg-batch-encode.sh b/ffmpeg/ffmpeg-batch-encode.sh index 6ccf105..38cab81 100755 --- a/ffmpeg/ffmpeg-batch-encode.sh +++ b/ffmpeg/ffmpeg-batch-encode.sh @@ -45,10 +45,13 @@ folder_encode () { FILENAME=$(basename "$FILE") if [[ $RES -gt 1920 ]]; then echo "File is 4K or higher, encoding using CRF $QUALITY_4K" - ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" - elif [[ $RES -le 1920 ]]; then + ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" || echo "ERROR Line $LINENO: File not encoded, unknown error occurred." 1>&2 + elif [[ $RES -le 1920 ]] && [[ -n $RES ]]; then echo "File is HD or lower, encoding using CRF $QUALITY_HD" - ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" + ffmpeg -i "$FILE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$INPUT_SOURCE"/output/"$FILENAME" || echo "ERROR Line $LINENO: File not encoded, unknown error occurred." 1>&2 + else + echo "ERROR Line $LINENO: Source file $FILE is not a valid video file" 1>&2 + echo "Skipping..." fi done } @@ -63,9 +66,13 @@ file_encode () { FILENAME=$(basename "$INPUT_SOURCE") RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$INPUT_SOURCE") if [[ $RES -gt 1920 ]]; then - ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$FILEDIR"/output/"$FILENAME" - elif [[ $RES -le 1920 ]]; then - ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$FILEDIR"/output/"$FILENAME" + echo "File is 4K or higher, encoding using CRF $QUALITY_4K" + ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_4K" -c:a copy "$FILEDIR"/output/"$FILENAME" || echo "ERROR Line $LINENO: File not encoded, unknown error occurred." 1>&2 + elif [[ $RES -le 1920 ]] && [[ -n $RES ]]; then + echo "File is HD or lower, encoding using CRF $QUALITY_HD" + ffmpeg -i "$INPUT_SOURCE" -c:v libx264 -preset slow -tune film -crf "$QUALITY_HD" -c:a copy "$FILEDIR"/output/"$FILENAME" || echo "ERROR Line $LINENO: File not encoded, unknown error occurred." 1>&2 + else + echo "ERROR Line $LINENO: Source file $INPUT_SOURCE is not a valid video file" 1>&2 fi } @@ -87,6 +94,8 @@ else error_exit "$LINENO: Not a valid source" 1>&2 fi +echo "File(s) encoded successfully!" + exit 0