mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 01:26:46 +00:00
added dryrun
This commit is contained in:
@@ -4,15 +4,18 @@
|
|||||||
setopt ERR_EXIT NO_UNSET PIPE_FAIL
|
setopt ERR_EXIT NO_UNSET PIPE_FAIL
|
||||||
# set -x # Uncomment this line for debugging output
|
# set -x # Uncomment this line for debugging output
|
||||||
|
|
||||||
# --- FLAC to MP3 Converter (Zsh Script - find -exec) ---
|
# --- FLAC to MP3 Converter (Zsh Script - Recursive Globbing) ---
|
||||||
#
|
#
|
||||||
# This script converts all FLAC files found in a specified input directory
|
# This script converts all FLAC files found in a specified input directory
|
||||||
# and its subdirectories into MP3 files, saving them to a specified output directory
|
# and its subdirectories into MP3 files, saving them to a specified output directory
|
||||||
# while preserving the original directory structure.
|
# while preserving the original directory structure.
|
||||||
#
|
#
|
||||||
# Usage: ./convert_flac_to_mp3_find_exec.zsh <input_directory> <output_directory>
|
# Usage: ./convert_flac_to_mp3_zsh_glob.zsh [-d|--dry-run] <input_directory> <output_directory>
|
||||||
#
|
#
|
||||||
# Arguments:
|
# Arguments:
|
||||||
|
# -d, --dry-run : Optional. If present, the script will only show what
|
||||||
|
# it would do without actually performing conversions
|
||||||
|
# or creating directories.
|
||||||
# <input_directory> : The path to the directory containing FLAC files.
|
# <input_directory> : The path to the directory containing FLAC files.
|
||||||
# <output_directory> : The path where the converted MP3 files will be saved.
|
# <output_directory> : The path where the converted MP3 files will be saved.
|
||||||
#
|
#
|
||||||
@@ -21,9 +24,20 @@ setopt ERR_EXIT NO_UNSET PIPE_FAIL
|
|||||||
# - realpath: Must be installed and accessible in your system's PATH.
|
# - realpath: Must be installed and accessible in your system's PATH.
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# ./convert_flac_to_mp3_find_exec.zsh "/home/user/music/flac albums" "/home/user/music/mp3 converted"
|
# ./convert_flac_to_mp3_zsh_glob.zsh "/home/user/music/flac albums" "/home/user/music/mp3 converted"
|
||||||
|
# ./convert_flac_to_mp3_zsh_glob.zsh --dry-run "/home/user/music/flac albums" "/home/user/music/mp3 converted"
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Initialize dry run flag
|
||||||
|
local DRY_RUN=false
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
# Check for dry run flag
|
||||||
|
if [[ "$1" == "-d" || "$1" == "--dry-run" ]]; then
|
||||||
|
DRY_RUN=true
|
||||||
|
shift # Remove the flag from the arguments list
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if ffmpeg is installed
|
# Check if ffmpeg is installed
|
||||||
if ! command -v ffmpeg &> /dev/null; then
|
if ! command -v ffmpeg &> /dev/null; then
|
||||||
echo "Error: ffmpeg is not installed. Please install it to use this script."
|
echo "Error: ffmpeg is not installed. Please install it to use this script."
|
||||||
@@ -37,17 +51,18 @@ if ! command -v realpath &> /dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for correct number of arguments
|
# Check for correct number of remaining arguments
|
||||||
if [ "$#" -ne 2 ]; then
|
if [ "$#" -ne 2 ]; then
|
||||||
echo "Usage: $0 <input_directory> <output_directory>"
|
echo "Usage: $0 [-d|--dry-run] <input_directory> <output_directory>"
|
||||||
echo "Example: $0 /path/to/flac_files /path/to/mp3_output"
|
echo "Example: $0 /path/to/flac_files /path/to/mp3_output"
|
||||||
|
echo "Example (Dry Run): $0 --dry-run /path/to/flac_files /path/to/mp3_output"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Resolve input and output directories to their absolute, canonical paths.
|
# Resolve input and output directories to their absolute, canonical paths.
|
||||||
export INPUT_DIR=$(realpath "$1") # Export for the subshell
|
local INPUT_DIR=$(realpath "$1")
|
||||||
export OUTPUT_DIR=$(realpath "$2") # Export for the subshell
|
local OUTPUT_DIR=$(realpath "$2")
|
||||||
export INPUT_BASENAME=$(basename "$INPUT_DIR") # Export for the subshell
|
local INPUT_BASENAME=$(basename "$INPUT_DIR") # Base name of the input directory
|
||||||
|
|
||||||
# Check if resolved input directory exists
|
# Check if resolved input directory exists
|
||||||
if [ ! -d "$INPUT_DIR" ]; then
|
if [ ! -d "$INPUT_DIR" ]; then
|
||||||
@@ -55,46 +70,66 @@ if [ ! -d "$INPUT_DIR" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create the output directory if it doesn't exist.
|
# Create the output directory if it doesn't exist (only if not in dry run mode).
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "Dry Run: Would create output base directory '$OUTPUT_DIR' if it didn't exist."
|
||||||
|
else
|
||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Starting FLAC to MP3 conversion using find -exec..."
|
echo "Starting FLAC to MP3 conversion using Zsh globbing..."
|
||||||
echo "Input Directory (resolved): $INPUT_DIR"
|
echo "Input Directory (resolved): $INPUT_DIR"
|
||||||
echo "Output Directory (resolved): $OUTPUT_DIR"
|
echo "Output Directory (resolved): $OUTPUT_DIR"
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "--- DRY RUN MODE ACTIVE --- No files will be converted or directories created."
|
||||||
|
fi
|
||||||
echo "--------------------------------------------------"
|
echo "--------------------------------------------------"
|
||||||
|
|
||||||
# Define a helper function to be called by find -exec.
|
# Enable recursive globbing (globstar) and nullglob (handle no matches gracefully)
|
||||||
# This function will be executed in a new subshell for each file.
|
setopt GLOBSTAR NULL_GLOB
|
||||||
exec_convert_single_file() {
|
|
||||||
local FLAC_FILEPATH_CANONICAL=$(realpath "$1")
|
|
||||||
|
|
||||||
local RELATIVE_PATH=$(realpath --relative-to="$INPUT_DIR" "$FLAC_FILEPATH_CANONICAL")
|
# Loop through all FLAC files found recursively
|
||||||
local MP3_FILENAME="${RELATIVE_PATH%.flac}.mp3"
|
for FLAC_FILEPATH_CANONICAL in "${INPUT_DIR}"/**/*.flac; do
|
||||||
local OUTPUT_FILEPATH="${OUTPUT_DIR}/${INPUT_BASENAME}/${MP3_FILENAME}"
|
# Skip if the glob found no files (due to NULL_GLOB)
|
||||||
|
[[ -e "$FLAC_FILEPATH_CANONICAL" ]] || continue
|
||||||
|
|
||||||
mkdir -p "$(dirname "$OUTPUT_FILEPATH")"
|
# Calculate the relative path of the FLAC file from the input directory.
|
||||||
|
RELATIVE_PATH=$(realpath --relative-to="$INPUT_DIR" "$FLAC_FILEPATH_CANONICAL")
|
||||||
|
|
||||||
echo "Converting: '$FLAC_FILEPATH_CANONICAL'"
|
# Construct the output filename by replacing the .flac extension with .mp3.
|
||||||
echo "Saving to: '$OUTPUT_FILEPATH'"
|
MP3_FILENAME="${RELATIVE_PATH%.flac}.mp3"
|
||||||
|
|
||||||
|
# Construct the full output path
|
||||||
|
OUTPUT_FILEPATH="${OUTPUT_DIR}/${INPUT_BASENAME}/${MP3_FILENAME}"
|
||||||
|
|
||||||
|
# Create the necessary subdirectory structure in the output directory (only if not in dry run mode).
|
||||||
|
local OUTPUT_SUBDIR="$(dirname "$OUTPUT_FILEPATH")"
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "Dry Run: Would create directory: '$OUTPUT_SUBDIR'"
|
||||||
|
else
|
||||||
|
mkdir -p "$OUTPUT_SUBDIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Processing: '$FLAC_FILEPATH_CANONICAL'"
|
||||||
|
echo "Target MP3: '$OUTPUT_FILEPATH'"
|
||||||
|
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "Dry Run: Would convert '$FLAC_FILEPATH_CANONICAL' to '$OUTPUT_FILEPATH'"
|
||||||
|
else
|
||||||
|
# Perform the conversion
|
||||||
ffmpeg -i "$FLAC_FILEPATH_CANONICAL" -map 0:a:0 -codec:a libmp3lame -b:a 320k -y "$OUTPUT_FILEPATH" >/dev/null 2>&1
|
ffmpeg -i "$FLAC_FILEPATH_CANONICAL" -map 0:a:0 -codec:a libmp3lame -b:a 320k -y "$OUTPUT_FILEPATH" >/dev/null 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Successfully converted: '$MP3_FILENAME'"
|
echo "Successfully converted: '$MP3_FILENAME'"
|
||||||
else
|
else
|
||||||
echo "Error converting: '$FLAC_FILEPATH_CANONICAL'. Check ffmpeg output for details."
|
echo "Error converting: '$FLAC_FILEPATH_CANONICAL'. Check ffmpeg output for details."
|
||||||
# find -exec doesn't stop on errors by default, so we explicitly exit the subshell.
|
fi
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
echo "--------------------------------------------------"
|
echo "--------------------------------------------------"
|
||||||
}
|
done
|
||||||
|
|
||||||
# Export the function so `find -exec zsh -c '...'` can see it.
|
|
||||||
export -f exec_convert_single_file
|
|
||||||
|
|
||||||
# Find all .flac files and execute the helper function for each.
|
|
||||||
# Using `+` instead of `;` tells find to pass multiple files to a single invocation
|
|
||||||
# of `zsh -c` if possible, which can be more efficient.
|
|
||||||
find "$INPUT_DIR" -type f -name "*.flac" -exec zsh -c 'exec_convert_single_file "$@"' _ {} +
|
|
||||||
|
|
||||||
echo "Conversion process completed."
|
echo "Conversion process completed."
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "Remember: This was a DRY RUN. No actual files were converted or directories created."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user