Moved mp3 tools to their own repo (isen)
This commit is contained in:
parent
14fbd2cfdb
commit
a20fc1f3f7
2 changed files with 0 additions and 224 deletions
153
mp3helpers
153
mp3helpers
|
@ -1,153 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
renameid3 () {
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
>&2 echo "Usage : $0 <file>"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
filename=$(mid3v2 "$1" | awk -F "=" '
|
|
||||||
/TIT2/{title = $2}
|
|
||||||
/TPE1/{artist = $2}
|
|
||||||
END {printf("%s - %s.mp3", artist, title)}
|
|
||||||
')
|
|
||||||
|
|
||||||
dir=$(dirname "$1")
|
|
||||||
mv -v "$1" "$dir/$filename"
|
|
||||||
}
|
|
||||||
|
|
||||||
#mp3tag () {
|
|
||||||
# if [ -z "$1" ]; then
|
|
||||||
# >&2 echo "Usage : $0 <file>"
|
|
||||||
# return 1
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# if [ -d "$1" ]; then
|
|
||||||
# >&2 echo "Cannot open $1"
|
|
||||||
# return 1
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# artist=$(basename "$1")
|
|
||||||
# for f in "$1"/*; do
|
|
||||||
# id3=$(mid3v2 "$f")
|
|
||||||
# id3_artist=$(awk -F= '/TPE1/{print $2; // Will fail with a "="}')
|
|
||||||
# if ! grep "^TPE1="; then
|
|
||||||
# # If artist is not already tagged
|
|
||||||
# fi
|
|
||||||
# if [ -n "$id3_artist" ] && [ "$artist" != "$id3_artist" ]; then
|
|
||||||
# artist
|
|
||||||
# fi
|
|
||||||
# done
|
|
||||||
#}
|
|
||||||
|
|
||||||
mp3sort () {
|
|
||||||
# TODO
|
|
||||||
# Fuzzy matching (ex Anti Nightcore -> Anti-Nightcore
|
|
||||||
# Best guess for artist enforcement -> Artist - Title.mp3
|
|
||||||
# Integrate filename cleanup (remove [offical video] etc.)
|
|
||||||
|
|
||||||
if [ "$#" -eq 0 ]; then
|
|
||||||
>&2 echo "Usage $0 <file1...file2...>"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mus_folder=${MUS_FOLDER:-"$HOME/mus"}
|
|
||||||
|
|
||||||
# Check that all the songs are from the same artist
|
|
||||||
artist=""
|
|
||||||
first=1
|
|
||||||
for f in "$@"; do
|
|
||||||
name=$(basename "$f")
|
|
||||||
# Fuck unicode
|
|
||||||
tmp=$(echo "$name" | awk -F " [-–] " '{print $1}')
|
|
||||||
# Trim a single whitespace
|
|
||||||
tmp="${tmp%% }"
|
|
||||||
if [ "$first" -eq 1 ]; then
|
|
||||||
first=0
|
|
||||||
elif [ "$tmp" != "$artist" ]; then
|
|
||||||
>&2 echo "File '$f' doesn't match artist name '$artist'"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
artist="$tmp"
|
|
||||||
done
|
|
||||||
|
|
||||||
folder="$mus_folder/$artist"
|
|
||||||
|
|
||||||
alt_folders=$(find "$mus_folder" -type d -iname '*'"$artist"'*' ! -name "$artist")
|
|
||||||
while [ -n "$alt_folders" ]; do
|
|
||||||
tmp=$(echo "$alt_folders" | head -n1)
|
|
||||||
>&2 printf 'One or more folders with mismatched casing already exist:\n%s\n' "$alt_folders"
|
|
||||||
>&2 printf "Use '%s' instead (y)\\nKeep original or skip to next choice (n)\\nQuit (q) " "$tmp"
|
|
||||||
old_stty_cfg=$(stty -g)
|
|
||||||
stty raw -echo
|
|
||||||
answer=$( while ! head -c 1 | grep -i '[nyq]' ;do true ;done )
|
|
||||||
stty "$old_stty_cfg" # Careful playing with stty
|
|
||||||
>&2 printf '\n'
|
|
||||||
# Use first line of $alt_folders (will break with newlines in dirnames)
|
|
||||||
if echo "$answer" | grep -iq "^y" ;then
|
|
||||||
folder="$tmp"
|
|
||||||
artist=$(basename "$folder")
|
|
||||||
break
|
|
||||||
# Quit
|
|
||||||
elif echo "$answer" | grep -iq "^q"; then
|
|
||||||
return 0
|
|
||||||
# Skip to next choice, or keep original if none are left
|
|
||||||
else
|
|
||||||
alt_folders=$(echo "$alt_folders" | tail -n +2)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
mkdir -p "$folder"
|
|
||||||
|
|
||||||
mid3v2 -a "$artist" "$@"
|
|
||||||
|
|
||||||
for f in "$@"; do
|
|
||||||
name=$(basename "$f")
|
|
||||||
# Make artist name in the filename match the folder
|
|
||||||
if [ -n "$alt_folders" ]; then
|
|
||||||
# https://stackoverflow.com/questions/19154996/awk-split-only-by-first-occurrence
|
|
||||||
name=$(echo "$name" | awk -F " [-–] " -v art="$artist" '{
|
|
||||||
st = match($0," [-–] ");
|
|
||||||
printf("%s %s", art, substr($0, st+1));
|
|
||||||
}')
|
|
||||||
fi
|
|
||||||
mv -v "$f" "$folder/$name"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
mp3swaptitle () {
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
>&2 echo "Usage : $0 <file>"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
filename=$(echo "$1" | sed 's/\.mp3$//' | awk -F " - " -v OFS=" - " '{
|
|
||||||
gsub(/[ \t]+$/, "", $1); // Suffix trim
|
|
||||||
gsub(/[ \t]+$/, "", $2); // Suffix trim
|
|
||||||
gsub(/^[ \t]+/, "", $2); // Prefix trim
|
|
||||||
artist = $2;
|
|
||||||
title = $1;
|
|
||||||
$1 = $2 = "";
|
|
||||||
printf("%s - %s%s.mp3", artist, title, substr($0, 4));
|
|
||||||
}')
|
|
||||||
|
|
||||||
dir=$(dirname "$1")
|
|
||||||
mv -v "$1" "$dir/$filename"
|
|
||||||
}
|
|
||||||
|
|
||||||
mp3fixdash () {
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
>&2 echo "Usage : $0 <file>"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
filename=$(echo "$1" | sed -E -e 's/\S[-~–]\s+/ - /g; s/\s+[-~–]\S/ - /g; s/\s+[-~–]\s+/ - /g')
|
|
||||||
#filename=$(echo "$1" | sed -E -e 's/\S-\s+/(a)/g; s/\s+-\S/(b)/g; s/\s+-\s+/(c)/g')
|
|
||||||
|
|
||||||
if [ "$filename" = "$1" ]; then
|
|
||||||
>&2 echo "Nothing to be done"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
dir=$(dirname "$1")
|
|
||||||
mv -v "$1" "$dir/$filename"
|
|
||||||
}
|
|
71
mp3tag.py
71
mp3tag.py
|
@ -1,71 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from fuzzywuzzy import fuzz, process
|
|
||||||
from mutagen.easyid3 import EasyID3
|
|
||||||
from mutagen.id3 import ID3NoHeaderError
|
|
||||||
import os
|
|
||||||
from os.path import basename, normpath, splitext
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def eprint(*args, **kwargs):
|
|
||||||
print(*args, file=sys.stderr, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def filename(f):
|
|
||||||
return splitext(normpath(basename(f)))[0]
|
|
||||||
|
|
||||||
|
|
||||||
dirs = []
|
|
||||||
for d in sys.argv[1:]:
|
|
||||||
if not os.path.isdir(d):
|
|
||||||
eprint("Error: Cannot open {}: not a directory".format(d))
|
|
||||||
sys.exit(1)
|
|
||||||
dirs += [d]
|
|
||||||
|
|
||||||
for d in dirs:
|
|
||||||
# Get first level file list
|
|
||||||
(root, _, files) = next(os.walk(d))
|
|
||||||
dir_artist = filename(d)
|
|
||||||
|
|
||||||
for f in files:
|
|
||||||
f = os.path.join(root, f)
|
|
||||||
name = filename(f)
|
|
||||||
name_parts = name.split(" - ")
|
|
||||||
file_artist = name_parts[0]
|
|
||||||
fuzzy_artist = process.extractOne(dir_artist, name_parts, scorer=fuzz.token_sort_ratio)
|
|
||||||
|
|
||||||
if len(name_parts) < 2:
|
|
||||||
eprint("Error: No title found for {}".format(f))
|
|
||||||
continue
|
|
||||||
|
|
||||||
file_title = name_parts[1]
|
|
||||||
|
|
||||||
if dir_artist != file_artist:
|
|
||||||
eprint("""Error: Artist name mismatch between folder and file: {}
|
|
||||||
Fuzzy score = {:3d}, artist = {}""".format(f, fuzzy_artist[1], fuzzy_artist[0]))
|
|
||||||
# Test for common artist name patterns
|
|
||||||
if fuzzy_artist[1] < 90:
|
|
||||||
r = fuzz.ratio(dir_artist, "the " + fuzzy_artist[0])
|
|
||||||
if True: # r >= 95:
|
|
||||||
eprint(" Fuzzy match r={} for: {}".format(
|
|
||||||
r,
|
|
||||||
"the " + fuzzy_artist[0]))
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
id3 = EasyID3(f)
|
|
||||||
except ID3NoHeaderError:
|
|
||||||
id3 = EasyID3()
|
|
||||||
if id3 is None:
|
|
||||||
eprint("Error: cannot open {} for tagging".format(f))
|
|
||||||
continue
|
|
||||||
|
|
||||||
if "artist" not in id3.keys():
|
|
||||||
id3["artist"] = file_artist
|
|
||||||
print("Artist set to {}".format(file_artist))
|
|
||||||
if "title" not in id3.keys():
|
|
||||||
id3["title"] = file_title
|
|
||||||
print("Title set to {}".format(file_title))
|
|
||||||
# id3.save(f)
|
|
Loading…
Reference in a new issue