#!/usr/bin/env bash LIBRARY="${1:-.}" mapfile -t FILES < <( find "$LIBRARY" -type f \( \ -iname "*.mp3" -o \ -iname "*.m4b" -o \ -iname "*.m4a" \ \) ) TOTAL=${#FILES[@]} PROCESSED=0 for f in "${FILES[@]}"; do ((PROCESSED++)) if (( PROCESSED % 100 == 0 )); then echo "Progress: $PROCESSED/$TOTAL files processed" fi comment=$(ffprobe -v error \ -show_entries format_tags=comment \ -of default=nw=1:nk=1 \ -- "$f") shopt -s nocasematch [[ $comment =~ (read[[:space:]]+by|spoken[[:space:]]+by|narrated[[:space:]]+by|gesprochen[[:space:]]+von|gelesen[[:space:]]+von)[[:space:]]+([^.$'\n']*) ]] || continue composer="${BASH_REMATCH[2]}" composer="${composer%"${composer##*[!.,[:space:]]}"}" printf '[%d/%d] [%s] %s | OLD="%s" | NEW="%s "\n' "$PROCESSED" "$TOTAL" "Update" "$f" "$comment" "$composer" dir=$(dirname -- "$f") base=$(basename -- "$f") ext="${base##*.}" case "${ext,,}" in mp3) format=mp3 ;; m4a|m4b) format=ipod ;; *) continue ;; esac tmp=$(mktemp -p "$dir" ".${base}.XXXXXX") || { echo "Couldn't create temporary file in $dir" >&2 continue } if ffmpeg -nostdin -v error -y \ -i "$f" \ -map 0 \ -map_metadata 0 \ -c copy \ -metadata composer="$composer" \ -metadata comment= \ -f "$format" \ "$tmp" then mv -f -- "$tmp" "$f" else echo "FAILED: $f" >&2 rm -f -- "$tmp" fi done