Files
caveman/compress.bash
2026-01-07 12:19:00 +01:00

128 lines
3.6 KiB
Bash

#!/bin/bash
# =============================================================================
# Batch Audio Compressor - 96 kbps AAC
# Preserves folder structure, uses ffmpeg + GNU parallel + hardware acceleration
# =============================================================================
set -euo pipefail
# -------------------------------
# Configuration
# -------------------------------
SOURCE_DIR="${1:-./audio_source}"
OUTPUT_DIR="${2:-./audio_96kbps}"
LOG_FILE="./compression.log"
#NUM_JOBS="1"
NUM_JOBS="${PARALLEL_JOBS:-$(nproc)}" # Use all cores by default
# Supported input audio extensions (lowercase)
declare -a AUDIO_EXTS=("wav" "flac" "aiff" "aif" "mp3" "m4a" "ogg" "wma" "ac3" "alac")
# -------------------------------
# Functions
# -------------------------------
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
detect_hw_accel() {
echo "vdpau"
return
# Cuda?
if ffmpeg -hwaccels 2>/dev/null | grep -q cuda; then
echo "cuda"
# Try to detect available hardware acceleration
elif ffmpeg -hwaccels 2>/dev/null | grep -q vaapi; then
echo "vaapi"
elif ffmpeg -buildconf 2>&1 | grep -q "enable-vdpau"; then
echo "vdpau"
elif [[ "$(uname)" == "Darwin" ]] && ffmpeg -codecs 2>/dev/null | grep -q 'h264.* videotoolbox'; then
echo "videotoolbox"
else
echo "none"
fi
}
get_hw_args() {
local hw_accel="$1"
local input_file="$2"
case "$hw_accel" in
"vaapi")
echo "-vaapi_device /dev/dri/renderD128 -vf 'format=nv12,hwupload' -c:a aac -b:a 64k"
;;
"videotoolbox")
# Apple's VideoToolbox (macOS) — fast for H.264, less useful for audio, but can accelerate some codecs
# Note: Audio encoding isn't accelerated, but we include for completeness if video is present
echo "-c:a aac -b:a 64k -c:v h264_videotoolbox"
;;
*)
echo "-c:a libmp3lame -b:a 64k" # Fallback to software encoding
;;
esac
}
# -------------------------------
# Input validation
# -------------------------------
if [[ ! -d "$SOURCE_DIR" ]]; then
echo "Error: Source directory does not exist: $SOURCE_DIR"
echo "Usage: $0 <source_dir> <output_dir>"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
log "Starting compression of '$SOURCE_DIR' -> '$OUTPUT_DIR' at 96 kbps AAC"
log "Using $NUM_JOBS parallel jobs"
# -------------------------------
# Detect hardware acceleration
# -------------------------------
HW_ACCEL="$(detect_hw_accel)"
log "Hardware acceleration detected: $HW_ACCEL"
# -------------------------------
# Find all audio files and process them via parallel
# -------------------------------
# Export functions and variables for GNU parallel
export -f get_hw_args
export SOURCE_DIR
export OUTPUT_DIR
export HW_ACCEL
# Build find command for all audio extensions
find_cmd="find \"$SOURCE_DIR\" -type f \\( "
for ext in "${AUDIO_EXTS[@]}"; do
find_cmd+=" -iname \"*.${ext}\" -o"
done
# Replace trailing "-o" with "\\)"
find_cmd="${find_cmd% -o} \\)"
# Use eval to execute the dynamic find command and pipe to parallel
eval "$find_cmd" | sort | parallel -j"$NUM_JOBS" --progress --bar --joblog parallel_jobs.log --eta '
input_file="{}"
rel_path="${SOURCE_DIR:+${input_file#"$SOURCE_DIR"/}}"
output_file="'$OUTPUT_DIR'/${rel_path%.*}.mp3"
# Create output directory if needed
mkdir -p "$(dirname "$output_file")"
if [[ -f "$output_file" ]]; then
echo "Skipped (exists): $rel_path"
exit 0
fi
hw_args=$(get_hw_args "'$HW_ACCEL'" "$input_file")
ffmpeg -v warning -stats \
-i "$input_file" \
$hw_args \
-y "$output_file" \
&& echo "Converted: $rel_path"
'
log "Compression complete. Output saved to: $OUTPUT_DIR"