172 lines
5.6 KiB
Bash
172 lines
5.6 KiB
Bash
#!/bin/bash
|
|
# Music library tree generator for VPS (no ffprobe required)
|
|
# Usage: ./music-library-tree-vps.sh [music-directory] [output-file]
|
|
|
|
MUSIC_DIR="${1:-/home/glenneth/Music}"
|
|
OUTPUT_FILE="${2:-music-library-tree.txt}"
|
|
|
|
# Check if music directory exists
|
|
if [ ! -d "$MUSIC_DIR" ]; then
|
|
echo "Error: Music directory '$MUSIC_DIR' does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
# Function to get duration using available tools
|
|
get_duration() {
|
|
local file="$1"
|
|
|
|
# Try mediainfo first
|
|
if command -v mediainfo &> /dev/null; then
|
|
duration=$(mediainfo --Inform="General;%Duration%" "$file" 2>/dev/null)
|
|
if [ -n "$duration" ] && [ "$duration" != "" ]; then
|
|
# Convert milliseconds to minutes:seconds
|
|
duration_sec=$((duration / 1000))
|
|
printf "%02d:%02d" $((duration_sec/60)) $((duration_sec%60))
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Try mp3info for MP3 files
|
|
if [[ "$file" == *.mp3 ]] && command -v mp3info &> /dev/null; then
|
|
duration=$(mp3info -p "%m:%02s" "$file" 2>/dev/null)
|
|
if [ -n "$duration" ]; then
|
|
echo "$duration"
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Try soxi (from sox package)
|
|
if command -v soxi &> /dev/null; then
|
|
duration=$(soxi -D "$file" 2>/dev/null)
|
|
if [ -n "$duration" ]; then
|
|
duration_sec=${duration%.*}
|
|
printf "%02d:%02d" $((duration_sec/60)) $((duration_sec%60))
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# No duration available
|
|
echo "--:--"
|
|
}
|
|
|
|
# Function to format file size
|
|
format_size() {
|
|
local size=$1
|
|
if [ $size -ge 1073741824 ]; then
|
|
printf "%.1fG" $(awk "BEGIN {printf \"%.1f\", $size/1073741824}")
|
|
elif [ $size -ge 1048576 ]; then
|
|
printf "%.1fM" $(awk "BEGIN {printf \"%.1f\", $size/1048576}")
|
|
elif [ $size -ge 1024 ]; then
|
|
printf "%.0fK" $(awk "BEGIN {printf \"%.0f\", $size/1024}")
|
|
else
|
|
printf "%dB" $size
|
|
fi
|
|
}
|
|
|
|
# Function to recursively build tree
|
|
build_tree() {
|
|
local dir="$1"
|
|
local prefix="$2"
|
|
|
|
# Get all entries sorted (directories first, then files)
|
|
local entries=($(find "$dir" -maxdepth 1 -mindepth 1 | sort))
|
|
local dirs=()
|
|
local files=()
|
|
|
|
# Separate directories and files
|
|
for entry in "${entries[@]}"; do
|
|
if [ -d "$entry" ]; then
|
|
dirs+=("$entry")
|
|
else
|
|
files+=("$entry")
|
|
fi
|
|
done
|
|
|
|
# Combine: directories first, then files
|
|
local all_entries=("${dirs[@]}" "${files[@]}")
|
|
local count=${#all_entries[@]}
|
|
local index=0
|
|
|
|
for entry in "${all_entries[@]}"; do
|
|
index=$((index + 1))
|
|
local basename=$(basename "$entry")
|
|
local is_last=false
|
|
[ $index -eq $count ] && is_last=true
|
|
|
|
if [ -d "$entry" ]; then
|
|
# Directory
|
|
if $is_last; then
|
|
echo "${prefix}└── $basename/" >> "$OUTPUT_FILE"
|
|
build_tree "$entry" "${prefix} "
|
|
else
|
|
echo "${prefix}├── $basename/" >> "$OUTPUT_FILE"
|
|
build_tree "$entry" "${prefix}│ "
|
|
fi
|
|
else
|
|
# File - check if it's an audio file
|
|
local ext="${basename##*.}"
|
|
ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [[ "$ext" =~ ^(mp3|flac|ogg|m4a|wav|aac|opus|wma)$ ]]; then
|
|
local duration=$(get_duration "$entry")
|
|
local size=$(stat -c%s "$entry" 2>/dev/null || stat -f%z "$entry" 2>/dev/null)
|
|
local size_fmt=$(format_size $size)
|
|
|
|
if $is_last; then
|
|
echo "${prefix}└── $basename [$duration] ($size_fmt)" >> "$OUTPUT_FILE"
|
|
else
|
|
echo "${prefix}├── $basename [$duration] ($size_fmt)" >> "$OUTPUT_FILE"
|
|
fi
|
|
else
|
|
# Non-audio file
|
|
if $is_last; then
|
|
echo "${prefix}└── $basename" >> "$OUTPUT_FILE"
|
|
else
|
|
echo "${prefix}├── $basename" >> "$OUTPUT_FILE"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Detect available tools
|
|
echo "Checking for available metadata tools..."
|
|
TOOLS_AVAILABLE=""
|
|
command -v mediainfo &> /dev/null && TOOLS_AVAILABLE="$TOOLS_AVAILABLE mediainfo"
|
|
command -v mp3info &> /dev/null && TOOLS_AVAILABLE="$TOOLS_AVAILABLE mp3info"
|
|
command -v soxi &> /dev/null && TOOLS_AVAILABLE="$TOOLS_AVAILABLE soxi"
|
|
|
|
if [ -z "$TOOLS_AVAILABLE" ]; then
|
|
echo "Warning: No metadata tools found (mediainfo, mp3info, soxi)"
|
|
echo "Duration information will not be available"
|
|
else
|
|
echo "Found tools:$TOOLS_AVAILABLE"
|
|
fi
|
|
|
|
echo "Generating music library tree..."
|
|
|
|
# Start generating the tree
|
|
{
|
|
echo "Music Library Tree"
|
|
echo "=================="
|
|
echo "Generated: $(date)"
|
|
echo "Directory: $MUSIC_DIR"
|
|
echo "Tools available:$TOOLS_AVAILABLE"
|
|
echo ""
|
|
|
|
# Count total files
|
|
total_audio=$(find "$MUSIC_DIR" -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.m4a" -o -iname "*.wav" -o -iname "*.aac" -o -iname "*.opus" -o -iname "*.wma" \) 2>/dev/null | wc -l)
|
|
echo "Total audio files: $total_audio"
|
|
echo ""
|
|
|
|
# Build the tree
|
|
echo "$(basename "$MUSIC_DIR")/"
|
|
} > "$OUTPUT_FILE"
|
|
|
|
build_tree "$MUSIC_DIR" ""
|
|
|
|
echo ""
|
|
echo "Tree generated successfully!"
|
|
echo "Output saved to: $OUTPUT_FILE"
|
|
echo "Total audio files: $(find "$MUSIC_DIR" -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.m4a" -o -iname "*.wav" -o -iname "*.aac" -o -iname "*.opus" -o -iname "*.wma" \) 2>/dev/null | wc -l)"
|