Turned GIT Converter Modular
📋 GIT Converter v2.7 - Feature Summary & Changes 🚀 Major New Features Added 🎬 Codec & Container Selection - AV1 vs HEVC encoding - Choose between next-gen AV1 or mature HEVC - MKV vs MP4 containers - Flexibility vs device compatibility - User-controlled output format - Full control over final file type ⚙️ Advanced Quality Control - Source Quality mode - Bypass quality changes unless required - CRF options - 16 (near-lossless), 18 (recommended), 20 (balanced) - Custom bitrate control - Exact bitrate specification for precise file sizes - Encoder-specific optimization - Different parameters for AV1 vs HEVC 🎮 GPU/Encoder Selection - Auto-detection - Intelligent hardware detection with benchmarking - Manual selection - Choose specific GPU/encoder: - NVIDIA NVENC (HEVC/AV1) - AMD AMF (HEVC/AV1) - Intel Quick Sync (HEVC/AV1) - CPU encoding (SVT-AV1/x265) - Custom encoder selection - Two-stage interface - Auto-detect first, then option to override 🎨 Enhanced Color Correction - 8 specialized presets: - 2000s DVD Restore - 90s Quality Restore - VHS Quality Restore - Anime Preservation - Pink skin tone restoration (Topaz AI fix) - Warm/Cool color boosts - Fixed filter parameters - Resolved unsharp filter matrix size issues 🔧 Technical Improvements 📦 Modular Architecture - Separated concerns into focused modules: - hardware.sh - GPU detection & encoder selection - codec.sh - Codec & container options - quality.sh - Quality modes & bitrate control - filters.sh - Resolution, FPS, color correction - encode.sh - FFmpeg execution & monitoring ⚡ Performance Optimizations - Hardware benchmarking - Tests encoder speed before selection - Timeout protection - Prevents hanging during encoder tests - Better error reporting - Shows SUCCESS/FAILED/NOT AVAILABLE status - Improved timing logic - Cross-platform compatible timing 🖥️ User Experience - Two-stage workflow - Auto-detect → confirm/override - Clear menu navigation - Numbered options with validation - Real-time feedback - Shows what's being tested/selected - Fixed input validation - Proper regex for multi-digit numbers 🐛 Bug Fixes - Fixed unsharp filter - Corrected matrix size requirements (odd numbers only) - Fixed hue parameter - Corrected eq filter syntax - Fixed encoder detection - Improved hardware detection logic - Fixed menu display - Resolved command substitution output capture issues 🎯 Key Benefits - Full user control over encoding parameters - Hardware optimization with automatic fallbacks - Professional quality restoration options - Modular design for easy maintenance - Cross-platform compatibility (Windows/Linux)
This commit is contained in:
parent
2ff6726d1b
commit
fa6ff5aba1
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -22,3 +22,6 @@ scripts/git_converter/*.mov
|
|||
scripts/git_converter/*.wmv
|
||||
scripts/git_converter/*.ts
|
||||
scripts/git_converter/*.m2ts
|
||||
scripts/git_converter/git_converter.sh
|
||||
scripts/git_converter && cp -r modules EgitVideoToolsscriptsgit_converter
|
||||
scripts/git_converter/git_converter.sh
|
||||
|
|
|
|||
199
scripts/git_converter/README.md
Normal file
199
scripts/git_converter/README.md
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
# GIT Converter v2.7 - Setup Instructions
|
||||
|
||||
## Overview
|
||||
GIT Converter v2.7 is a modular video conversion tool with automatic hardware detection and optimization. It supports AV1 and HEVC encoding with various quality settings, color correction options, and smart upscaling.
|
||||
|
||||
## File Structure
|
||||
```
|
||||
git_converter/
|
||||
├── git_converter.sh # Main script
|
||||
├── modules/
|
||||
│ ├── hardware.sh # GPU detection & encoder selection
|
||||
│ ├── quality.sh # Quality settings & parameters
|
||||
│ ├── filters.sh # Scaling, color, FPS options
|
||||
│ └── encode.sh # Core ffmpeg execution
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. File Structure Setup
|
||||
- Ensure all files remain in the same directory structure
|
||||
- The `modules/` folder must be alongside the main script
|
||||
- Do not rename or move individual module files
|
||||
|
||||
### 2. Make Script Executable
|
||||
**Windows:**
|
||||
1. Right-click on `git_converter.sh`
|
||||
2. Properties → Permissions → "Allow executing file"
|
||||
3. Click OK
|
||||
|
||||
**Or in Git Bash:**
|
||||
```bash
|
||||
chmod +x git_converter.sh
|
||||
```
|
||||
|
||||
### 3. Dependencies
|
||||
- **FFmpeg** with encoder support (libx265, libsvtav1, hevc_amf, etc.)
|
||||
- **Git Bash** (for Windows users)
|
||||
- **GPU Drivers** (NVIDIA, AMD, or Intel) for hardware acceleration
|
||||
|
||||
## Usage Methods
|
||||
|
||||
### Method 1: Double-Click (Batch Processing)
|
||||
1. **Double-click** `git_converter.sh`
|
||||
2. **Hardware detection** runs automatically:
|
||||
```
|
||||
Detecting hardware and optimal encoder...
|
||||
✓ AMD GPU detected
|
||||
Testing hevc_amf...
|
||||
hevc_amf: 0.8s
|
||||
✓ Selected: hevc_amf (fastest encoder)
|
||||
```
|
||||
3. **Follow menu prompts** for resolution, FPS, quality, and color correction
|
||||
4. **Processes all videos** in the same directory
|
||||
|
||||
### Method 2: Drag & Drop (Selective Processing)
|
||||
1. **Select video files** in Windows Explorer
|
||||
2. **Drag them onto** `git_converter.sh`
|
||||
3. **Same menu flow** as double-click method
|
||||
4. **Processes only dragged files**
|
||||
|
||||
## Menu Options
|
||||
|
||||
### Resolution Settings
|
||||
- **Source**: No upscaling (original resolution)
|
||||
- **720p/1080p/1440p/4K**: Fixed resolution upscaling
|
||||
- **2X/4X**: Relative upscaling (double/quadruple size)
|
||||
|
||||
### Scaling Algorithm (when upscaling)
|
||||
- **Bicubic**: Fast, good quality
|
||||
- **Lanczos**: Best quality, slower
|
||||
- **Bilinear**: Fastest, basic quality
|
||||
|
||||
### FPS Settings
|
||||
- **Original FPS**: Maintains source frame rate
|
||||
- **60 FPS**: Converts to smooth 60fps motion
|
||||
|
||||
### Quality Modes
|
||||
- **High Quality (CRF 18)**: Recommended balance
|
||||
- **Near-Lossless (CRF 16)**: Maximum quality
|
||||
- **Good Quality (CRF 20)**: Balanced size/quality
|
||||
- **Custom bitrate**: Manual bitrate control
|
||||
|
||||
### Color Correction Options
|
||||
1. **No correction**: Original colors
|
||||
2. **Pink skin tones**: Fixes Topaz AI color loss
|
||||
3. **Warm boost**: Increases warmth
|
||||
4. **Cool boost**: Increases cool tones
|
||||
5. **2000s DVD Restore**: Fixes DVD degradation
|
||||
6. **90s Quality Restore**: Restores 90s media
|
||||
7. **VHS Quality Restore**: Repairs VHS degradation
|
||||
8. **Anime Preservation**: Protects anime art style
|
||||
|
||||
## Hardware Detection
|
||||
|
||||
The script automatically detects and tests:
|
||||
- **NVIDIA GPUs**: Uses NVENC encoders
|
||||
- **AMD GPUs**: Uses AMF encoders
|
||||
- **Intel GPUs**: Uses Quick Sync Video
|
||||
- **No GPU**: Uses optimized CPU encoders
|
||||
|
||||
### Encoder Priority
|
||||
1. **Hardware encoders** (GPU acceleration)
|
||||
2. **SVT-AV1** (fast CPU encoding)
|
||||
3. **libx265** (fallback CPU encoding)
|
||||
|
||||
## Output Structure
|
||||
|
||||
### Converted Folder
|
||||
- Automatically created in script directory
|
||||
- Contains all converted files
|
||||
- Original files remain untouched
|
||||
|
||||
### File Naming Convention
|
||||
```
|
||||
[original_name]_[fps]_[color]__cv.[extension]
|
||||
|
||||
Examples:
|
||||
- vacation.mp4 → vacation__cv.mkv
|
||||
- wedding.mp4 → wedding_60fps__cv.mkv
|
||||
- old_tape.avi → old_tape_vhsrestore__cv.mkv
|
||||
- anime.mkv → anime_anime__cv.mkv
|
||||
```
|
||||
|
||||
## Performance Features
|
||||
|
||||
### Optimizations
|
||||
- **Hardware detection**: Uses fastest available encoder
|
||||
- **Modular loading**: Faster startup, less memory
|
||||
- **CRF encoding**: Consistent quality vs variable bitrate
|
||||
- **Smart filter chains**: Proper ffmpeg parameter ordering
|
||||
|
||||
### Quality Settings
|
||||
- **AV1**: Best compression, smaller files
|
||||
- **HEVC**: Faster encoding, good compression
|
||||
- **CRF 16-22**: Near-lossless to balanced quality
|
||||
- **GPU acceleration**: 10x+ faster than CPU encoding
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### "No video files found"
|
||||
- **Cause**: Script folder contains no supported videos
|
||||
- **Solution**: Move script to folder with videos or drag files onto it
|
||||
|
||||
#### "No working encoder found"
|
||||
- **Cause**: FFmpeg missing encoder support
|
||||
- **Solution**: Install GPU drivers or rebuild FFmpeg with encoder support
|
||||
|
||||
#### "Failed to process"
|
||||
- **Cause**: Permission issues, disk space, or corrupted file
|
||||
- **Solution**: Check file permissions and available disk space
|
||||
|
||||
#### Slow encoding (0.1 FPS)
|
||||
- **Cause**: Using slow CPU encoder (libaom-av1)
|
||||
- **Solution**: Script auto-selects fastest encoder, ensure GPU drivers are installed
|
||||
|
||||
### Supported Formats
|
||||
- **Input**: MP4, MKV, MOV, AVI, WMV, TS, M2TS
|
||||
- **Output**: MKV (recommended) or MP4
|
||||
- **Codecs**: AV1, HEVC (H.265)
|
||||
|
||||
### Performance Tips
|
||||
- **For quality**: Use Lanczos scaling + CRF 16-18
|
||||
- **For speed**: Use Bicubic scaling + CRF 20
|
||||
- **For storage**: Use HEVC + CRF 20-22
|
||||
- **For old content**: Use appropriate color correction option
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Keyboard Shortcuts
|
||||
- **Enter**: Confirm selections
|
||||
- **Numbers**: Quick menu selection
|
||||
- **Ctrl+C**: Cancel script
|
||||
|
||||
### Custom Workflows
|
||||
- **Topaz AI videos**: Use "Pink skin tones" correction
|
||||
- **DVD content**: Use "2000s DVD Restore"
|
||||
- **Anime**: Use "Anime Preservation" mode
|
||||
- **Family videos**: Use "Warm color boost"
|
||||
|
||||
### Batch Processing
|
||||
- Place multiple videos in same folder
|
||||
- Double-click script for batch conversion
|
||||
- All files processed with same settings
|
||||
|
||||
## Version Information
|
||||
- **Version**: v2.7 Modular Edition
|
||||
- **Author**: LeakTechnologies
|
||||
- **Release**: December 2025
|
||||
- **Architecture**: Modular for performance optimization
|
||||
|
||||
## Support
|
||||
For issues or feature requests, ensure:
|
||||
1. All files in correct directory structure
|
||||
2. FFmpeg properly installed with encoder support
|
||||
3. GPU drivers up to date (if using hardware acceleration)
|
||||
4. Sufficient disk space for output files
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# GIT Converter — FINAL — 1080p FORCED + 60 FPS FIXED
|
||||
# Author: LeakTechnologies
|
||||
# ===================================================================
|
||||
|
||||
OUT="Converted"
|
||||
mkdir -p "$OUT"
|
||||
|
||||
# Choose best available encoder with runtime check
|
||||
pick_encoder() {
|
||||
# candidate list in order of preference
|
||||
local candidates=("$@")
|
||||
for enc in "${candidates[@]}"; do
|
||||
# Quick runtime probe: attempt tiny encode and discard output
|
||||
if ffmpeg -hide_banner -loglevel error \
|
||||
-f lavfi -i color=size=16x16:rate=1 -frames:v 1 \
|
||||
-c:v "$enc" -f null - >/dev/null 2>&1; then
|
||||
echo "$enc"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
clear
|
||||
cat << "EOF"
|
||||
|
||||
╔═══════════════════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ GIT Converter (December 2025) ║
|
||||
║ by LeakTechnologies ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
EOF
|
||||
|
||||
# — Resolution —
|
||||
echo " Choose your resolution:"
|
||||
echo
|
||||
echo " 1) Source file resolution (no upscale)"
|
||||
echo " 2) 720p (1280×720)"
|
||||
echo " 3) 1080p (1920×1080)"
|
||||
echo " 4) 1440p (2560×1440)"
|
||||
echo " 5) 4K (3840×2160)"
|
||||
echo " 6) 2X Upscale"
|
||||
echo " 7) 4X Upscale"
|
||||
echo
|
||||
read -p " Enter 1–7 → " res
|
||||
|
||||
case $res in
|
||||
1) scale="" ; res_name="Source" ;;
|
||||
2) scale="1280:720" ; res_name="720p" ;;
|
||||
3) scale="1920:1080" ; res_name="1080p" ;;
|
||||
4) scale="2560:1440" ; res_name="1440p" ;;
|
||||
5) scale="3840:2160" ; res_name="4K" ;;
|
||||
6) scale="iw*2:ih*2" ; res_name="2X" ;;
|
||||
7) scale="iw*4:ih*4" ; res_name="4X" ;;
|
||||
*) echo "Invalid — using 1080p"; scale="1920:1080"; res_name="1080p" ;;
|
||||
esac
|
||||
|
||||
# — Codec + FPS + Container —
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose codec + FPS ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) [MKV] AV1_AMF — Original FPS
|
||||
2) [MKV] HEVC — Original FPS
|
||||
3) [MKV] AV1_AMF — 60 FPS
|
||||
4) [MKV] HEVC — 60 FPS
|
||||
5) [MP4] HEVC — Original FPS
|
||||
6) [MP4] HEVC — 60 FPS
|
||||
EOF
|
||||
echo
|
||||
read -p " Enter 1–6 → " c
|
||||
|
||||
case $c in
|
||||
1|3) codec_pref=("av1_amf" "libaom-av1") ;;
|
||||
2|4|5|6) codec_pref=("hevc_amf" "hevc_nvenc" "h264_nvenc" "libx265") ;;
|
||||
*) echo "Invalid — exiting"; sleep 3; exit ;;
|
||||
esac
|
||||
|
||||
case $c in
|
||||
1|2|3|4) ext="mkv" ;;
|
||||
5|6) ext="mp4" ;;
|
||||
esac
|
||||
|
||||
case $c in
|
||||
3|4|6) fps_filter=",fps=60"; suf="_60fps" ;;
|
||||
*) fps_filter=""; suf="" ;;
|
||||
esac
|
||||
|
||||
# Resolve encoder now, once
|
||||
codec=$(pick_encoder "${codec_pref[@]}")
|
||||
if [ -z "$codec" ]; then
|
||||
echo "No supported encoder found (tried: ${codec_pref[*]})."
|
||||
echo "Install/enable GPU drivers or fall back to CPU codecs."
|
||||
echo "Defaulting to libx265."
|
||||
codec="libx265"
|
||||
fi
|
||||
|
||||
# — Bitrate Selection —
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose bitrate ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) 1800 kbps
|
||||
2) 2000 kbps
|
||||
3) 2300 kbps
|
||||
4) 2600 kbps
|
||||
5) 2900 kbps
|
||||
6) 3200 kbps
|
||||
7) 3500 kbps
|
||||
8) 3800 kbps
|
||||
9) Source file bitrate
|
||||
EOF
|
||||
echo
|
||||
read -p " Enter 1–9 → " b
|
||||
|
||||
case $b in
|
||||
1) BITRATE="1800k" ;;
|
||||
2) BITRATE="2000k" ;;
|
||||
3) BITRATE="2300k" ;;
|
||||
4) BITRATE="2600k" ;;
|
||||
5) BITRATE="2900k" ;;
|
||||
6) BITRATE="3200k" ;;
|
||||
7) BITRATE="3500k" ;;
|
||||
8) BITRATE="3800k" ;;
|
||||
9) BITRATE="source" ;;
|
||||
*) BITRATE="2400k"; echo "Invalid → using default 2400k" ;;
|
||||
esac
|
||||
|
||||
# Force 8-bit input
|
||||
bitdepth_filter="-pix_fmt yuv420p"
|
||||
|
||||
echo
|
||||
echo "Encoding → $codec | $res_name | $ext $suf @ ${BITRATE:-source} kbps"
|
||||
echo
|
||||
|
||||
for f in *.mp4 *.mkv *.mov *.avi *.wmv *.ts *.m2ts; do
|
||||
[[ -f "$f" ]] || continue
|
||||
|
||||
out="$OUT/${f%.*}${suf}__cv.$ext"
|
||||
[[ -f "$out" ]] && { echo "SKIP $f"; continue; }
|
||||
|
||||
# Source bitrate if chosen
|
||||
if [ "$BITRATE" = "source" ]; then
|
||||
src_bitrate=$(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of csv=p=0 "$f" 2>/dev/null || echo 2400000)
|
||||
this_bitrate=$(( src_bitrate / 1000 ))k
|
||||
else
|
||||
this_bitrate="$BITRATE"
|
||||
fi
|
||||
|
||||
# FINAL FIXED CONVERSION — 1080p FORCED + 60fps works
|
||||
if ffmpeg -y -i "$f" $bitdepth_filter -vf "scale=${scale}:flags=lanczos${fps_filter}" \
|
||||
-c:v "$codec" -b:v "$this_bitrate" -c:a aac -b:a 192k -ac 2 "$out"; then
|
||||
echo "DONE → $(basename "$out")"
|
||||
else
|
||||
echo "FAILED → $f (encoder: $codec). Check ffmpeg output above."
|
||||
rm -f "$out"
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
echo "========================================================"
|
||||
echo "All finished — files in '$OUT'"
|
||||
echo "========================================================"
|
||||
read -p "Press Enter to exit"
|
||||
378
scripts/git_converter/lt-convert.sh
Normal file
378
scripts/git_converter/lt-convert.sh
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# LT Converter v3.0 — Professional Edition (December 2025)
|
||||
# Author: LeakTechnologies
|
||||
# Fixed: Converted folder always created in script directory
|
||||
# Fixed: Filter chaining, input validation, bitrate handling
|
||||
# ===================================================================
|
||||
|
||||
# Force window size in Git Bash on Windows
|
||||
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
||||
printf '\e[8;45;100t'
|
||||
fi
|
||||
|
||||
# Get the directory where the script is located
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Always create Converted folder in the script's directory
|
||||
OUT="$SCRIPT_DIR/Converted"
|
||||
mkdir -p "$OUT"
|
||||
|
||||
# Detect optimal encoder at startup
|
||||
optimal_encoder=$(detect_hardware)
|
||||
|
||||
# Hardware detection and encoder selection
|
||||
detect_hardware() {
|
||||
echo "Detecting hardware and optimal encoder..."
|
||||
|
||||
# Detect GPU type
|
||||
gpu_type="none"
|
||||
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
|
||||
gpu_type="nvidia"
|
||||
echo " ✓ NVIDIA GPU detected"
|
||||
elif lspci 2>/dev/null | grep -iq "amd\|radeon"; then
|
||||
gpu_type="amd"
|
||||
echo " ✓ AMD GPU detected"
|
||||
elif lspci 2>/dev/null | grep -iq "intel.*vga\|intel.*display"; then
|
||||
gpu_type="intel"
|
||||
echo " ✓ Intel GPU detected"
|
||||
else
|
||||
echo " ⚠ No GPU detected, will use CPU encoding"
|
||||
fi
|
||||
|
||||
# Test encoder availability and speed
|
||||
local best_encoder=""
|
||||
local best_time=999999
|
||||
|
||||
# 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
|
||||
|
||||
# Quick benchmark each encoder
|
||||
for enc in "${candidates[@]}"; do
|
||||
if ffmpeg -hide_banner -loglevel error -encoders | grep -q "$enc"; then
|
||||
echo " Testing $enc..."
|
||||
start_time=$(date +%s.%N)
|
||||
if ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=2:size=320x240:rate=1" \
|
||||
-c:v "$enc" -f null - >/dev/null 2>&1; then
|
||||
end_time=$(date +%s.%N)
|
||||
test_time=$(echo "$end_time - $start_time" | bc -l 2>/dev/null || echo "1")
|
||||
echo " $enc: ${test_time}s"
|
||||
if (( $(echo "$test_time < $best_time" | bc -l 2>/dev/null || echo "0") )); then
|
||||
best_time=$test_time
|
||||
best_encoder=$enc
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$best_encoder" ]]; then
|
||||
echo " ✓ Selected: $best_encoder (fastest encoder)"
|
||||
echo "$best_encoder"
|
||||
return 0
|
||||
else
|
||||
echo " ⚠ No working encoder found, defaulting to libx265"
|
||||
echo "libx265"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
clear
|
||||
cat << "EOF"
|
||||
|
||||
╔═══════════════════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ LT Converter v3.0 (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
|
||||
|
||||
# — Resolution —
|
||||
echo " Choose your resolution:"
|
||||
echo
|
||||
echo " 1) Source file resolution (no upscale)"
|
||||
echo " 2) 720p (1280×720)"
|
||||
echo " 3) 1080p (1920×1080)"
|
||||
echo " 4) 1440p (2560×1440)"
|
||||
echo " 5) 4K (3840×2160)"
|
||||
echo " 6) 2X Upscale"
|
||||
echo " 7) 4X Upscale"
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–7 → " res
|
||||
if [[ -n "$res" && "$res" =~ ^[1-7]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 7."
|
||||
fi
|
||||
done
|
||||
|
||||
case $res in
|
||||
1) scale="" ; res_name="Source" ;;
|
||||
2) scale="1280:720" ; res_name="720p" ;;
|
||||
3) scale="1920:1080" ; res_name="1080p" ;;
|
||||
4) scale="2560:1440" ; res_name="1440p" ;;
|
||||
5) scale="3840:2160" ; res_name="4K" ;;
|
||||
6) scale="iw*2:ih*2" ; res_name="2X" ;;
|
||||
7) scale="iw*4:ih*4" ; res_name="4X" ;;
|
||||
esac
|
||||
|
||||
# — Scaling Algorithm (only if upscaling) —
|
||||
if [[ -n "$scale" ]]; then
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose Scaling Algorithm ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) Bicubic (fast, good quality)
|
||||
2) Lanczos (best quality, slower)
|
||||
3) Bilinear (fastest, basic quality)
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–3 → " scale_opt
|
||||
if [[ -n "$scale_opt" && "$scale_opt" =~ ^[1-3]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 3."
|
||||
fi
|
||||
done
|
||||
|
||||
case $scale_opt in
|
||||
1) scale_flags="bicubic" ;;
|
||||
2) scale_flags="lanczos" ;;
|
||||
3) scale_flags="bilinear" ;;
|
||||
esac
|
||||
else
|
||||
scale_flags="lanczos" # Default for consistency
|
||||
fi
|
||||
|
||||
# — Encoding Options —
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═════════════════════════════════════════════════════════════╗
|
||||
║ Encoding Options ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
Auto-detected encoder: $optimal_encoder
|
||||
|
||||
1) Original FPS
|
||||
2) 60 FPS
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–2 → " c
|
||||
if [[ -n "$c" && "$c" =~ ^[1-2]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter 1 or 2."
|
||||
fi
|
||||
done
|
||||
|
||||
# Set container and FPS
|
||||
ext="mkv"
|
||||
fps_filter=""
|
||||
suf=""
|
||||
if [[ "$c" == "2" ]]; then
|
||||
fps_filter="fps=60"
|
||||
suf="_60fps"
|
||||
fi
|
||||
|
||||
# Use auto-detected encoder
|
||||
codec="$optimal_encoder"
|
||||
|
||||
# — Color Correction Option —
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Color Correction Option ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) No color correction
|
||||
2) Restore pink skin tones (Topaz AI fix)
|
||||
3) Warm color boost
|
||||
4) Cool color boost
|
||||
5) 2000s DVD Restore
|
||||
6) 90s Quality Restore
|
||||
7) VHS Quality Restore
|
||||
8) Anime Preservation (clean lines & colors)
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–8 → " color_opt
|
||||
if [[ -n "$color_opt" && "$color_opt" =~ ^[1-8]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 8."
|
||||
fi
|
||||
done
|
||||
|
||||
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" ;;
|
||||
esac
|
||||
|
||||
# — Quality Selection —
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose Quality Mode ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) High Quality AV1 (CRF 18) - Best compression
|
||||
2) High Quality HEVC (CRF 18) - Fast encoding
|
||||
3) Near-Lossless AV1 (CRF 16) - Maximum quality
|
||||
4) Near-Lossless HEVC (CRF 16) - Quality/Speed balance
|
||||
5) Custom bitrate
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
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 5."
|
||||
fi
|
||||
done
|
||||
|
||||
# Set quality parameters based on auto-detected encoder
|
||||
case $b in
|
||||
1)
|
||||
if [[ "$codec" == *"av1"* ]]; then
|
||||
quality_params="-crf 18 -preset 6"
|
||||
quality_name="AV1 CRF 18"
|
||||
else
|
||||
quality_params="-crf 18 -quality 23"
|
||||
quality_name="HEVC CRF 18"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [[ "$codec" == *"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
|
||||
;;
|
||||
3)
|
||||
echo
|
||||
echo "Enter bitrate (e.g., 5000k, 8000k):"
|
||||
read -p "→ " custom_bitrate
|
||||
if [[ -n "$custom_bitrate" ]]; then
|
||||
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
|
||||
|
||||
# Force 8-bit input with performance optimization
|
||||
bitdepth_filter="-pix_fmt yuv420p -movflags +faststart"
|
||||
|
||||
echo
|
||||
echo "Encoding → $codec | $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
|
||||
shopt -s nullglob
|
||||
video_files=(*.mp4 *.mkv *.mov *.avi *.wmv *.ts *.m2ts)
|
||||
shopt -u nullglob
|
||||
|
||||
if [[ ${#video_files[@]} -eq 0 ]]; then
|
||||
echo "No video files found in current directory."
|
||||
read -p "Press Enter to exit"
|
||||
exit 0
|
||||
fi
|
||||
echo "Processing all video files in current directory: ${#video_files[@]} file(s)"
|
||||
fi
|
||||
|
||||
for f in "${video_files[@]}"; do
|
||||
[[ -f "$f" ]] || continue
|
||||
|
||||
# Extract basename for output filename (handles both relative and absolute paths)
|
||||
basename_f=$(basename "$f")
|
||||
out="$OUT/${basename_f%.*}${suf}${color_suf}__cv.$ext"
|
||||
[[ -f "$out" ]] && { echo "SKIP $f (already exists)"; continue; }
|
||||
|
||||
# Build filter chain
|
||||
filter_chain=""
|
||||
if [[ -n "$scale" ]]; then
|
||||
filter_chain="scale=${scale}:flags=${scale_flags}"
|
||||
fi
|
||||
|
||||
if [[ -n "$fps_filter" ]]; then
|
||||
if [[ -n "$filter_chain" ]]; then
|
||||
filter_chain="${filter_chain},${fps_filter}"
|
||||
else
|
||||
filter_chain="$fps_filter"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$color_filter" ]]; then
|
||||
if [[ -n "$filter_chain" ]]; then
|
||||
filter_chain="${filter_chain},${color_filter}"
|
||||
else
|
||||
filter_chain="$color_filter"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Processing: $f → $(basename "$out")"
|
||||
|
||||
# Build optimized ffmpeg command
|
||||
if [[ -n "$filter_chain" ]]; then
|
||||
ffmpeg -y -i "$f" -pix_fmt yuv420p -vf "$filter_chain" \
|
||||
-c:v "$codec" $quality_params -c:a aac -b:a 192k -ac 2 "$out"
|
||||
else
|
||||
ffmpeg -y -i "$f" -pix_fmt yuv420p \
|
||||
-c:v "$codec" $quality_params -c:a aac -b:a 192k -ac 2 "$out"
|
||||
fi
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "DONE → $(basename "$out")"
|
||||
else
|
||||
echo "ERROR → Failed to process $f"
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
echo "========================================================"
|
||||
echo "All finished — files in '$OUT'"
|
||||
echo "========================================================"
|
||||
read -p "Press Enter to exit"
|
||||
83
scripts/git_converter/modules/codec.sh
Normal file
83
scripts/git_converter/modules/codec.sh
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/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"
|
||||
|
||||
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
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter 1 or 2."
|
||||
fi
|
||||
done
|
||||
|
||||
case $container_choice in
|
||||
1) ext="mkv" ;;
|
||||
2) ext="mp4" ;;
|
||||
esac
|
||||
else
|
||||
ext="mkv" # Default fallback
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# Export variables for main script
|
||||
echo "$final_encoder"
|
||||
echo "$ext"
|
||||
}
|
||||
102
scripts/git_converter/modules/encode.sh
Normal file
102
scripts/git_converter/modules/encode.sh
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# Optimized Encoding Module - GIT Converter v2.7
|
||||
# Maximum speed, lossless quality encoding
|
||||
# ===================================================================
|
||||
|
||||
encode_video() {
|
||||
local input_file="$1"
|
||||
local output_file="$2"
|
||||
local encoder="$3"
|
||||
local quality_params="$4"
|
||||
local filter_chain="$5"
|
||||
|
||||
echo "Processing: $input_file → $(basename "$output_file")"
|
||||
|
||||
# Optimized ffmpeg command for maximum speed
|
||||
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 \
|
||||
-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"
|
||||
fi
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "DONE → $(basename "$output_file")"
|
||||
return 0
|
||||
else
|
||||
echo "ERROR → Failed to process $input_file"
|
||||
return 1
|
||||
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"
|
||||
local quality_params="$2"
|
||||
local filter_chain="$3"
|
||||
local suf="$4"
|
||||
local color_suf="$5"
|
||||
local ext="$6"
|
||||
|
||||
for f in "${video_files[@]}"; do
|
||||
[[ -f "$f" ]] || continue
|
||||
|
||||
# Extract basename for output filename
|
||||
basename_f=$(basename "$f")
|
||||
out="$OUT/${basename_f%.*}${suf}${color_suf}__cv.$ext"
|
||||
[[ -f "$out" ]] && { echo "SKIP $f (already exists)"; continue; }
|
||||
|
||||
encode_video "$f" "$out" "$encoder" "$quality_params" "$filter_chain"
|
||||
echo
|
||||
done
|
||||
}
|
||||
164
scripts/git_converter/modules/filters.sh
Normal file
164
scripts/git_converter/modules/filters.sh
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# Filters Module - GIT Converter v2.7
|
||||
# Handles scaling, color correction, and FPS
|
||||
# ===================================================================
|
||||
|
||||
get_resolution_settings() {
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose Resolution ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) Source file resolution (no upscale)
|
||||
2) 720p (1280×720)
|
||||
3) 1080p (1920×1080)
|
||||
4) 1440p (2560×1440)
|
||||
5) 4K (3840×2160)
|
||||
6) 2X Upscale
|
||||
7) 4X Upscale
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–7 → " res
|
||||
if [[ -n "$res" && "$res" =~ ^[1-7]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 7."
|
||||
fi
|
||||
done
|
||||
|
||||
case $res in
|
||||
1) scale="" ; res_name="Source" ;;
|
||||
2) scale="1280:720" ; res_name="720p" ;;
|
||||
3) scale="1920:1080" ; res_name="1080p" ;;
|
||||
4) scale="2560:1440" ; res_name="1440p" ;;
|
||||
5) scale="3840:2160" ; res_name="4K" ;;
|
||||
6) scale="iw*2:ih*2" ; res_name="2X" ;;
|
||||
7) scale="iw*4:ih*4" ; res_name="4X" ;;
|
||||
esac
|
||||
|
||||
# Scaling algorithm choice (only if upscaling)
|
||||
if [[ -n "$scale" ]]; then
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose Scaling Algorithm ║
|
||||
╚═════════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) Bicubic (fast, good quality)
|
||||
2) Lanczos (best quality, slower)
|
||||
3) Bilinear (fastest, basic quality)
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–3 → " scale_opt
|
||||
if [[ -n "$scale_opt" && "$scale_opt" =~ ^[1-3]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 3."
|
||||
fi
|
||||
done
|
||||
|
||||
case $scale_opt in
|
||||
1) scale_flags="bicubic" ;;
|
||||
2) scale_flags="lanczos" ;;
|
||||
3) scale_flags="bilinear" ;;
|
||||
esac
|
||||
else
|
||||
scale_flags="lanczos"
|
||||
fi
|
||||
}
|
||||
|
||||
get_fps_settings() {
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Choose FPS Mode ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) Original FPS
|
||||
2) 60 FPS
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–2 → " fps_choice
|
||||
if [[ -n "$fps_choice" && "$fps_choice" =~ ^[1-2]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter 1 or 2."
|
||||
fi
|
||||
done
|
||||
|
||||
case $fps_choice in
|
||||
2) fps_filter="fps=60"; suf="_60fps" ;;
|
||||
*) fps_filter=""; suf="" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_color_correction() {
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Color Correction Option ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) No color correction
|
||||
2) Restore pink skin tones (Topaz AI fix)
|
||||
3) Warm color boost
|
||||
4) Cool color boost
|
||||
5) 2000s DVD Restore
|
||||
6) 90s Quality Restore
|
||||
7) VHS Quality Restore
|
||||
8) Anime Preservation (clean lines & colors)
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–8 → " color_opt
|
||||
if [[ -n "$color_opt" && "$color_opt" =~ ^[1-8]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 8."
|
||||
fi
|
||||
done
|
||||
|
||||
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" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
build_filter_chain() {
|
||||
filter_chain=""
|
||||
|
||||
if [[ -n "$scale" ]]; then
|
||||
filter_chain="scale=${scale}:flags=${scale_flags}"
|
||||
fi
|
||||
|
||||
if [[ -n "$fps_filter" ]]; then
|
||||
if [[ -n "$filter_chain" ]]; then
|
||||
filter_chain="${filter_chain},${fps_filter}"
|
||||
else
|
||||
filter_chain="$fps_filter"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$color_filter" ]]; then
|
||||
if [[ -n "$filter_chain" ]]; then
|
||||
filter_chain="${filter_chain},${color_filter}"
|
||||
else
|
||||
filter_chain="$color_filter"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
82
scripts/git_converter/modules/hardware.sh
Normal file
82
scripts/git_converter/modules/hardware.sh
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# Hardware Detection Module - GIT Converter v2.7
|
||||
# Optimized GPU and encoder detection
|
||||
# ===================================================================
|
||||
|
||||
detect_hardware() {
|
||||
echo "Detecting hardware and optimal encoder..." >&2
|
||||
|
||||
# Detect GPU type
|
||||
gpu_type="none"
|
||||
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
|
||||
gpu_type="nvidia"
|
||||
echo " ✓ NVIDIA GPU detected" >&2
|
||||
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
|
||||
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
|
||||
else
|
||||
echo " ⚠ No GPU detected, will use CPU encoding" >&2
|
||||
fi
|
||||
|
||||
# Test encoder availability and speed
|
||||
local best_encoder=""
|
||||
local best_time=999999
|
||||
|
||||
# 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
|
||||
|
||||
# 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.%N)
|
||||
if ffmpeg -hide_banner -loglevel error -y -f lavfi -i "testsrc=duration=2:size=320x240:rate=1" \
|
||||
-c:v "$enc" -f null - >/dev/null 2>&1; then
|
||||
end_time=$(date +%s.%N)
|
||||
test_time=$(echo "$end_time - $start_time" | bc -l 2>/dev/null || echo "1")
|
||||
echo " $enc: ${test_time}s" >&2
|
||||
if (( $(echo "$test_time < $best_time" | bc -l 2>/dev/null || echo "0") )); then
|
||||
best_time=$test_time
|
||||
best_encoder=$enc
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
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
|
||||
}
|
||||
157
scripts/git_converter/modules/quality.sh
Normal file
157
scripts/git_converter/modules/quality.sh
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#!/bin/bash
|
||||
# ===================================================================
|
||||
# Optimized Quality Settings Module - GIT Converter v2.7
|
||||
# Encoder-specific optimal parameters for maximum speed
|
||||
# ===================================================================
|
||||
|
||||
get_quality_settings() {
|
||||
local encoder="$1"
|
||||
|
||||
clear
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════════════════════════════════╗
|
||||
║ Choose Quality Mode ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
1) Near-Lossless (CRF 16) - Maximum quality
|
||||
2) High Quality (CRF 18) - Recommended
|
||||
3) Good Quality (CRF 20) - Balanced
|
||||
4) Custom bitrate
|
||||
EOF
|
||||
echo
|
||||
|
||||
while true; do
|
||||
read -p " Enter 1–4 → " b
|
||||
if [[ -n "$b" && "$b" =~ ^[1-4]$ ]]; then
|
||||
break
|
||||
else
|
||||
echo " Invalid input. Please enter a number between 1 and 4."
|
||||
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}"
|
||||
;;
|
||||
*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
|
||||
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_name="HEVC CRF 18"
|
||||
fi
|
||||
else
|
||||
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 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
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user