metadata scripts
This commit is contained in:
1 parent
74a3cfe8ed
commit
cff21a4dab
4 files changed
+256
No files matched your search
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
set -Eeuo pipefail
|
||||
escape_kid3() {
|
||||
printf '%s' "$1" | sed "s/'/'\\\\''/g"
|
||||
}
|
||||
DRY_RUN=false
|
||||
|
||||
if [[ "$1" == "--dry-run" ]]; then
|
||||
DRY_RUN=true
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 [--dry-run] file.txt"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
list="$1"
|
||||
|
||||
if [[ ! -f "$list" ]]; then
|
||||
echo "ERROR: File list not found: $list"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while IFS= read -r file; do
|
||||
|
||||
[[ -z "$file" ]] && continue
|
||||
|
||||
if [[ ! -e "$file" ]]; then
|
||||
echo "ERROR: Missing file: $file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "$file" ]]; then
|
||||
echo "WARNING: Is a directory, skipping: $file"
|
||||
continue
|
||||
fi
|
||||
|
||||
bookdir="$(dirname "$file")"
|
||||
booktitle="$(basename "$bookdir")"
|
||||
author="$(basename "$(dirname "$bookdir")")"
|
||||
|
||||
echo
|
||||
echo "File: $file"
|
||||
echo "Artist: $author"
|
||||
echo "Album: $booktitle"
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "DRY RUN: no changes made"
|
||||
continue
|
||||
fi
|
||||
|
||||
artist=$(escape_kid3 "$author")
|
||||
album=$(escape_kid3 "$booktitle")
|
||||
|
||||
kid3-cli "$file" \
|
||||
-c "tag 1" \
|
||||
-c "set artist '$artist'" \
|
||||
-c "set album '$album'" \
|
||||
-c "tag 2" \
|
||||
-c "set artist '$artist'" \
|
||||
-c "set album '$album'" \
|
||||
-c save
|
||||
done < "$list"
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
|
||||
DRY_RUN=false
|
||||
DELETE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
--delete)
|
||||
DELETE=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 [--dry-run] [--delete] file.txt"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
list="$1"
|
||||
|
||||
while IFS= read -r file; do
|
||||
|
||||
[[ -z "$file" ]] && continue
|
||||
|
||||
if [[ ! -e "$file" ]]; then
|
||||
echo "ERROR: Missing file: $file"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -d "$file" ]]; then
|
||||
echo "WARNING: Is a directory, skipping: $file"
|
||||
continue
|
||||
fi
|
||||
# Get comment from ID3v2
|
||||
comment=$(kid3-cli "$file" \
|
||||
-c "tag 2" \
|
||||
-c "get comment" 2>/dev/null)
|
||||
|
||||
[[ -z "$comment" ]] && continue
|
||||
|
||||
echo
|
||||
echo "File: $file"
|
||||
echo "Comment: $comment"
|
||||
|
||||
composer=""
|
||||
|
||||
# Match: read by Name; text
|
||||
if [[ "$comment" =~ ^[Rr]ead[[:space:]]+[Bb]y[[:space:]]+([^;]+)\; ]]; then
|
||||
composer="${BASH_REMATCH[1]}"
|
||||
composer="$(echo "$composer" | sed 's/[[:space:]]*$//')"
|
||||
|
||||
echo "Found narrator: $composer"
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "DRY RUN: set composer '$composer', delete comment"
|
||||
else
|
||||
kid3-cli "$file" \
|
||||
-c "tag 2" \
|
||||
-c "set composer '$composer'" \
|
||||
-c "set comment ''" \
|
||||
-c save
|
||||
fi
|
||||
|
||||
elif [[ ${#comment} -lt 40 ]]; then
|
||||
|
||||
echo "Short comment (${#comment} chars): $comment"
|
||||
|
||||
if $DELETE; then
|
||||
if $DRY_RUN; then
|
||||
echo "DRY RUN: delete comment"
|
||||
else
|
||||
kid3-cli "$file" \
|
||||
-c "tag 2" \
|
||||
-c "set comment ''" \
|
||||
-c save
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
done < "$list"
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
root="${1:-.}"
|
||||
mode="${2:-}"
|
||||
THRESHOLD=40
|
||||
find "$root" \( -iname '*.mp3' -o -iname '*.m4a' -o -iname '*.m4b' \) -print0 |
|
||||
while IFS= read -r -d '' f; do
|
||||
|
||||
comment=$(ffprobe -v error \
|
||||
-show_entries format_tags=comment \
|
||||
-of default=nw=1:nk=1 \
|
||||
-- "$f")
|
||||
|
||||
description=$(ffprobe -v error \
|
||||
-show_entries format_tags=description \
|
||||
-of default=nw=1:nk=1 \
|
||||
-- "$f")
|
||||
|
||||
# trim comment
|
||||
comment="${comment#"${comment%%[![:space:]]*}"}"
|
||||
comment="${comment%"${comment##*[![:space:]]}"}"
|
||||
|
||||
# ---- DELETE MODE ----
|
||||
if [[ "$mode" == "del" && -n "$comment" && ${#comment} -lt $THRESHOLD ]]; then
|
||||
tmp=$(mktemp -p "$(dirname -- "$f")" ".fftmp.XXXXXX.${f##*.}") || continue
|
||||
|
||||
echo "Removing short comment: $f"
|
||||
echo " comment: $comment"
|
||||
|
||||
ffmpeg -nostdin -v error -y \
|
||||
-i "$f" \
|
||||
-map 0 \
|
||||
-map_metadata 0 \
|
||||
-c copy \
|
||||
-metadata comment= \
|
||||
"$tmp" &&
|
||||
mv -f -- "$tmp" "$f" || {
|
||||
echo "FAILED: $f" >&2
|
||||
rm -f -- "$tmp"
|
||||
}
|
||||
|
||||
continue
|
||||
fi
|
||||
|
||||
# ---- SCAN MODE ----
|
||||
# only show short non-empty tags (<20 chars)
|
||||
for tag in comment description; do
|
||||
value="${!tag}"
|
||||
|
||||
value="${value#"${value%%[![:space:]]*}"}"
|
||||
value="${value%"${value##*[![:space:]]}"}"
|
||||
|
||||
if [[ -n "$value" && ${#value} -lt $THRESHOLD ]]; then
|
||||
printf "%s\n %s: %s\n\n" "$f" "$tag" "$value"
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
find . \( -iname '*.mp3' -o -iname '*.m4a' -o -iname '*.m4b' \) -print0 |
|
||||
while IFS= read -r -d '' f; do
|
||||
|
||||
comment=$(ffprobe -v error \
|
||||
-show_entries format_tags=comment \
|
||||
-of default=nw=1:nk=1 \
|
||||
-- "$f")
|
||||
|
||||
[[ $comment =~ ^[Rr]ead[[:space:]]+[Bb]y[[:space:]]+(.+) ]] || continue
|
||||
|
||||
composer="${BASH_REMATCH[1]}"
|
||||
echo "Updating: $f"
|
||||
echo " Composer: $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
|
||||
Reference in new issue
Block a user