#!/bin/bash # encode_all encodes the whole library into specified format # if [[ "$HOSTNAME" != 'thrakkorzog' ]]; then printf 'This should be run from thrakkorzog...\n' >&2 exit 1 fi ulimit -n "$(ulimit -Hn)" . env_parallel.bash function ts() { date '+%Y-%m-%d_%H:%M' } # overwrite_all=true overwrite_all=false debug_only=false # debug_only=true src_library="${HOME}/flac" output_dir="${HOME}/opus" logdir="${HOME}/encoding_logs" [[ -d "$logdir" ]] || mkdir "$logdir" start_ts="$(ts)" log="${logdir}/${start_ts}_encoding_log" fixes="${logdir}/${start_ts}_fixes.sh" temp_dir="$(mktemp -d)" printf '#!/bin/bash\n# FIXES generated by library_works/encode_all\n\n' > "$fixes" function encode() { file="$1" # file is full original path + filename src_dir="$(dirname "$file")" file_name="$(basename "$file")" output_dir="$(sed "s_${HOME}/flac_${HOME}/opus_" <<< "$src_dir")" final_opus="$(sed \ -e 's/\.flac$/.opus/' \ -e "s_${HOME}/flac_${HOME}/opus_" <<< "$file")" sum="$(sha256sum <<< "$final_opus" | cut -d\ -f1)" printf '%s\n' "$final_opus" > "$temp_dir/$sum" if [[ -f "$final_opus" && "$overwrite_all" == 'false' ]]; then printf '%s exists, not reencoding\n' >> "$log" return fi unset tags unset dest_dir declare -A tags while read -r line; do tag_type="$(cut -d= -f1 <<< "$line")" tag_type="${tag_type^^}" tag_val="$(cut -d= -f2- <<< "$line")" # TODO: suggest fixes for lower case tags tags["$tag_type"]="$tag_val" done < <(metaflac --list --block-type='VORBIS_COMMENT' "$file" | \ grep 'comment\[' | \ cut -d: -f2- | \ sed 's/^ //') album="$(basename "$output_dir")" album_dir_date="${album%% *}" album_dir_date_valid='true' if [[ ! "$album_dir_date" =~ ^[-0-9]+$ ]]; then printf '%s invalid album date extracted from album directory name: %s\n' "$file" "$album_dir_date" >> "$log" album_dir_date_valid='false' fi # FLAC tags to read in order: DATE RELEASEDATE YEAR album_flac_date_valid='false' for date_tag in DATE RELEASEDATE YEAR; do album_flac_date="${tags[$date_tag]}" if [[ "$album_flac_date" =~ ^[-0-9]+$ ]]; then album_flac_date_valid='true' break fi done if [[ "$album_flac_date_valid" == 'false' ]]; then [[ -n "$album_flac_date" ]] && printf '%s invalid album date extracted from flac data: %s\n' "$file" "$album_flac_date" >> "$log" [[ ! -n "$album_flac_date" ]] && printf '%s no album date extracted from flac data\n' "$file" >> "$log" fi album_date='unknown' if [[ "$album_dir_date_valid" && ! "$album_flac_date_valid" ]]; then printf '%s invalid flac tag date\n' >> "$log" album_date="$album_dir_date" if [[ "$file" != *\'* ]]; then printf "metaflac --set-tag=DATE='%s' '%s'\n" "$album_date" "$file" >> "$fixes" elif [[ "$file" != *\"* && "$file" == *\'* ]]; then printf 'metaflac --set-tag=DATE="%s" "%s"\n' "$album_date" "$file" >> "$fixes" elif [[ "$file" == *\"* && "$file" == *\'* ]]; then printf "# metaflac --set-tag=DATE='%s' '%s'\n" "$album_date" "$file" >> "$fixes" printf '# cant quote\n' >> "$fixes" fi [[ -n "$album_flac_date" ]] && printf "# old tag: '%s'\n" "$album_flac_date" >> "$fixes" [[ -z "$album_flac_date" ]] && printf "# no old tag\n" >> "$fixes" elif [[ ! "$album_dir_date_valid" && "$album_flac_date_valid" ]]; then printf '%s invalid album dir date\n' "$file" >> "$log" album_date="$album_flac_date" elif [[ "$album_dir_date_valid" && "$album_flac_date_valid" ]]; then album_dir_date_length="$(wc -c <<< "$album_dir_date")" album_flac_date_length="$(wc -c <<< "$album_flac_date")" if [[ "$album_dir_date_length" -gt "$album_flac_date_length" ]]; then printf '%s has a longer date set in album dir name\n' "$file" >> "$log" album_date="$album_dir_date" if [[ "$file" != *\'* ]]; then printf "metaflac --set-tag=DATE='%s' '%s'\n" "$album_date" "$file" >> "$fixes" elif [[ "$file" != *\"* && "$file" == *\'* ]]; then printf 'metaflac --set-tag=DATE="%s" "%s"\n' "$album_date" "$file" >> "$fixes" elif [[ "$file" == *\"* && "$file" == *\'* ]]; then printf "# metaflac --set-tag=DATE='%s' '%s'\n" "$album_date" "$file" >> "$fixes" printf '# cant quote\n' >> "$fixes" fi printf "# old tag: '%s'\n" "$album_flac_date" >> "$fixes" else printf '%s has a longer date set in flac tag\n' "$file" >> "$log" album_date="$album_flac_date" fi fi if [[ "$file_name" =~ ^D[0-9]+ ]]; then disk="$(cut -d\ -f1 <<< "$file_name")" tags['DISK']="${disk#D}" fi declare -a tag_ensure tag_ensure=( 'TRACKNUMBER' 'TITLE' 'ALBUM' 'ARTIST' ) for tag_type in "${tag_ensure[@]}"; do if [[ -z "${tags["$tag_type"]}" ]]; then printf '%s is missing tag: %s\n' "$file" "$tag_type" >> "$log" tags["$tag_type"]="missing $tag_type" fi done [[ -d "$output_dir" ]] || mkdir -p "$output_dir" tag_flags=( '--title' "${tags['TITLE']}" '--artist' "${tags['ARTIST']}" '--album' "${tags['ALBUM']}" '--tracknumber' "${tags['TRACKNUMBER']}" '--date' "${album_date}") [[ -n "${tags[DISK]}" ]] && tag_flags+=('--comment' "DISK=${tags['DISK']}") tags='' for tag in "${tag_flags[@]}"; do tags+="$(printf '"%s" ' "$tag")" done if [[ "$debug_only" == 'false' ]]; then # err="$(opusenc --quiet --discard-comments --discard-pictures "${tag_flags[@]}" "$file" "$final_opus" 2>&1)" cmd=$(printf 'opusenc --quiet --discard-comments --discard-pictures %s "%s" "%s"\n' "$tags" "$file" "$final_opus") printf '%s\n' "$cmd" eval $cmd else cmd=$(printf 'opusenc --quiet --discard-comments --discard-pictures %s "%s" "%s"\n' "$tags" "$file" "$final_opus") printf '%s\n' "$cmd" fi if [[ -n "$err" ]]; then printf '%s\n' "$err" >> "$log" fi } echo starting processing find "$src_library" -type f -name '*.flac' -print0 | env_parallel -P 0 -0 --bar encode {} echo done processing echo removing obsolete opus files diff -d --suppress-common-lines <(cat "$temp_dir"/* | sort -V) <(find "$output_dir" -type f | sort -V) | grep -E '^>' | sed 's/^> //' | while read old_opus; do rm -f "$old_opus" done rm -rf "$temp_dir" echo deleting any empty directories find "$output_dir" -empty -type d -delete