Last active
August 21, 2025 13:33
-
-
Save raghavmri/f901b3ff0daee01165285587f84b40e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -euo pipefail | |
# --- Helper: detect package manager --- | |
detect_pkg_mgr() { | |
if command -v apt-get &>/dev/null; then echo "apt-get" | |
elif command -v yum &>/dev/null; then echo "yum" | |
elif command -v dnf &>/dev/null; then echo "dnf" | |
elif command -v pacman &>/dev/null; then echo "pacman" | |
elif command -v zypper &>/dev/null; then echo "zypper" | |
else echo "unknown"; fi | |
} | |
# --- Helper: ensure a command exists --- | |
ensure_command() { | |
local cmd="$1"; local pkg="$2" | |
if command -v "$cmd" &>/dev/null; then return 0; fi | |
echo "$cmd not found. Attempting to install..." | |
PKG_MGR="$(detect_pkg_mgr)" | |
case "$PKG_MGR" in | |
apt-get) sudo apt-get update && sudo apt-get install -y "$pkg" ;; | |
yum) sudo yum install -y "$pkg" ;; | |
dnf) sudo dnf install -y "$pkg" ;; | |
pacman) sudo pacman -Sy --noconfirm "$pkg" ;; | |
zypper) sudo zypper install -y "$pkg" ;; | |
*) echo "Could not detect package manager. Please install $cmd manually." >&2; exit 1 ;; | |
esac | |
} | |
# Ensure ffmpeg exists | |
ensure_command ffmpeg ffmpeg | |
# Detect CPU count | |
if command -v nproc &>/dev/null; then | |
MAX_PROCS=$(nproc) | |
elif [ -f /proc/cpuinfo ]; then | |
MAX_PROCS=$(grep -c '^processor' /proc/cpuinfo) | |
else | |
MAX_PROCS=4 | |
fi | |
echo "Using $MAX_PROCS parallel jobs." | |
# Output directory (absolute path) | |
CONVERTED_DEST="$(pwd)/m4a_outputs" | |
mkdir -p "$CONVERTED_DEST" | |
echo "Output directory: $CONVERTED_DEST" | |
# Create log directory | |
LOG_DIR="$(pwd)/conversion_logs" | |
mkdir -p "$LOG_DIR" | |
echo "Log directory: $LOG_DIR" | |
# Find MP4 files first | |
echo "Searching for MP4 files..." | |
MP4_FILES="$(mktemp)" | |
find "." -type f -iname '*.mp4' > "$MP4_FILES" | |
FILE_COUNT=$(wc -l < "$MP4_FILES") | |
if [ "$FILE_COUNT" -eq 0 ]; then | |
echo "No MP4 files found in current directory and subdirectories." | |
rm -f "$MP4_FILES" | |
exit 0 | |
fi | |
echo "Found $FILE_COUNT MP4 files to convert:" | |
cat "$MP4_FILES" | |
echo "====================" | |
# Create results file | |
RESULTS="$(mktemp)" | |
echo "Starting parallel conversion..." | |
# Process files with better parallel handling | |
echo "Using xargs for processing..." | |
# Create a wrapper script for the function | |
WRAPPER_SCRIPT="$(mktemp)" | |
cat > "$WRAPPER_SCRIPT" << 'EOF' | |
#!/bin/bash | |
file="$1" | |
CONVERTED_DEST="$2" | |
LOG_DIR="$3" | |
filename="$(basename "$file")" | |
base="${filename%.*}" | |
out="$CONVERTED_DEST/${base}.m4a" | |
log_file="$LOG_DIR/${base}.log" | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $file" | tee -a "$log_file" | |
# Check if input file exists and is readable | |
if [ ! -f "$file" ]; then | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: Input file not found: $file" | tee -a "$log_file" | |
echo "FAIL:$file:File not found" | |
exit 1 | |
fi | |
# Run ffmpeg with full logging | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Converting: $file -> $out" | tee -a "$log_file" | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Running: ffmpeg -i \"$file\" -vn -c:a aac -b:a 192k -y \"$out\"" | tee -a "$log_file" | |
if ffmpeg -i "$file" -vn -c:a aac -b:a 192k -y "$out" 2>&1 | tee -a "$log_file"; then | |
if [ -f "$out" ] && [ -s "$out" ]; then | |
local size=$(stat -f%z "$out" 2>/dev/null || stat -c%s "$out" 2>/dev/null || echo "unknown") | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✅ SUCCESS: $file -> $out (size: ${size} bytes)" | tee -a "$log_file" | |
echo "OK:$file:$out:$size" | |
else | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ FAILED: Output file is empty or missing: $out" | tee -a "$log_file" | |
echo "FAIL:$file:Output file empty or missing" | |
fi | |
else | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ FAILED: ffmpeg error for $file" | tee -a "$log_file" | |
echo "FAIL:$file:ffmpeg error" | |
fi | |
EOF | |
chmod +x "$WRAPPER_SCRIPT" | |
# Process files using the wrapper script | |
cat "$MP4_FILES" | head -5 | xargs -I {} -P "$MAX_PROCS" -n 1 "$WRAPPER_SCRIPT" {} "$CONVERTED_DEST" "$LOG_DIR" > "$RESULTS" 2>&1 | |
# Clean up wrapper script | |
rm -f "$WRAPPER_SCRIPT" | |
echo "Conversion jobs completed. Analyzing results..." | |
# Count results and show detailed summary | |
SUCCESS=0 | |
FAILED=0 | |
echo "" | |
echo "=== CONVERSION SUMMARY ===" | |
while IFS=: read -r status file rest; do | |
case "$status" in | |
"OK") | |
SUCCESS=$((SUCCESS + 1)) | |
echo "✅ $file" | |
;; | |
"FAIL") | |
FAILED=$((FAILED + 1)) | |
echo "❌ $file ($rest)" | |
;; | |
esac | |
done < "$RESULTS" | |
echo "" | |
echo "=== FINAL RESULTS ===" | |
echo "Successfully converted: $SUCCESS" | |
echo "Failed conversions: $FAILED" | |
echo "Total processed: $((SUCCESS + FAILED))" | |
# Show output directory contents | |
echo "" | |
echo "=== OUTPUT DIRECTORY CONTENTS ===" | |
if [ -d "$CONVERTED_DEST" ]; then | |
ls -la "$CONVERTED_DEST"/ || echo "Directory is empty" | |
else | |
echo "Output directory does not exist!" | |
fi | |
echo "" | |
echo "=== LOG FILES ===" | |
if [ -d "$LOG_DIR" ]; then | |
echo "Conversion logs available in: $LOG_DIR" | |
ls -la "$LOG_DIR"/ || echo "No log files found" | |
# Show last few lines of failed conversions | |
if [ "$FAILED" -gt 0 ]; then | |
echo "" | |
echo "=== SAMPLE ERROR LOGS ===" | |
for logfile in "$LOG_DIR"/*.log; do | |
if [ -f "$logfile" ] && grep -q "FAILED\|ERROR" "$logfile"; then | |
echo "--- Last 10 lines of $(basename "$logfile") ---" | |
tail -10 "$logfile" | |
echo "" | |
fi | |
done | |
fi | |
else | |
echo "Log directory does not exist!" | |
fi | |
# Cleanup temp files | |
rm -f "$MP4_FILES" "$RESULTS" | |
echo "All outputs are in: $CONVERTED_DEST" | |
echo "All logs are in: $LOG_DIR" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment