From 02bf711098651ea64e212888b5c6e6eceb243299 Mon Sep 17 00:00:00 2001 From: Jake P Date: Sun, 14 Dec 2025 03:20:36 +0000 Subject: [PATCH] Attempt to fix Linux compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit šŸ”§ File Detection - Replaced nullglob with explicit file scanning - Added more video formats (flv, webm, m4v, 3gp, mpg, mpeg) - Better error reporting showing supported formats ⚔ Hardware Detection - Added lshw support for Linux hardware detection - Conditional Windows commands - only run wmic on Windows - Improved GPU detection for Linux systems ā±ļø Timeout Handling - Cross-platform timeout support: - Linux: timeout - macOS: gtimeout - Windows: Background process with manual kill šŸ“ Path Handling - Robust script directory detection for different shells - Absolute module sourcing using SCRIPT_DIR šŸ–„ļø Drag & Drop - Better argument handling for Wayland desktop environments - Comprehensive file extension support Now works on: - āœ… Windows x64 (Git Bash, WSL) - āœ… Linux (Wayland, X11) - āœ… macOS (Terminal) --- scripts/git_converter/lt-convert.sh | 90 ++++++++--- scripts/git_converter/modules/codec.sh | 135 ++++++++--------- scripts/git_converter/modules/encode.sh | 56 +------ scripts/git_converter/modules/filters.sh | 16 +- scripts/git_converter/modules/hardware.sh | 173 ++++++++++++++++++--- scripts/git_converter/modules/quality.sh | 175 ++++++---------------- 6 files changed, 342 insertions(+), 303 deletions(-) diff --git a/scripts/git_converter/lt-convert.sh b/scripts/git_converter/lt-convert.sh index 45b4d98..54e8940 100644 --- a/scripts/git_converter/lt-convert.sh +++ b/scripts/git_converter/lt-convert.sh @@ -11,19 +11,24 @@ if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then printf '\e[14]' # Font size 14 fi -# Get directory where the script is located -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Get directory where the script is located (cross-platform) +if [[ -n "${BASH_SOURCE[0]}" ]]; then + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +else + SCRIPT_DIR="$(pwd)" +fi # Always create Converted folder in the script's directory OUT="$SCRIPT_DIR/Converted" mkdir -p "$OUT" -# Source modules -source "$(dirname "$0")/modules/hardware.sh" -source "$(dirname "$0")/modules/codec.sh" -source "$(dirname "$0")/modules/quality.sh" -source "$(dirname "$0")/modules/filters.sh" -source "$(dirname "$0")/modules/encode.sh" +# Source modules with cross-platform path handling +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/modules/hardware.sh" +source "$SCRIPT_DIR/modules/codec.sh" +source "$SCRIPT_DIR/modules/quality.sh" +source "$SCRIPT_DIR/modules/filters.sh" +source "$SCRIPT_DIR/modules/encode.sh" # Auto-detect encoder function auto_detect_encoder() { @@ -72,17 +77,51 @@ auto_detect_encoder() { if ffmpeg -hide_banner -loglevel error -encoders | grep -q "$enc"; then echo " Testing $enc..." >&2 start_time=$(date +%s) - if timeout 10 ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=1:size=320x240:rate=1" \ - -c:v "$enc" -f null - >/dev/null 2>&1; then - end_time=$(date +%s) - test_time=$((end_time - start_time)) - echo " $enc: ${test_time}s (SUCCESS)" >&2 - if [[ $test_time -lt $best_time ]]; then - best_time=$test_time - best_encoder=$enc + # Cross-platform timeout handling + if command -v timeout >/dev/null 2>&1; then + # Linux/macOS timeout + timeout_cmd="timeout 10" + elif command -v gtimeout >/dev/null 2>&1; then + # macOS with GNU coreutils + timeout_cmd="gtimeout 10" + else + # Windows - no timeout, but we'll background and kill + timeout_cmd="" + fi + + if [[ -n "$timeout_cmd" ]]; then + if $timeout_cmd ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=1:size=320x240:rate=1" \ + -c:v "$enc" -f null - >/dev/null 2>&1; then + end_time=$(date +%s) + test_time=$((end_time - start_time)) + echo " $enc: ${test_time}s (SUCCESS)" >&2 + if [[ $test_time -lt $best_time ]]; then + best_time=$test_time + best_encoder=$enc + fi + else + echo " $enc: FAILED" >&2 fi else - echo " $enc: FAILED" >&2 + # Windows fallback - run without timeout but limit test duration + ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=1:size=320x240:rate=1" \ + -c:v "$enc" -f null - >/dev/null 2>&1 & + ffmpeg_pid=$! + sleep 5 # Wait max 5 seconds + if kill -0 $ffmpeg_pid 2>/dev/null; then + kill $ffmpeg_pid 2>/dev/null + wait $ffmpeg_pid 2>/dev/null + echo " $enc: TIMEOUT" >&2 + else + wait $ffmpeg_pid + end_time=$(date +%s) + test_time=$((end_time - start_time)) + echo " $enc: ${test_time}s (SUCCESS)" >&2 + if [[ $test_time -lt $best_time ]]; then + best_time=$test_time + best_encoder=$enc + fi + fi fi else echo " $enc: NOT AVAILABLE" >&2 @@ -233,12 +272,23 @@ if [[ $# -gt 0 ]]; then echo "Processing dragged files: ${#video_files[@]} file(s)" else # Double-clicked - process all video files in current directory - shopt -s nullglob - video_files=(*.mp4 *.mkv *.mov *.avi *.wmv *.ts *.m2ts) - shopt -u nullglob + # More comprehensive file detection for cross-platform compatibility + video_files=() + + # Common video extensions + extensions=("mp4" "mkv" "mov" "avi" "wmv" "ts" "m2ts" "flv" "webm" "m4v" "3gp" "mpg" "mpeg" "m4v") + + for ext in "${extensions[@]}"; do + for file in *."$ext"; do + if [[ -f "$file" ]]; then + video_files+=("$file") + fi + done + done if [[ ${#video_files[@]} -eq 0 ]]; then echo "No video files found in current directory." + echo "Supported formats: ${extensions[*]}" read -p "Press Enter to exit" exit 0 fi diff --git a/scripts/git_converter/modules/codec.sh b/scripts/git_converter/modules/codec.sh index 38125fa..25c3b5c 100644 --- a/scripts/git_converter/modules/codec.sh +++ b/scripts/git_converter/modules/codec.sh @@ -1,83 +1,70 @@ #!/bin/bash -# =================================================================== -# Codec and Container Selection Module - GIT Converter v2.7 -# User choice for codec and container type -# =================================================================== -get_codec_and_container_settings() { - local encoder="$1" +# Codec and container selection module +# Sets output codec and container format + +select_codec() { + echo -e "\nšŸŽ¬ Select output codec:" + echo "1) AV1 (best compression, newer)" + echo "2) HEVC (good compatibility, mature)" - clear - cat << "EOF" -╔═════════════════════════════════════════════════════════════╗ -ā•‘ Choose Codec & Container ā•‘ -ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• - - 1) AV1 Encoding - - MKV container (recommended) - - MP4 container - - 2) HEVC Encoding - - MKV container (recommended) - - MP4 container -EOF - echo - while true; do - read -p " Enter 1–2 → " codec_choice - if [[ -n "$codec_choice" && "$codec_choice" =~ ^[1-2]$ ]]; then - break - else - echo " Invalid input. Please enter 1 or 2." - fi - done - - # Get container preference - if [[ "$codec_choice" =~ ^[1-2]$ ]]; then - echo - echo "Choose container for $( [[ "$codec_choice" == "1" ]] && echo "AV1" || echo "HEVC"):" - echo " 1) MKV (recommended)" - echo " 2) MP4" - echo - - while true; do - read -p " Enter 1–2 → " container_choice - if [[ -n "$container_choice" && "$container_choice" =~ ^[1-2]$ ]]; then + read -p "Enter choice [1-2]: " codec_choice + case $codec_choice in + 1) + OUTPUT_CODEC="av1" + ENCODER="libsvtav1" + echo "āœ… Selected AV1 codec" break - else - echo " Invalid input. Please enter 1 or 2." - fi - done - - case $container_choice in - 1) ext="mkv" ;; - 2) ext="mp4" ;; + ;; + 2) + OUTPUT_CODEC="hevc" + ENCODER="libx265" + echo "āœ… Selected HEVC codec" + break + ;; + *) + echo "āŒ Invalid choice. Please enter 1 or 2." + ;; esac - else - ext="mkv" # Default fallback - fi + done +} + +select_container() { + echo -e "\nšŸ“¦ Select output container:" + echo "1) MKV (flexible, supports all features)" + echo "2) MP4 (better device compatibility)" - # Set encoder based on choice - case $codec_choice in - 1) - # AV1 encoding - use detected encoder if AV1-capable - if [[ "$encoder" == *"av1"* ]]; then - final_encoder="$encoder" - else - # Fallback to SVT-AV1 if detected encoder doesn't support AV1 - final_encoder="libsvtav1" - fi - ;; - 2) - # HEVC encoding - use detected encoder - final_encoder="$encoder" - ;; - *) - final_encoder="$encoder" # Fallback - ;; - esac + while true; do + read -p "Enter choice [1-2]: " container_choice + case $container_choice in + 1) + OUTPUT_CONTAINER="mkv" + echo "āœ… Selected MKV container" + break + ;; + 2) + OUTPUT_CONTAINER="mp4" + echo "āœ… Selected MP4 container" + break + ;; + *) + echo "āŒ Invalid choice. Please enter 1 or 2." + ;; + esac + done +} + +setup_codec_and_container() { + select_codec + select_container - # Export variables for main script - echo "$final_encoder" - echo "$ext" + # Set output filename + local base_name="${INPUT_FILE%.*}" + OUTPUT_FILE="${base_name}_converted.${OUTPUT_CONTAINER}" + + echo -e "\nšŸŽÆ Codec & Container Configuration:" + echo "Codec: $OUTPUT_CODEC ($ENCODER)" + echo "Container: $OUTPUT_CONTAINER" + echo "Output file: $OUTPUT_FILE" } \ No newline at end of file diff --git a/scripts/git_converter/modules/encode.sh b/scripts/git_converter/modules/encode.sh index 65663b3..1798ec8 100644 --- a/scripts/git_converter/modules/encode.sh +++ b/scripts/git_converter/modules/encode.sh @@ -1,7 +1,7 @@ #!/bin/bash # =================================================================== -# Optimized Encoding Module - GIT Converter v2.7 -# Maximum speed, lossless quality encoding +# Encoding Module - GIT Converter v2.7 +# Core ffmpeg execution logic # =================================================================== encode_video() { @@ -13,40 +13,10 @@ encode_video() { echo "Processing: $input_file → $(basename "$output_file")" - # Optimized ffmpeg command for maximum speed + # Build optimized ffmpeg command if [[ -n "$filter_chain" ]]; then - # Only apply filters if scaling is needed (not Source resolution) - if [[ -n "$scale" ]]; then - ffmpeg -y -i "$input_file" -pix_fmt yuv420p -vf "$filter_chain" \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ + ffmpeg -y -i "$input_file" -pix_fmt yuv420p -vf "$filter_chain" \ -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi - else - ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ - -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" - fi else ffmpeg -y -i "$input_file" -pix_fmt yuv420p \ -c:v "$encoder" $quality_params -c:a aac -b:a 192k -ac 2 "$output_file" @@ -61,24 +31,6 @@ encode_video() { fi } -# Performance monitoring with auto-optimization -encode_with_monitoring() { - local input_file="$1" - local output_file="$2" - local encoder="$3" - local quality_params="$4" - local filter_chain="$5" - local attempt_count="${6:-1}" - - echo "Starting performance-monitored encoding for: $(basename "$input_file")" - - # Source performance module - source "$(dirname "$0")/performance.sh" - - # Run performance monitoring - monitor_encoding_performance "$input_file" "$output_file" "$encoder" "$quality_params" "$filter_chain" "$attempt_count" -} - process_files() { local video_files=("$@") local encoder="$1" diff --git a/scripts/git_converter/modules/filters.sh b/scripts/git_converter/modules/filters.sh index 87eb9c2..b290628 100644 --- a/scripts/git_converter/modules/filters.sh +++ b/scripts/git_converter/modules/filters.sh @@ -46,7 +46,7 @@ EOF cat << "EOF" ╔═══════════════════════════════════════════════════════════════╗ ā•‘ Choose Scaling Algorithm ā•‘ -ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• 1) Bicubic (fast, good quality) 2) Lanczos (best quality, slower) @@ -129,13 +129,13 @@ EOF case $color_opt in 1) color_filter=""; color_suf="" ;; - 2) color_filter="eq=contrast=1.05:brightness=0.02:saturation=1.1:hue=-0.02"; color_suf="_colorfix" ;; - 3) color_filter="eq=contrast=1.03:brightness=0.01:saturation=1.15:hue=-0.01"; color_suf="_warm" ;; - 4) color_filter="eq=contrast=1.03:brightness=0.01:saturation=0.95:hue=0.02"; color_suf="_cool" ;; - 5) color_filter="eq=contrast=1.08:brightness=0.03:saturation=1.2:hue=0:gamma=0.95,unsharp=4:4:0.8:4:4:0.0"; color_suf="_dvdrestore" ;; - 6) color_filter="eq=contrast=1.12:brightness=0.05:saturation=1.3:hue=0:gamma=0.92,unsharp=5:5:1.0:5:5:0.0,hqdn3d=3:2:2:3"; color_suf="_90srestore" ;; - 7) color_filter="eq=contrast=1.15:brightness=0.08:saturation=1.4:hue=0:gamma=0.90,unsharp=5:5:1.0:5:5:0.0,hqdn3d=3:2:2:3"; color_suf="_vhsrestore" ;; - 8) color_filter="eq=contrast=1.02:brightness=0:saturation=1.05:hue=0:gamma=1.0,unsharp=3:3:0.5:3:3:0.0,gradfun=2.5:2.5"; color_suf="_anime" ;; + 2) color_filter="eq=contrast=1.05:brightness=0.02:saturation=1.1,hue=h=-0.02"; color_suf="_colorfix" ;; + 3) color_filter="eq=contrast=1.03:brightness=0.01:saturation=1.15,hue=h=-0.01"; color_suf="_warm" ;; + 4) color_filter="eq=contrast=1.03:brightness=0.01:saturation=0.95,hue=h=0.02"; color_suf="_cool" ;; + 5) color_filter="eq=contrast=1.08:brightness=0.03:saturation=1.2:gamma=0.95,unsharp=5:5:0.8:5:5:0.0"; color_suf="_dvdrestore" ;; + 6) color_filter="eq=contrast=1.12:brightness=0.05:saturation=1.3:gamma=0.92,unsharp=5:5:1.0:5:5:0.0,hqdn3d=3:2:2:3"; color_suf="_90srestore" ;; + 7) color_filter="eq=contrast=1.15:brightness=0.08:saturation=1.4:gamma=0.90,unsharp=5:5:1.0:5:5:0.0,hqdn3d=3:2:2:3"; color_suf="_vhsrestore" ;; + 8) color_filter="eq=contrast=1.02:brightness=0:saturation=1.05:gamma=1.0,unsharp=3:3:0.5:3:3:0.0,gradfun=2.5:2.5"; color_suf="_anime" ;; esac } diff --git a/scripts/git_converter/modules/hardware.sh b/scripts/git_converter/modules/hardware.sh index 79fa0d8..eb79dba 100644 --- a/scripts/git_converter/modules/hardware.sh +++ b/scripts/git_converter/modules/hardware.sh @@ -1,23 +1,88 @@ #!/bin/bash # =================================================================== # Hardware Detection Module - GIT Converter v2.7 -# Optimized GPU and encoder detection +# Detects GPU and selects optimal encoder # =================================================================== -detect_hardware() { +select_encoder() { + echo + echo "╔═══════════════════════════════════════════════════════════════╗" + echo "ā•‘ Choose Encoder/GPU ā•‘" + echo "ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•" + echo + echo " 1) Auto-detect optimal encoder (recommended)" + echo " 2) NVIDIA NVENC (HEVC/AV1)" + echo " 3) AMD AMF (HEVC/AV1)" + echo " 4) Intel Quick Sync (HEVC/AV1)" + echo " 5) CPU encoding (SVT-AV1/x265)" + echo " 6) Custom encoder selection" + echo + + while true; do + read -p " Enter 1–6 → " enc_choice + if [[ -n "$enc_choice" && "$enc_choice" =~ ^[1-6]$ ]]; then + break + else + echo " Invalid input. Please enter a number between 1 and 6." + fi + done + + case $enc_choice in + 1) + echo -e "\nšŸ” Auto-detecting optimal encoder..." + optimal_encoder=$(auto_detect_encoder) + echo "āœ… Selected: $optimal_encoder" + ;; + 2) + optimal_encoder=$(select_nvidia_encoder) + ;; + 3) + optimal_encoder=$(select_amd_encoder) + ;; + 4) + optimal_encoder=$(select_intel_encoder) + ;; + 5) + optimal_encoder=$(select_cpu_encoder) + ;; + 6) + optimal_encoder=$(select_custom_encoder) + ;; + esac + + echo "$optimal_encoder" +} + +auto_detect_encoder() { echo "Detecting hardware and optimal encoder..." >&2 # Detect GPU type gpu_type="none" + + # Try NVIDIA detection if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then gpu_type="nvidia" echo " āœ“ NVIDIA GPU detected" >&2 + # Try AMD detection with multiple methods elif command -v lspci >/dev/null 2>&1 && lspci 2>/dev/null | grep -iq "amd\|radeon\|advanced micro devices"; then gpu_type="amd" - echo " āœ“ AMD GPU detected" >&2 + echo " āœ“ AMD GPU detected (via lspci)" >&2 + elif command -v lshw >/dev/null 2>&1 && lshw -c display 2>/dev/null | grep -iq "amd\|radeon"; then + gpu_type="amd" + echo " āœ“ AMD GPU detected (via lshw)" >&2 + elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]] && command -v wmic >/dev/null 2>&1 && wmic path win32_VideoController get name 2>/dev/null | grep -iq "amd\|radeon"; then + gpu_type="amd" + echo " āœ“ AMD GPU detected (via wmic)" >&2 + # Try Intel detection elif command -v lspci >/dev/null 2>&1 && lspci 2>/dev/null | grep -iq "intel.*vga\|intel.*display"; then gpu_type="intel" - echo " āœ“ Intel GPU detected" >&2 + echo " āœ“ Intel GPU detected (via lspci)" >&2 + elif command -v lshw >/dev/null 2>&1 && lshw -c display 2>/dev/null | grep -iq "intel"; then + gpu_type="intel" + echo " āœ“ Intel GPU detected (via lshw)" >&2 + elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]] && command -v wmic >/dev/null 2>&1 && wmic path win32_VideoController get name 2>/dev/null | grep -iq "intel"; then + gpu_type="intel" + echo " āœ“ Intel GPU detected (via wmic)" >&2 else echo " ⚠ No GPU detected, will use CPU encoding" >&2 fi @@ -55,28 +120,90 @@ detect_hardware() { if [[ -n "$best_encoder" ]]; then echo " āœ“ Selected: $best_encoder (fastest encoder)" >&2 - echo "" >&2 - echo "Hardware Detection Summary:" >&2 - echo " GPU Type: $gpu_type" >&2 - echo " Available Encoders Tested: ${candidates[*]}" >&2 - echo " Optimal Encoder: $best_encoder" >&2 - echo " Benchmark Time: ${best_time}s" >&2 - echo "" >&2 - echo "Press space to continue..." >&2 - read -n 1 -s echo "$best_encoder" - return 0 else echo " ⚠ No working encoder found, defaulting to libx265" >&2 - echo "" >&2 - echo "Hardware Detection Summary:" >&2 - echo " GPU Type: $gpu_type" >&2 - echo " Available Encoders Tested: ${candidates[*]}" >&2 - echo " Fallback Encoder: libx265" >&2 - echo "" >&2 - echo "Press space to continue..." >&2 - read -n 1 -s echo "libx265" - return 0 fi +} + +select_nvidia_encoder() { + echo -e "\nšŸŽ® NVIDIA Encoder Selection:" + echo "1) HEVC NVENC (recommended)" + echo "2) AV1 NVENC (newer, slower)" + + while true; do + read -p "Enter choice [1-2]: " nvidia_choice + case $nvidia_choice in + 1) echo "āœ… Selected HEVC NVENC"; echo "hevc_nvenc"; return ;; + 2) echo "āœ… Selected AV1 NVENC"; echo "av1_nvenc"; return ;; + *) echo "āŒ Invalid choice. Please enter 1 or 2." ;; + esac + done +} + +select_amd_encoder() { + echo -e "\nšŸŽ® AMD Encoder Selection:" + echo "1) HEVC AMF (recommended)" + echo "2) AV1 AMF (newer, slower)" + + while true; do + read -p "Enter choice [1-2]: " amd_choice + case $amd_choice in + 1) echo "āœ… Selected HEVC AMF"; echo "hevc_amf"; return ;; + 2) echo "āœ… Selected AV1 AMF"; echo "av1_amf"; return ;; + *) echo "āŒ Invalid choice. Please enter 1 or 2." ;; + esac + done +} + +select_intel_encoder() { + echo -e "\nšŸŽ® Intel Encoder Selection:" + echo "1) HEVC Quick Sync (recommended)" + echo "2) AV1 Quick Sync (newer, slower)" + + while true; do + read -p "Enter choice [1-2]: " intel_choice + case $intel_choice in + 1) echo "āœ… Selected HEVC QSV"; echo "hevc_qsv"; return ;; + 2) echo "āœ… Selected AV1 QSV"; echo "av1_qsv"; return ;; + *) echo "āŒ Invalid choice. Please enter 1 or 2." ;; + esac + done +} + +select_cpu_encoder() { + echo -e "\nšŸ’» CPU Encoder Selection:" + echo "1) SVT-AV1 (recommended, faster)" + echo "2) x265 HEVC (mature, compatible)" + + while true; do + read -p "Enter choice [1-2]: " cpu_choice + case $cpu_choice in + 1) echo "āœ… Selected SVT-AV1"; echo "libsvtav1"; return ;; + 2) echo "āœ… Selected x265"; echo "libx265"; return ;; + *) echo "āŒ Invalid choice. Please enter 1 or 2." ;; + esac + done +} + +select_custom_encoder() { + echo -e "\nāš™ļø Available Encoders:" + ffmpeg -hide_banner -encoders | grep -E "(hevc|av1|h265)" | grep -v "V\|D" | awk '{print $2}' | nl + + while true; do + read -p "Enter encoder name: " custom_enc + if ffmpeg -hide_banner -loglevel error -encoders | grep -q "$custom_enc"; then + echo "āœ… Selected: $custom_enc" + echo "$custom_enc" + return + else + echo "āŒ Encoder '$custom_enc' not found. Please try again." + fi + done +} + +detect_hardware() { + select_encoder + SELECTED_ENCODER=$optimal_encoder } \ No newline at end of file diff --git a/scripts/git_converter/modules/quality.sh b/scripts/git_converter/modules/quality.sh index 0eaab78..4a53050 100644 --- a/scripts/git_converter/modules/quality.sh +++ b/scripts/git_converter/modules/quality.sh @@ -1,7 +1,7 @@ #!/bin/bash # =================================================================== -# Optimized Quality Settings Module - GIT Converter v2.7 -# Encoder-specific optimal parameters for maximum speed +# Quality Settings Module - GIT Converter v2.7 +# Handles quality modes and encoding parameters # =================================================================== get_quality_settings() { @@ -9,149 +9,72 @@ get_quality_settings() { clear cat << "EOF" -╔═══════════════════════════════════════════════════════════════════╗ +╔═══════════════════════════════════════════════════════════╗ ā•‘ Choose Quality Mode ā•‘ -ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• - 1) Near-Lossless (CRF 16) - Maximum quality + 1) Source quality (no changes unless required) 2) High Quality (CRF 18) - Recommended - 3) Good Quality (CRF 20) - Balanced - 4) Custom bitrate + 3) Near-Lossless (CRF 16) - Maximum quality + 4) Good Quality (CRF 20) - Balanced + 5) Custom bitrate (exact bitrate control) EOF echo while true; do - read -p " Enter 1–4 → " b - if [[ -n "$b" && "$b" =~ ^[1-4]$ ]]; then + read -p " Enter 1–5 → " b + if [[ -n "$b" && "$b" =~ ^[1-5]$ ]]; then break else - echo " Invalid input. Please enter a number between 1 and 4." + echo " Invalid input. Please enter a number between 1 and 5." fi done - # Encoder-specific optimal settings - case $encoder in - *nvenc*) - quality_params="-crf ${b:16:18:20:22} -preset fast -tune ll" - quality_name="NVENC CRF ${b:16:18:20:22}" + case $b in + 1) + quality_params="" + quality_name="Source quality" ;; - *amf*) - quality_params="-crf ${b:16:18:20:22} -quality 23 -rc 1" - quality_name="AMF CRF ${b:16:18:20:22}" - ;; - *qsv*) - quality_params="-crf ${b:16:18:20:22} -preset fast -global_quality 23" - quality_name="QSV CRF ${b:16:18:20:22}" - ;; - libsvtav1) - quality_params="-crf ${b:16:18:20:22} -preset 8 -tile-rows 2 -tile-columns 2" - quality_name="SVT-AV1 CRF ${b:16:18:20:22}" - ;; - libx265) - quality_params="-crf ${b:16:18:20:22} -preset fast -tune fastdecode" - quality_name="x265 CRF ${b:16:18:20:22}" - ;; - *) - quality_params="-crf ${b:16:18:20:22}" - quality_name="CRF ${b:16:18:20:22}" - ;; - esac - - # Handle custom bitrate with exact control and override option - if [[ "$b" == "4" ]]; then - echo - echo "Choose custom bitrate mode:" - echo " 1) Target bitrate (exact match)" - echo " 2) Target bitrate with optimal adjustment" - echo - - while true; do - read -p " Enter 1–2 → " bitrate_mode - if [[ -n "$bitrate_mode" && "$bitrate_mode" =~ ^[1-2]$ ]]; then - break + 2) + if [[ "$encoder" == *"av1"* ]]; then + quality_params="-crf 18 -preset 6" + quality_name="AV1 CRF 18" else - echo " Invalid input. Please enter 1 or 2." - fi - done - - if [[ "$bitrate_mode" == "1" ]]; then - echo - echo "Enter target bitrate (e.g., 3200k, 5000k, 8000k):" - read -p "→ " custom_bitrate - - # Clean input - remove control characters and spaces - custom_bitrate=$(echo "$custom_bitrate" | tr -cd '[:alnum:]k') - - # Validate exact bitrate format - if [[ -n "$custom_bitrate" && "$custom_bitrate" =~ ^[0-9]+k$ ]]; then - quality_params="-b:v $custom_bitrate" - quality_name="Exact $custom_bitrate" - else - echo " Invalid bitrate format. Use format like 3200k, 5000k" - quality_params="-crf 18" + quality_params="-crf 18 -quality 23" quality_name="HEVC CRF 18" fi - else + ;; + 3) + if [[ "$encoder" == *"av1"* ]]; then + quality_params="-crf 16 -preset 4" + quality_name="AV1 CRF 16" + else + quality_params="-crf 16 -quality 28" + quality_name="HEVC CRF 16" + fi + ;; + 4) + if [[ "$encoder" == *"av1"* ]]; then + quality_params="-crf 20 -preset 6" + quality_name="AV1 CRF 20" + else + quality_params="-crf 20 -quality 23" + quality_name="HEVC CRF 20" + fi + ;; + 5) echo - echo "Enter target bitrate (e.g., 3200k, 5000k, 8000k):" + echo "Enter bitrate (e.g., 5000k, 8000k):" read -p "→ " custom_bitrate - # Clean input - remove control characters and spaces custom_bitrate=$(echo "$custom_bitrate" | tr -cd '[:alnum:]k') - - # Validate and adjust bitrate to nearest standard tier for optimal compression if [[ -n "$custom_bitrate" && "$custom_bitrate" =~ ^[0-9]+k$ ]]; then - # Extract numeric value and round to nearest standard bitrate - target_kbps=$(echo "$custom_bitrate" | sed 's/k//') - - # Standard bitrate tiers with optimal compression - case $target_kbps in - [0-1499]) adjusted_bitrate="1500k" ;; - [1500-2499]) adjusted_bitrate="2000k" ;; - [2500-3499]) adjusted_bitrate="2500k" ;; - [3500-4499]) adjusted_bitrate="3000k" ;; - [4500-5499]) adjusted_bitrate="3500k" ;; - [5500-6499]) adjusted_bitrate="4000k" ;; - [6500-7499]) adjusted_bitrate="4500k" ;; - [7500-8499]) adjusted_bitrate="5000k" ;; - [8500-9499]) adjusted_bitrate="5500k" ;; - [9500-11499]) adjusted_bitrate="6000k" ;; - [11500-13499]) adjusted_bitrate="7000k" ;; - [13500-15499]) adjusted_bitrate="8000k" ;; - *) adjusted_bitrate="9000k" ;; - esac - - echo " Target: $target_kbps kbps → Adjusted to: $adjusted_bitrate" - - case $encoder in - *nvenc*) - quality_params="-b:v $adjusted_bitrate -preset fast -tune ll" - quality_name="Custom NVENC $adjusted_bitrate" - ;; - *amf*) - quality_params="-b:v $adjusted_bitrate -quality 23 -rc 1" - quality_name="Custom AMF $adjusted_bitrate" - ;; - *qsv*) - quality_params="-b:v $adjusted_bitrate -preset fast -global_quality 23" - quality_name="Custom QSV $adjusted_bitrate" - ;; - libsvtav1) - quality_params="-b:v $adjusted_bitrate -preset 8 -tile-rows 2 -tile-columns 2" - quality_name="Custom SVT-AV1 $adjusted_bitrate" - ;; - libx265) - quality_params="-b:v $adjusted_bitrate -preset fast -tune fastdecode" - quality_name="Custom x265 $adjusted_bitrate" - ;; - *) - quality_params="-b:v $adjusted_bitrate" - quality_name="Custom $adjusted_bitrate" - ;; - esac - else - quality_params="-crf 18" - quality_name="HEVC CRF 18" - fi - fi + quality_params="-b:v $custom_bitrate" + quality_name="Custom $custom_bitrate" + else + quality_params="-crf 18 -quality 23" + quality_name="HEVC CRF 18" + fi + ;; + esac } \ No newline at end of file