scripts-bash/local/bin/convertMKV.sh

276 lines
10 KiB
Bash
Executable File

#!/bin/bash
###############################################################################
#
# Script to recursively search a directory and batch convert all files of a given
# file type into another file type via HandBrake conversion.
#
# To run in your environment set the variables:
# hbcli - Path to your HandBrakeCLI
#
# source_dir - Starting directory for recursive search
#
# input_file_type - Input file type to search for
#
# output_file_type - Output file type to convert into
#
#
# Change log:
# 2012-01-08: Initial release. Tested on Mac OS X Lion.
#
###############################################################################
#clear
logFile=~/$(basename ${0}).log
echo -e "\n"
echo -e "==> Préparation de l'environnement...\n"|tee $logFile
echo ""
if [ -f "$1" ]; then
echo -e "Le paramètre est un fichier : $1\n" |tee -a $logFile
type="file"
input_file=$1
shift
else
echo -e "Le paramètre n'est pas un fichier\n" |tee -a $logFile
fi
if [ -d "$1" ]; then
echo -e "Le paramètre est un dossier : $1\n" |tee -a $logFile
cd $1
shift
else
echo -e "Le paramètre n'est pas un dossier\n" |tee -a $logFile
fi
# Vérifie que deux paramètres ont été renseignés
param1=${1:-mkv}
param2=${2:-26}
echo -e "$(basename ${0}) $param1 $param2\n" |tee -a $logFile
date_en_cours=$(date +"%Y%m%dT%H%M%S")
source_dir=$(pwd)
input_file_type=${param1}
output_file_type="new${param2}.mkv"
declare -a mesFichiers
listFileName=~/rsbConvert_${date_en_cours}.sh
echo -e "Dossier en cours : " |tee -a $logFile
echo -e " $source_dir\n" |tee -a $logFile
# Construction d'un tableau des noms de fichiers
i=0
echo -e "==> Type de liste : \n" |tee -a $logFile
if [ "$type" = "file" ]; then
echo -e "$source_dir/$input_file\n"|tee -a $logFile
echo -e "$source_dir/$input_file"> ~/fichiersATraiter_${date_en_cours}_$$.lst
else
echo -e "find -L \"$source_dir\" -type f -iname \"*.$input_file_type\"\n" |tee -a $logFile
find -L "$source_dir" -type f -iname "*.$input_file_type" > ~/fichiersATraiter_${date_en_cours}_$$.lst
fi
echo -e "==> Traitement de la liste : \n" |tee -a $logFile
while read -e aLine
do
echo "[NFO] $aLine"|tee -a $logFile
if [ ${#aLine} -ge 2 ]; then
echo " a traiter."|tee -a $logFile
mesFichiers[$i]=$aLine
i=$(($i+1))
fi
done < ~/fichiersATraiter_${date_en_cours}_$$.lst
rm ~/fichiersATraiter_${date_en_cours}_$$.lst
echo -e "\n"|tee -a $logFile
echo -e "==> Traitement des vidéos en cours...\n"|tee -a $logFile
for in_file in "${mesFichiers[@]}"
do # Liste tous les éléments du tableau.
echo "Traitement de : $in_file"|tee -a $logFile
if [ ${#in_file} -ge 2 ]; then
echo -e "\n________________________________________________________________________________"|tee -a $logFile
echo -e "\n ==> Processing…"|tee -a $logFile
echo -e "\n [NFO] Input $in_file"|tee -a $logFile
# Replace the file type
out_file=$(echo "$in_file"|sed "s/\(.*\.\)$input_file_type/\1$output_file_type/g")
echo -e "\n [NFO] Output \"$out_file\"\n"|tee -a $logFile
if [ "$in_file" != "$out_file" ]; then
# ---------------- RESOLUTION DE SORTIE --------------
echo -e "==> RESOLUTION, calcul en cours ...\n"
# Obtenez la résolution de la vidéo d'entrée en utilisant FFmpeg
read width height < <(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "$in_file" | tr ',' ' ')
echo -e " RESOLUTION de la vidéo en entrée : \"${width} x ${height}\"\n"|tee -a $logFile
# Vérifiez si la résolution est inférieure ou égale à 1080p
if [[ "$width" -le 1920 && "$height" -le 1080 ]]; then
# Si la résolution est inférieure ou égale à 1080p, utilisez la résolution d'entrée pour la sortie
vf_option="scale=${width}:${height}"
else
# Si la résolution est supérieure à 1080p, utilisez une résolution de sortie de 1080p
# Obtenez la résolution de la vidéo d'entrée en utilisant FFmpeg
vf_option="scale='min(1920\,iw)':'-1'"
fi
echo -e " RESOLUTION de sortie \"${vf_option}\"\n"|tee -a $logFile
# -------------- DETECTION DES BADNES NOIRES ------------------
echo -e "==> DETECTION DES BANDES NOIRES, calcul en cours ...\n"
# Get cropSize en fonction de la résoltuion
# Calculer la valeur de cropSize en fonction de la résolution d'entrée
if (( $width > 1920 || $height > 1080 )); then
if (( $width > 1920 )); then
echo -e " calcule du scale car vidéo trop grande avec un width de ${width}.\n"|tee -a $logFile
scale=$(echo "scale=2;1920/$width*100" | bc)
else
scale=100
fi
cropSize="crop="$(echo "scale=0;$width*$scale/100" | bc)":"$(echo "scale=0;$height*$scale/100" | bc)":0:0"
else
cropSize=$(ffmpeg -i "$in_file" -ss 00:02:00 -vframes 1 -vf cropdetect -f null - 2>&1 | awk '/crop/ { print $NF }' | tail -1)
fi
# cropSize=$(ffmpeg -i "$in_file" -ss 00:02:00 -vframes 1 -vf cropdetect -f null - 2>&1 | awk '/crop/ { print $NF }' | tail -1)
echo -e " CROP ${cropSize} avec un scale de ${scale}\n"|tee -a $logFile
# -------------- ESPACE COLORMETRIQUE ------------------
echo -e "==> ESPACE COLORMETRIQUE, calcul en cours ...\n"
# Détection automatique de l'espace colorimétrique de la vidéo d'entrée en utilisant FFprobe
read color_primaries color_trc colorspace < <(ffprobe -v error -select_streams v:0 -show_entries stream=color_primaries,color_trc,colorspace -of csv=p=0 "$in_file")
# Définition des paramètres de l'espace colorimétrique en fonction de la détection automatique
if [[ "$color_primaries" == "bt709" && "$color_trc" == "bt709" && "$colorspace" == "bt709" ]]; then
color_params=" -color_primaries 1 -color_trc 1 -colorspace 1"
else
color_params=""
fi
echo -e " COLOR_PARAMS ${color_params}\n"|tee -a $logFile
# --------------- DETECTION DU BITRATE et FRAMERATE -------------------
#bitrate=$(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$in_file")
#framerate=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "$in_file")
# Get video frame rate
framerate=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "$in_file")
# Calculate target bitrate based on video resolution and frame rate
bitrate=$(echo "scale=0; $width*$height*$framerate*0.1*0.6" | bc)
# Calculate maxrate and bufsize based on target bitrate
maxrate=$(echo "scale=0; $bitrate*1.5/1" | bc)
bufsize=$(echo "scale=0; $maxrate*2" | bc)
#maxrate="10M"
#bufsize="20M"
echo -e " framerate : $framerate\n"|tee -a $logFile
echo -e " Bitrate : $bitrate\n"|tee -a $logFile
echo -e " Maxrate : $maxrate\n"|tee -a $logFile
echo -e " Bufsize : $bufsize\n"|tee -a $logFile
# --------------- DETECTION DE LA DUREE -------------------
echo -e "==> DUREE, calcul en cours ...\n"
# Get duration
duration=$(ffmpeg -i "$in_file" 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//)
echo -e " Duration : $duration\n"|tee -a $logFile
echo -e "\n ==> Demande de compression"|tee -a $logFile
cmd_exec="ffmpeg -y -i \"${in_file}\""
if [ ${#cropSize} -ge 2 ]; then
# compression réaliser avec un crop
vf_option="${vf_option},${cropSize}"
fi
# cmd_exec="${cmd_exec} -map 0:v -map 0:a? -map 0:s?"
cmd_exec="${cmd_exec} -map 0"
# cmd_exec="${cmd_exec} -c:a libvorbis -qscale:a 4"
# cmd_exec="${cmd_exec} -c:a aac -b:a 128k -ac 2 -af loudnorm=I=-18:TP=-1:LRA=11:print_format=summary"
cmd_exec="${cmd_exec} -c:a eac3 -b:a 256k -ac 2 -af loudnorm=I=-18:TP=-1:LRA=11:print_format=summary"
cmd_exec="${cmd_exec} -c:v libx264"
cmd_exec="${cmd_exec} -filter:v \"${vf_option}\""
cmd_exec="${cmd_exec} ${color_params}"
# cmd_exec="${cmd_exec} -preset veryfast"
md_exec="${cmd_exec} -threads $(nproc)"
cmd_exec="${cmd_exec} -preset slower"
cmd_exec="${cmd_exec} -bf 5"
cmd_exec="${cmd_exec} -crf ${param2} -b:v $bitrate -pix_fmt yuv420p -maxrate $maxrate -bufsize $bufsize"
# cmd_exec="${cmd_exec} -crf 23 -maxrate 4500k -bufsize 6000k -b:v 3000k -pix_fmt yuv420p"
# cmd_exec="${cmd_exec} -profile:v high -level 4.2"
cmd_exec="${cmd_exec} -profile:v main -level 4.1 -tune film"
cmd_exec="${cmd_exec} -movflags +faststart"
cmd_exec="${cmd_exec} -tune fastdecode+zerolatency"
cmd_exec="${cmd_exec} -max_muxing_queue_size 1024 -ss 00:00:00 -t $duration"
cmd_exec="${cmd_exec} -c:s copy"
cmd_exec="${cmd_exec} \"${out_file}\""
echo "touch \"${out_file}.process\"">> ${listFileName}
echo ${cmd_exec}>> ${listFileName}
echo "rm \"${out_file}.process\"">> ${listFileName}
echo "touch \"${out_file}.processed\"">> ${listFileName}
echo -e "\n ==> On indique le fichier traité et le résultat dans un log"|tee -a $logFile
cmd_exec="echo -e \"\\\"${in_file}\\\" > \\\"${out_file}\\\"\">> ~/rsbConvert.log"
echo ${cmd_exec}>> ${listFileName}
echo -e "\n ==> Finished \"$out_file\""|tee -a $logFile
fi
fi
done
echo -e "rm ${listFileName}">> ${listFileName}
chmod +x ${listFileName}
#./rsbConvert.sh
echo -e "\n ==== DONE CONVERTING FILES ===="|tee -a $logFile
echo -e "\n\n fichier à appeler : ${listFileName}\n";
exit 0