Create ffencoder.sh
First version
This commit is contained in:
parent
8dd6a85f8b
commit
19c97a0fa5
273
ffencoder.sh
Normal file
273
ffencoder.sh
Normal file
@ -0,0 +1,273 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script for mass video encoding with ffmpeg
|
||||
|
||||
DEF='\e[0m'; RED='\e[31m'; GRN='\e[32m'; WHT='\e[37m'; BLD='\e[1m';
|
||||
|
||||
ScriptName=$(echo "$0" | awk -F '/' '{print $NF;}')
|
||||
ScriptDir=$(dirname $(readlink -e "$0"))
|
||||
|
||||
ExtRegex='.*\(mkv\|mp4\|wmv\|avi\)'
|
||||
RateAbbr="ntsc|pal|qntsc|qpal|sntsc|spal|film|ntsc-film"
|
||||
CopyACodec="FLAC|vorbis"
|
||||
|
||||
FFmpeg=$(which 'ffmpeg')
|
||||
Wrapper=$(which 'x264-10bit')
|
||||
|
||||
Priority=""
|
||||
Nice=""
|
||||
Jobs=""
|
||||
WriteLog=""
|
||||
LogDir="Logs"
|
||||
Log="/dev/null"
|
||||
|
||||
Resolution=""
|
||||
OutputDir=""
|
||||
InputDir=""
|
||||
BitDepth=""
|
||||
Bitrate=""
|
||||
Audio=""
|
||||
VCodec=""
|
||||
Format=""
|
||||
Fps=""
|
||||
|
||||
view_help ()
|
||||
{
|
||||
echo "Usage: ./$ScriptName [KEY]... [ARG]..."
|
||||
echo "This is script for mass video encoding to libx264/mkv with custom bitdepth, bitrate, resolution and fps."
|
||||
echo "-i, --input set the input directory (required)"
|
||||
echo "-o, --output set output directory (required)"
|
||||
echo "-d, --depth set bit depth (8 or 10)"
|
||||
echo "-r, --resolution set resolution (<Width>x<Height>)"
|
||||
echo "-f, --fps set fps (\"http://ffmpeg.org/ffmpeg-all.html#Video-rate\")"
|
||||
echo "-b, --bitrate set bitrate (integer value with \"k\" or \"m\" postfix)"
|
||||
echo "-p, --priority set priority (integer value from -19 to 20. Transferred to \"nice -n\")"
|
||||
echo "-l, --log creates a directory with logs in output directory"
|
||||
echo "-h, --help shows this page and exit"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_args ()
|
||||
{
|
||||
local Errors=""
|
||||
|
||||
# InputDir
|
||||
if [[ -z "$InputDir" ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} InputDir not set."; Errors="True"
|
||||
elif [[ -d "$InputDir" ]]; then
|
||||
InputDir=$(readlink -e "$InputDir")
|
||||
if [[ $(find "$InputDir" -maxdepth 1 -type f -regex "$ExtRegex" | wc -l) == '0' ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} $InputDir does not contain any video files."; Errors="True"
|
||||
fi
|
||||
else
|
||||
echo -e "${BLD}${RED}Error:${DEF} $Input not a directory."; Errors="True"
|
||||
fi
|
||||
|
||||
# OutputDir
|
||||
if [[ -z "$OutputDir" ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} OutputDir not set."; Errors="True"
|
||||
elif [[ -d "$OutputDir" ]]; then
|
||||
OutputDir=$(readlink -e "$OutputDir")
|
||||
elif ! mkdir -p "$OutputDir"; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Can't create ${OutputDir}!"; Errors="True"
|
||||
else
|
||||
OutputDir=$(readlink -e "$OutputDir")
|
||||
fi
|
||||
|
||||
# BitDepth
|
||||
if [[ (! -z "$BitDepth") && ("$BitDepth" != '8' && "$BitDepth" != '10') ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} BitDepth must be '8' or '10', not \"${BitDepth}\"."; Errors="True"
|
||||
fi
|
||||
|
||||
# Resolution
|
||||
if ! echo "$Resolution" | grep -Po '^[0-9]+x[0-9]+$' &> /dev/null && [[ ! -z $Resolution ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Unknown resolution format: \"$Resolution\".\n\tMust be: <widht>x<height>"; Errors="True"
|
||||
fi
|
||||
|
||||
# Fps
|
||||
if ! echo "$Fps" | grep -Po "^([0-9]+(/[0-9]+)?|${RateAbbr})$" &> /dev/null && [[ ! -z $Fps ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Unknown fps format: \"$Fps\".\n\tIt has to be a string in the format frame_rate_num/frame_rate_den, an integer number, a float number or a valid video frame rate abbreviation"; Errors="True"
|
||||
fi
|
||||
|
||||
# Bitrate
|
||||
if ! echo "$Bitrate" | grep -Po '^[0-9]+(k|m)?$' &> /dev/null && [[ ! -z $Bitrate ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Unknown bitrate format: \"$Bitrate\".\n\tMust be integer value (with 'k' or 'm' postfix)."; Errors="True"
|
||||
fi
|
||||
|
||||
# Priority
|
||||
if [[ ! -z "$Priority" ]]; then
|
||||
if ! echo "$Priority" | grep -P '[-0-9]{1,3}' &> /dev/null; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Unknown priority: \"$Priority\".\n\tMust be integer value from -19 to 20."; Errors="True"
|
||||
elif [[ "$Priority" -lt "-19" || "$Priority" -gt "20" ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} Priority must be from -19 to 20."; Errors="True"
|
||||
else
|
||||
Nice="nice -n $Priority"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Jobs
|
||||
#if [[ ! -z "$Jobs" ]]; then
|
||||
# if ! echo "$Jobs" | grep -P '^[0-9]+$' &> /dev/null; then
|
||||
# echo -e "${BLD}${RED}Error:${DEF} Unknown jobs count: \"$Jobs\".\n\tMust be integer value from 1 to 99."; Errors="True"
|
||||
# elif [[ "$Jobs" -lt "1" ]]; then
|
||||
# echo -e "${BLD}${RED}Error:${DEF} Jobs count must be integer value from 1 to 99."; Errors="True"
|
||||
# else
|
||||
# Jobs="-threads $Jobs"
|
||||
# fi
|
||||
#fi
|
||||
|
||||
# VCodec/Format
|
||||
VCodec="libx264"
|
||||
Format="matroska"
|
||||
|
||||
if [[ ! -z $Errors ]]; then exit 3; fi
|
||||
}
|
||||
|
||||
auto_exec ()
|
||||
{
|
||||
local Info="$1"
|
||||
local Depth="8"
|
||||
local Exec="$FFmpeg"
|
||||
|
||||
if [[ -z "$BitDepth" && ! -z $(echo "$Info" | grep -Po 'High 10') ]]; then
|
||||
Depth='10'
|
||||
else
|
||||
Depth="$BitDepth"
|
||||
fi
|
||||
|
||||
if [[ "$Depth" == "10" ]]; then
|
||||
Exec="$Wrapper $Exec"
|
||||
fi
|
||||
echo "$Exec"
|
||||
}
|
||||
|
||||
auto_resolution ()
|
||||
{
|
||||
local Info="$1"
|
||||
|
||||
if [[ -z "$Resolution" ]]; then
|
||||
echo "-s "$(echo "$Info" | sed -r 's/.+ ([0-9]+x[0-9]+)[, ].+/\1/g')
|
||||
else
|
||||
echo "-s $Resolution"
|
||||
fi
|
||||
}
|
||||
|
||||
auto_fps ()
|
||||
{
|
||||
local Info="$1"
|
||||
|
||||
if [[ -z "$Fps" ]] && echo "$Info" | grep -P '[0-9\.] fps' &> /dev/null; then
|
||||
Fps=$(echo "$Info" | sed -r 's/.+ ([0-9\.]+) fps.+/\1/g')
|
||||
fi
|
||||
|
||||
if [[ ! -z "$Fps" ]]; then
|
||||
Fps="-r $Fps"
|
||||
fi
|
||||
|
||||
echo "$Fps"
|
||||
}
|
||||
|
||||
auto_bitrate ()
|
||||
{
|
||||
local Info="$1"
|
||||
|
||||
if [[ -z "$Bitrate" ]]; then
|
||||
echo "-b:v "$(echo "$Info" | sed -r 's/.+bitrate: ([0-9]+) ([kmg]?).+/\1\2/g')
|
||||
else
|
||||
echo "-b:v $Bitrate"
|
||||
fi
|
||||
}
|
||||
|
||||
auto_audio ()
|
||||
{
|
||||
local Info="$1"
|
||||
local OnlyCopy=$(echo "$Info" | grep -Po '($CopyACodec)')
|
||||
local ABitrate=$(echo "$Info" | sed -r 's/.+ ([0-9]+) kb\/s.*/\1/g')
|
||||
|
||||
if [[ $ABitrate -lt 128 ]]; then
|
||||
ABitrate="128"
|
||||
fi
|
||||
|
||||
if [[ -z "$OnlyCopy" ]]; then
|
||||
echo "-acodec libvorbis -b:a ${ABitrate}k"
|
||||
else
|
||||
echo "-acodec copy"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check FFmpeg and Wrapper
|
||||
if [[ -z "$FFmpeg" ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} ffmpeg not found."; exit 1
|
||||
fi
|
||||
if [[ -z "$Wrapper" ]]; then
|
||||
echo -e "${BLD}${RED}Error:${DEF} 10bit wrapper not found."; exit 1
|
||||
fi
|
||||
|
||||
# Processing arguments
|
||||
while [[ $# -gt 0 ]]; do case $1 in
|
||||
|
||||
-i|--input ) InputDir="$2" ; shift; shift;;
|
||||
-o|--output ) OutputDir="$2" ; shift; shift;;
|
||||
-d|--depth ) BitDepth="$2" ; shift; shift;;
|
||||
-r|--resolution ) Resolution="$2" ; shift; shift;;
|
||||
-f|--fps ) Fps="$2" ; shift; shift;;
|
||||
-b|--bitrate ) Bitrate="$2" ; shift; shift;;
|
||||
-p|--priority ) Priority="$2" ; shift; shift;;
|
||||
-l|--log ) WriteLog="True" ; shift;;
|
||||
-h|--help ) view_help ; shift;;
|
||||
# -j|--jobs ) Jobs="$2" ; shift; shift;;
|
||||
# -a|--acodec ) ACodec="$2" ; shift; shift;;
|
||||
# -v|--vcodec ) VCodec="$2" ; shift; shift;;
|
||||
|
||||
*) echo "Unknown argument: \"$1\""; exit 2;;
|
||||
|
||||
esac; done; check_args
|
||||
|
||||
LogDir="$OutputDir/$LogDir"
|
||||
if [[ ! -z $WriteLog && ! -d "$LogDir" ]]; then
|
||||
mkdir "$LogDir"
|
||||
fi
|
||||
|
||||
# Main
|
||||
Index='1'
|
||||
Count=$(find "$InputDir" -maxdepth 1 -type f -regex "$ExtRegex" | wc -l)
|
||||
|
||||
while IFS= read -r -d $'\n' InputFile <&3
|
||||
do
|
||||
InputFileName=$(echo "$InputFile" | awk -F '/' '{print $NF;}')
|
||||
InputFileNameCrop=$(echo "$InputFileName" | sed -r 's/\.[a-Z0-9]+$//g')
|
||||
|
||||
printf "${BLD}[----] %#3d/%-3d${DEF} %s" "$Index" "$Count" "$InputFileNameCrop"
|
||||
|
||||
OutputFile="$OutputDir/$InputFileNameCrop.mkv"
|
||||
|
||||
if [[ ! -z $WriteLog ]]; then
|
||||
Log="$LogDir/$InputFileNameCrop.log"
|
||||
fi
|
||||
|
||||
InfoP1=$("$FFmpeg" -i "$InputFile" 2>&1 | grep 'Video:')
|
||||
InfoP2=$("$FFmpeg" -i "$InputFile" 2>&1 | grep 'bitrate')
|
||||
InfoP3=$("$FFmpeg" -i "$InputFile" 2>&1 | grep -P 'Stream #0:1.+Audio:')
|
||||
|
||||
Exec=$(auto_exec "$InfoP1")
|
||||
|
||||
# Uncomment for fast debug:
|
||||
# VCodec="copy"
|
||||
|
||||
if $Nice $Jobs $Exec \
|
||||
-i "$InputFile" \
|
||||
-f "$Format" \
|
||||
-vcodec "$VCodec" \
|
||||
$(auto_audio "$InfoP3") \
|
||||
$(auto_resolution "$InfoP1") \
|
||||
$(auto_bitrate "$InfoP2") \
|
||||
$(auto_fps "$InfoP3") \
|
||||
-y "$OutputFile" &> "$Log"; then
|
||||
printf "\r${BLD}[${GRN}DONE${DEF}${BLD}]\n"
|
||||
else
|
||||
printf "\r${BLD}[${RED}FAIL${DEF}${BLD}]\n"
|
||||
#break
|
||||
fi
|
||||
((Index++))
|
||||
done 3< <(find "$InputDir" -maxdepth 1 -type f -regex "$ExtRegex")
|
Loading…
x
Reference in New Issue
Block a user