#!/bin/bash # global variables declare -a video_file_list settings_file="./settings.ini" ffprobe_path="/usr/bin/ffprobe" # Funktion zum Extrahieren der Sprachen und Audio-Codec für alle Audio-Spuren extract_audio_languages_and_codecs() { local file=$1 # Führe ffprobe aus und extrahiere die Streams ffprobe_json=$("$ffprobe_path" -v error -show_streams -of json "$file") # Durchlaufe alle Audio-Streams und extrahiere Sprache und Codec audio_streams=() while IFS= read -r audio_stream; do stream_index=$(echo "$audio_stream" | jq -r '.index') codec_name=$(echo "$audio_stream" | jq -r '.codec_name') language=$(echo "$audio_stream" | jq -r '.tags.language') # Format für jede Audio-Spur: [index-codec_language] audio_streams+=("[$codec_name"_"$language]") done < <(echo "$ffprobe_json" | jq -c '.streams[] | select(.codec_type == "audio")') # Rückgabe des Arrays der Audio-Streams echo "${audio_streams[@]}" } # Funktion zum Extrahieren der Sprachen und "forced"-Tags für alle Untertitel-Spuren extract_subtitle_languages_and_forced_tags() { local file=$1 # Führe ffprobe aus und extrahiere die Streams ffprobe_json=$("$ffprobe_path" -v error -show_streams -of json "$file") # Durchlaufe alle Untertitel-Streams und extrahiere Sprache und Forced-Tag subtitle_streams=() while IFS= read -r subtitle_stream; do stream_index=$(echo "$subtitle_stream" | jq -r '.index') language=$(echo "$subtitle_stream" | jq -r '.tags.language') # Überprüfe sowohl das Forced-Tag in "tags" als auch das Forced-Flag in "disposition" forced=$(echo "$subtitle_stream" | jq -r '.tags.forced // empty') forced_flag=$(echo "$subtitle_stream" | jq -r '.disposition.forced') # Wenn das "forced"-Tag existiert, berücksichtige es if [[ "$forced" == "1" || "$forced_flag" == "1" ]]; then subtitle_streams+=("[forced_$language]") fi subtitle_streams+=("[$language]") done < <(echo "$ffprobe_json" | jq -c '.streams[] | select(.codec_type == "subtitle")') # Rückgabe des Arrays der Untertitel-Streams echo "${subtitle_streams[@]}" } get_user_variables_from_ini_file() { # get absolut path of the ini file settings_file=$(relativ_to_fullpath "$settings_file") # abort script if settings file can't be found if [ ! -e "$settings_file" ]; then _exit 1 "Settingsfile not found at: "$settings_file fi # read ini values input_folder=$(sed -nr "/^\[pathes\]/ { :l /^input_folder[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") output_folder=$(sed -nr "/^\[pathes\]/ { :l /^output_folder[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") jsonfile_path=$(sed -nr "/^\[pathes\]/ { :l /^jsonfile_path[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") mode=$(sed -nr "/^\[mode\]/ { :l /^mode[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") mkvmerge=$(sed -nr "/^\[mkvmerge\]/ { :l /^mkvmerge[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") notification_text=$(sed -nr "/^\[notification_text\]/ { :l /^notification_text[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") nofification_audio=$(sed -nr "/^\[nofification_audio\]/ { :l /^nofification_audio[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file") } relativ_to_fullpath() { local path="$1" scriptpath="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" # Entferne doppelte Slashes, bevor der Pfad weiterverarbeitet wird path=$(echo "$path" | sed 's|/+|/|g') if [ ! -e "$path" ]; then pathfull=$(realpath "$(dirname "$scriptpath")/$path" 2>/dev/null) else pathfull=$(realpath "$path" 2>/dev/null) fi echo "$pathfull" } main(){ get_user_variables_from_ini_file output_dir="$input_folder/[0] Sort" # Entferne doppelte Slashes output_dir=$(echo "$output_dir" | sed 's|//|/|g') echo "output_dir: '$output_dir'" mkdir -p "$output_dir" # Durchlaufe alle Videodateien im Eingabeverzeichnis rekursiv find "$input_folder" -type f \( -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.avi" \) | while IFS= read -r file; do # Überspringe Dateien, die "-sample" im Dateinamen haben if [[ "$file" == *"-sample"* ]]; then echo "Überspringe Datei '$file' (wegen '-sample' im Dateinamen)" continue fi # Extrahiere die Audio-Spuren, Sprache und Codec audio_streams=$(extract_audio_languages_and_codecs "$file") # Extrahiere die Untertitel-Spuren, Sprache und "forced"-Tag subtitle_streams=$(extract_subtitle_languages_and_forced_tags "$file") # Wenn keine Audio- oder Untertitel-Spuren vorhanden sind, überspringe die Datei if [ -z "$audio_streams" ] && [ -z "$subtitle_streams" ]; then echo "Keine Audio- oder Untertitel-Spuren in '$file'. Überspringe." continue fi # Kombiniere die Audio- und Untertitel-Streams mit einem | nur, wenn subtitle_streams nicht leer ist if [ -z "$subtitle_streams" ]; then combined_streams="$audio_streams" else combined_streams="${audio_streams} | ${subtitle_streams}" fi # Generiere den Ordnernamen basierend auf den kombinierten Streams folder_name=$(echo "$combined_streams" | tr ' ' ' ') # Zielordner für diese Kombination erstellen target_folder="$output_dir/$folder_name" mkdir -p "$target_folder" # Datei in den entsprechenden Ordner verschieben mv "$file" "$target_folder/" echo "Verschiebe '$file' nach '$target_folder/'" done } # Main main $SHELL