#!/bin/bash # Number of concurrent ffmpeg processes N=${1:-4} # Create a semaphore with a given number of slots semaphore=$(mktemp) exec 3<>$semaphore for ((i=0; i&3 done # Debugging function debug_log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $@" } # Run ffmpeg command with semaphore locking and delete .wav file on success run_ffmpeg() { local file=$1 local outfile="${file/%.wav/.opus}" # Wait for a slot to become available read -u 3 debug_log "Starting conversion: $file" if ffmpeg -i "$file" -y -c:a libopus -vbr on -compression_level 5 -ar 48000 -application audio "$outfile"; then debug_log "Completed conversion: $file" debug_log "Deleting original file: $file" rm "$file" else debug_log "Failed conversion: $file" fi # Release the slot echo >&3 } export -f run_ffmpeg export -f debug_log # Find all .wav files and convert them to .opus in parallel, respecting semaphore, and delete .wav files on success find . -maxdepth 1 -type f -name '*.wav' -print0 | xargs -0 -I {} -P $N bash -c 'run_ffmpeg "$@"' _ {} # Cleanup exec 3>&- rm -f $semaphore