diff --git a/music_tagmove_lib b/music_tagmove_lib index 1581414..5a30bb2 100644 --- a/music_tagmove_lib +++ b/music_tagmove_lib @@ -39,13 +39,79 @@ function error { >&2 printf "%s\n" "$current_error_line" } -function clr_errf { local_errf= +function clr_errf { + local_errf= } -function read_tag { - clr_errf +function get_file_extension { + echo "${1##*.}" +} + +function read_tag_flac { + local tag=${1^^} + local file="$2" + + if [[ $tag == "TRACK" ]]; then + tag="TRACKNUMBER" + fi + + local comment_line + comment_line=$(metaflac --list "$file" --block-type=VORBIS_COMMENT | grep -F "$tag=") + if [[ $? -ne 0 ]]; then + error "Reading tag \"$1\" from \"$file\" failed: metaflac error" + return + fi + local result=${comment_line#*=} + if [[ -z $result ]]; then + error "Reading tag "$1" from \"$file\" failed: empty value" + return + fi + echo "$result" +} + +function read_tag_id3 { local tag="$1" local file="$2" + + declare -A id3v2_map=( [artist]=TPE1 \ + [album]=TALB \ + [title]=TIT2 \ + [date]=TYER \ + [track]=TRCK ) + + local id3v2_content_rfc822 + id3v2_content_rfc822=$(id3v2 -R "$file") + if [[ $? -ne 0 ]]; then + error "Reading tag \"$1\" from \"$file\" failed: id3v2 error" + return + fi + local no_id3tag_fmt='*No ID3 tag' + + if [[ $id3v2_content_rfc822 == $no_id3tag_fmt ]]; then + read_tag_fallback "$tag" "$file" + return + else + local rfc822tag=${id3v2_map[$tag]} + if [[ -z $rfc822tag ]]; then + error "Unknown tag \"$tag\" requested for file \"$file\"" + return + fi + local line=$(grep -E "^$rfc822tag:\s" <<<"$id3v2_content_rfc822") + local result=${line:6} + + if [[ -z $result ]]; then + error "Reading tag \"$tag\" from \"$file\" failed: empty value" + return + fi + + echo "$result" + fi +} + +function read_tag_fallback { + local tag="$1" + local file="$2" + local result=$(ffprobe -loglevel error -show_entries format_tags="$tag" -of default=noprint_wrappers=1:nokey=1 "$file") if [[ $? -ne 0 ]]; then error "Reading tag \"$tag\" from \"$file\" failed (ffprobe failed)" @@ -53,10 +119,31 @@ function read_tag { fi if [[ -z $result ]]; then error "Reading tag \"$tag\" from \"$file\" failed (result empty)" + return fi echo "$result" } +function read_tag { + clr_errf + local tag="$1" + local file="$2" + local ext=$(get_file_extension "$file") + + shopt -s nocasematch + case "$ext" in + flac) + read_tag_flac "$tag" "$file" + ;; + mp3) + read_tag_id3 "$tag" "$file" + ;; + *) + read_tag_fallback "$tag" "$file" + ;; + esac +} + function cuesplit_single { clr_errf @@ -119,7 +206,7 @@ function cuesplit_single { if cuebreakpoints "$cue" | shnsplit -o flac "$flac" || \ cuebreakpoints "$cue" | sed 's/$/0/' | shnsplit -o flac "$flac"; then info "Tagging target \"$image_dir\"" - if cuetag "$cue" split-*.flac; then + if cuetag.sh "$cue" split-*.flac; then info "Renaming source files" mv "$cue" "$cue.ignore" mv "$flac" "$flac.ignore" @@ -178,7 +265,27 @@ function tagmove_single { eval "dest_file=\"$FILE_FORMAT\"" mkdir -p "$dest_root/$dest_directory" - mv_wrap "$file_name" "$dest_root/$dest_directory/$dest_file.${file_name##*.}" + mv_wrap "$file_name" "$dest_root/$dest_directory/$dest_file.$(get_file_extension "$file_name")" +} + +function tagmove_get_media_type { + file="$1" + ext=$(get_file_extension "$file") + + shopt -s nocasematch + + case $ext in + flac|alac|aac|m4a|mp3|ogg|oga|opus|wav|wma) + echo "audio" + ;; + jpg|jpeg|png) + echo "image" + ;; + *) + file -b --mime-type "$file" | cut -d'/' -f1 + ;; + esac + } @@ -189,9 +296,18 @@ function tagmove { fi while read -r file; do - if [[ $(file -b --mime-type "$file") =~ ^audio/ ]]; then - tagmove_single "$file" - fi + media_type=$(tagmove_get_media_type "$file") + + case "$media_type" in + audio) + tagmove_single "$file" + ;; + image) + # TODO: cover move + echo "potential cover: $file" + ;; + esac + done < <(find "$source_dir" -type f -not -name "*.ignore") }