207 lines
4.0 KiB
Bash
207 lines
4.0 KiB
Bash
#!/bin/sh
|
|
|
|
#
|
|
# Section: Argument parsing
|
|
#
|
|
|
|
options="sim run full"
|
|
|
|
if [ $# -ne 2 ]; then
|
|
echo "reencode <$( echo "$options" | sed 's/ /|/g' )> <directory>"
|
|
exit 1
|
|
fi
|
|
|
|
mode=""
|
|
|
|
for opt in $options; do
|
|
if [ "$opt" = "$1" ]; then
|
|
mode="$opt"
|
|
fi
|
|
done
|
|
|
|
if [ "$mode" = "" ]; then
|
|
echo "'$1' is not a valid option"
|
|
exit 1
|
|
fi
|
|
|
|
path="$2"
|
|
cd "$path"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "Path does not exist: $path"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Searching for MKVs in $( pwd )"
|
|
|
|
#
|
|
# Section: Functions
|
|
#
|
|
|
|
do_ffprobe() {
|
|
ffprobe -v quiet -select_streams v:0 -show_entries $1 -of csv=p=0:nk=1 "$2"
|
|
}
|
|
|
|
get_codec() {
|
|
do_ffprobe stream=codec_name "$1"
|
|
}
|
|
|
|
get_bitrate() {
|
|
do_ffprobe format=bit_rate "$1"
|
|
}
|
|
|
|
get_resolution() {
|
|
do_ffprobe stream=height,width "$1"
|
|
}
|
|
|
|
file_size() {
|
|
du -sb "$1" | awk '{print $1}'
|
|
}
|
|
|
|
format_size() {
|
|
echo "$1" | numfmt --to=iec-i | awk '{print $1"B"}'
|
|
}
|
|
|
|
format_rate() {
|
|
echo "$1" | numfmt --to=si | awk '{print $1"bps"}'
|
|
}
|
|
|
|
encode_file() {
|
|
process=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $1}' )
|
|
filesize=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $2}' )
|
|
bitrate=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $3}' )
|
|
codec=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $4}' )
|
|
infile=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $5}' | sed "s/^'\|'\$//g" )
|
|
outfile=$( echo $1 | awk -v FPAT="([^' ]+)|'([^']+)'" '{print $6}' | sed "s/^'\|'\$//g" )
|
|
|
|
if [ "$process" = "Ignore" ]; then
|
|
return 1
|
|
fi
|
|
|
|
tmpfile="$infile.bak"
|
|
|
|
ffmpeg -nostdin -hide_banner -i "$infile" -c:v hevc_nvenc -c:a copy -c:s copy -map 0 -vtag hvc1 output.mkv
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "FFMPEG re-encode failed: $infile"
|
|
return 1
|
|
fi
|
|
|
|
mv "$infile" "$tmpfile"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to make backup file: $infile"
|
|
rm output.mkv
|
|
return 2
|
|
fi
|
|
|
|
mv output.mkv "$outfile"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed final move to: $outfile"
|
|
mv -f "$tmpfile" "$infile"
|
|
rm output.mkv
|
|
return 2
|
|
fi
|
|
|
|
echo "Output file: $outfile"
|
|
|
|
rm "$tmpfile"
|
|
oldsize=$( format_size $filesize )
|
|
oldbitr=$( format_rate $bitrate )
|
|
newsize=$( format_size $( file_size "$outfile" ) )
|
|
newbitr=$( format_rate $( get_bitrate "$outfile" ) )
|
|
echo "Converted $infile:" >> summary.txt
|
|
echo "\t$oldsize ($oldbitr) => $newsize ($newbitr)\n" >> summary.txt
|
|
return 0
|
|
}
|
|
|
|
get_file_info() {
|
|
# Args:
|
|
# $1 - video file name
|
|
#
|
|
# Returns a single line:
|
|
# filesize bitrate codec
|
|
echo "$( file_size "$1" ) $( get_bitrate "$1" ) $( get_codec "$1" )"
|
|
}
|
|
|
|
select_file() {
|
|
# Arg:
|
|
# $1 - filename
|
|
# $2 - filesize
|
|
# $3 - bitrate
|
|
# $4 - codec
|
|
#
|
|
# Note: args line up with return values from get_file_info
|
|
#
|
|
# Echo "Ignore" or "Process" with an optional reason
|
|
file=$1
|
|
size=$2
|
|
bitrate=$3
|
|
codec=$4
|
|
|
|
#if [ "$codec" = "hevc" ]; then
|
|
# echo "Ignore Already HEVC"
|
|
# return
|
|
#fi
|
|
|
|
if [ $bitrate -lt 4000000 ]; then
|
|
echo "Ignore bitrate too low"
|
|
else
|
|
echo "Process"
|
|
fi
|
|
}
|
|
|
|
simulate_file() {
|
|
# Arg:
|
|
# $1 - video file name
|
|
#
|
|
# Prints out a line to simulate.txt formatted like so:
|
|
# process filesize bitrate codec infile outfile
|
|
fileinfo=$( get_file_info "$1" )
|
|
selected=$( select_file "$1" $fileinfo )
|
|
outputfile="${1%.*}.mkv"
|
|
|
|
reason=${selected#* }
|
|
selected=$( echo "$selected" | awk '{print $1}' )
|
|
|
|
if [ "$selected" = "Ignore" ]; then
|
|
echo "$selected $fileinfo '$1' '$reason'" >> simulation.txt
|
|
echo "Ignored $1"
|
|
echo "\t => $reason"
|
|
else
|
|
echo "$selected $fileinfo '$1' '$outputfile' '$reason'" >> simulation.txt
|
|
echo "Selected $1"
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Section: Main code - do mode-specific stuff
|
|
#
|
|
|
|
if [ "$mode" != "run" ]; then
|
|
# if mode is not run (sim or full) then we're doing a simulation
|
|
rm -f simulation.txt
|
|
|
|
find -type f \( -name "*.mkv" -o -name "*.mp4" \) | while read file; do
|
|
simulate_file "$file"
|
|
done
|
|
fi
|
|
|
|
if [ "$mode" != "sim" ]; then
|
|
# if mode is not sim (run or full) then we're actually executing re-encodings
|
|
rm -f output.mkv
|
|
|
|
if [ ! -f "simulation.txt" ]; then
|
|
echo "No simulation file found. Cannot proceed."
|
|
exit 1
|
|
fi
|
|
|
|
cat simulation.txt | while read line; do
|
|
encode_file "$line"
|
|
if [ $? -eq 2 ]; then
|
|
exit 2
|
|
fi
|
|
done
|
|
fi
|