VideoTools/scripts/git_converter/lt-convert.sh
Jake P 799102cac7 Attempted to create GUI
Attempted to create GUIs for both lt-convert and lt-gui
2025-12-17 22:50:59 +00:00

435 lines
17 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ===================================================================
# GIT Converter v2.7 — Professional Edition (December 2025)
# Author: LeakTechnologies
# Modular Architecture for optimal performance
# ===================================================================
# Force window size and font in Git Bash on Windows
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
printf '\e[8;100;80t' # Window size 1000x800
printf '\e[14]' # Font size 14
fi
# 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 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"
# Hardware benchmarking function
run_hardware_benchmark() {
echo "Detecting your hardware..." >&2
# Detect GPU type
gpu_type="none"
gpu_name="Unknown"
# Try NVIDIA detection
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
gpu_type="nvidia"
gpu_name=$(nvidia-smi --query-gpu=name --format=csv,noheader,nounits | head -1)
echo " ✓ NVIDIA GPU detected: $gpu_name" >&2
# Try AMD detection
elif command -v lspci >/dev/null 2>&1 && lspci 2>/dev/null | grep -iq "amd\|radeon\|advanced micro devices"; then
gpu_type="amd"
gpu_name=$(lspci 2>/dev/null | grep -i "amd\|radeon" | head -1 | cut -d':' -f3 | xargs)
echo " ✓ AMD GPU detected: $gpu_name" >&2
elif command -v lshw >/dev/null 2>&1 && lshw -c display 2>/dev/null | grep -iq "amd\|radeon"; then
gpu_type="amd"
gpu_name=$(lshw -c display 2>/dev/null | grep -i "product" | head -1 | cut -d':' -f2 | xargs)
echo " ✓ AMD GPU detected: $gpu_name" >&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"
gpu_name=$(wmic path win32_VideoController get name 2>/dev/null | grep -i "amd\|radeon" | head -1 | xargs)
echo " ✓ AMD GPU detected: $gpu_name" >&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"
gpu_name=$(lspci 2>/dev/null | grep -i "intel.*vga\|intel.*display" | head -1 | cut -d':' -f3 | xargs)
echo " ✓ Intel GPU detected: $gpu_name" >&2
elif command -v lshw >/dev/null 2>&1 && lshw -c display 2>/dev/null | grep -iq "intel"; then
gpu_type="intel"
gpu_name=$(lshw -c display 2>/dev/null | grep -i "product" | head -1 | cut -d':' -f2 | xargs)
echo " ✓ Intel GPU detected: $gpu_name" >&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"
gpu_name=$(wmic path win32_VideoController get name 2>/dev/null | grep -i "intel" | head -1 | xargs)
echo " ✓ Intel GPU detected: $gpu_name" >&2
else
echo " ⚠ No GPU detected, will use CPU encoding" >&2
gpu_name="CPU"
fi
# Test encoder availability and speed
local best_encoder=""
local best_time=999999
local benchmark_score=0
# Test candidates based on GPU type
local candidates=()
case $gpu_type in
nvidia) candidates=("hevc_nvenc" "av1_nvenc" "libsvtav1" "libx265") ;;
amd) candidates=("hevc_amf" "av1_amf" "libsvtav1" "libx265") ;;
intel) candidates=("hevc_qsv" "av1_qsv" "libsvtav1" "libx265") ;;
*) candidates=("libsvtav1" "libx265") ;;
esac
echo " Testing encoders..." >&2
# Quick benchmark each encoder
for enc in "${candidates[@]}"; do
if ffmpeg -hide_banner -loglevel error -encoders | grep -q "$enc"; then
echo " Testing $enc..." >&2
start_time=$(date +%s)
# 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=2:size=640x480:rate=30" \
-c:v "$enc" -f null - >/dev/null 2>&1; then
end_time=$(date +%s)
test_time=$((end_time - start_time))
# Calculate benchmark score (higher is better)
benchmark_score=$((1000 / test_time))
echo " $enc: ${test_time}s (Score: $benchmark_score)" >&2
if [[ $test_time -lt $best_time ]]; then
best_time=$test_time
best_encoder=$enc
benchmark_score=$((1000 / best_time))
fi
else
echo " $enc: FAILED" >&2
fi
else
# Windows fallback - run without timeout but limit test duration
ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=2:size=640x480:rate=30" \
-c:v "$enc" -f null - >/dev/null 2>&1 &
ffmpeg_pid=$!
sleep 8 # Wait max 8 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))
if [[ $test_time -gt 0 ]]; then
benchmark_score=$((1000 / test_time))
else
benchmark_score=1
fi
echo " $enc: ${test_time}s (Score: $benchmark_score)" >&2
if [[ $test_time -lt $best_time ]]; then
best_time=$test_time
best_encoder=$enc
benchmark_score=$((1000 / best_time))
fi
fi
fi
else
echo " $enc: NOT AVAILABLE" >&2
fi
done
# Display results with ASCII thumbs up
echo
echo " Your $gpu_name was detected" >&2
echo " The best encoder for you is $best_encoder" >&2
echo " Your benchmark score was $benchmark_score" >&2
echo
echo " ( ͡° ͜ʖ ͡°)" >&2
echo
# Cache results
cat > "$CACHE_FILE" << EOF
cached_gpu="$gpu_name"
cached_encoder="$best_encoder"
cached_score="$benchmark_score"
cached_gpu_type="$gpu_type"
EOF
optimal_encoder="$best_encoder"
}
# Display header
clear
cat << "EOF"
╔═══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ GIT Converter v2.7 (December 2025)
║ by LeakTechnologies ║
║ ║
║ High-quality batch conversion with hardware acceleration ║
║ • AV1 & H.265 support ║
║ • Smart upscaling (Source / 720p / 1080p / 1440p / 4K / 2X / 4X)
║ • Optional 60 fps smooth motion ║
║ • Color correction for Topaz AI videos ║
║ • Clean 8-bit encoding (no green lines)
║ • AAC stereo audio ║
║ • MKV or MP4 output ║
║ ║
╚═══════════════════════════════════════════════════════════════════════════════╝
EOF
# Check for cached hardware results
CACHE_FILE="$SCRIPT_DIR/.hardware_cache"
SETTINGS_FILE="$SCRIPT_DIR/.user_settings"
if [[ -f "$CACHE_FILE" ]]; then
echo
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ Hardware Benchmarking ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo
echo " 1) Convert (Skip Benchmark) - Use cached settings"
echo " 2) Run Hardware Benchmarking"
echo
while true; do
read -p " Enter 12 → " bench_choice
if [[ -n "$bench_choice" && "$bench_choice" =~ ^[1-2]$ ]]; then
break
else
echo " Invalid input. Please enter 1 or 2."
fi
done
if [[ "$bench_choice" == "1" ]]; then
# Load cached results
source "$CACHE_FILE"
echo "✅ Using cached hardware settings"
echo " Your $cached_gpu was detected"
echo " The best encoder for you is $cached_encoder"
echo " Your benchmark score was $cached_score"
echo
optimal_encoder="$cached_encoder"
else
echo -e "\n🔍 Running hardware benchmarking..."
run_hardware_benchmark
fi
else
echo -e "\n🔍 First-time setup - running hardware benchmarking..."
run_hardware_benchmark
fi
echo
echo "Press space to continue..."
read -n 1 -s
clear
# Get user settings
echo
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ Choose Encoder/GPU ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo
echo " 1) Auto-detect optimal encoder (recommended)"
echo " 2) NVIDIA GPU encoding"
echo " 3) AMD GPU encoding"
echo " 4) CPU encoding"
echo
while true; do
read -p " Enter 14 → " enc_choice
if [[ -n "$enc_choice" && "$enc_choice" =~ ^[1-4]$ ]]; then
break
else
echo " Invalid input. Please enter a number between 1 and 4."
fi
done
case $enc_choice in
1)
echo "✅ Auto-detected: $optimal_encoder"
;;
2)
# Auto-select best NVIDIA encoder
if ffmpeg -hide_banner -loglevel error -encoders | grep -q "hevc_nvenc"; then
optimal_encoder="hevc_nvenc"
echo "✅ Selected: NVIDIA HEVC NVENC"
elif ffmpeg -hide_banner -loglevel error -encoders | grep -q "av1_nvenc"; then
optimal_encoder="av1_nvenc"
echo "✅ Selected: NVIDIA AV1 NVENC"
else
echo "❌ No NVIDIA encoders available, using auto-detected"
fi
;;
3)
# Auto-select best AMD encoder
if ffmpeg -hide_banner -loglevel error -encoders | grep -q "hevc_amf"; then
optimal_encoder="hevc_amf"
echo "✅ Selected: AMD HEVC AMF"
elif ffmpeg -hide_banner -loglevel error -encoders | grep -q "av1_amf"; then
optimal_encoder="av1_amf"
echo "✅ Selected: AMD AV1 AMF"
else
echo "❌ No AMD encoders available, using auto-detected"
fi
;;
4)
# Auto-select best CPU encoder
if ffmpeg -hide_banner -loglevel error -encoders | grep -q "libsvtav1"; then
optimal_encoder="libsvtav1"
echo "✅ Selected: CPU SVT-AV1"
else
optimal_encoder="libx265"
echo "✅ Selected: CPU x265 HEVC"
fi
;;
esac
# Settings persistence functions
save_user_settings() {
cat > "$SETTINGS_FILE" << EOF
# User settings cache - GIT Converter v2.7
cached_encoder="$optimal_encoder"
cached_resolution="$res_name"
cached_fps_choice="$fps_choice"
cached_quality_choice="$b"
cached_color_choice="$color_opt"
cached_modular_choice="$op_choice"
cached_scale="$scale"
cached_scale_flags="$scale_flags"
cached_quality_params="$quality_params"
cached_quality_name="$quality_name"
cached_color_filter="$color_filter"
cached_color_suf="$color_suf"
cached_fps_filter="$fps_filter"
cached_suf="$suf"
EOF
}
load_user_settings() {
if [[ -f "$SETTINGS_FILE" ]]; then
echo
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ Previous Settings Found ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo
echo " 1) Use previous settings"
echo " 2) Configure new settings"
echo
while true; do
read -p " Enter 12 → " settings_choice
if [[ -n "$settings_choice" && "$settings_choice" =~ ^[1-2]$ ]]; then
break
else
echo " Invalid input. Please enter 1 or 2."
fi
done
if [[ "$settings_choice" == "1" ]]; then
source "$SETTINGS_FILE"
echo "✅ Using previous settings"
echo " Encoder: $cached_encoder"
echo " Resolution: $cached_resolution"
echo " Quality: $cached_quality_name"
echo " Color: ${cached_color_suf:-None}"
echo " FPS: ${cached_suf:-Original}"
echo
optimal_encoder="$cached_encoder"
res_name="$cached_resolution"
scale="$cached_scale"
scale_flags="$cached_scale_flags"
fps_choice="$cached_fps_choice"
fps_filter="$cached_fps_filter"
suf="$cached_suf"
b="$cached_quality_choice"
quality_params="$cached_quality_params"
quality_name="$cached_quality_name"
color_opt="$cached_color_choice"
color_filter="$cached_color_filter"
color_suf="$cached_color_suf"
return 0
fi
fi
return 1
}
setup_codec_and_container
if ! load_user_settings; then
get_modular_operations
get_resolution_settings
get_fps_settings
get_quality_settings "$optimal_encoder"
get_color_correction
# Save settings for next time
save_user_settings
fi
# Build filter chain
build_filter_chain
# Set container from user selection
ext="$OUTPUT_CONTAINER"
# Display encoding summary
echo
echo "Encoding → $ENCODER | $res_name | $ext $suf${color_suf} @ $quality_name"
echo
# Process video files - handle drag-and-drop vs double-click
if [[ $# -gt 0 ]]; then
# Files were dragged onto the script
video_files=("$@")
echo "Processing dragged files: ${#video_files[@]} file(s)"
else
# Double-clicked - process all video files in current directory
# 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
echo "Processing all video files in current directory: ${#video_files[@]} file(s)"
fi
# Process all files
process_files "$ENCODER" "$quality_params" "$filter_chain" "$suf" "$color_suf" "$ext" "${video_files[@]}"
echo "========================================================"
echo "All finished — files in '$OUT'"
echo "========================================================"
read -p "Press Enter to exit"