Issue
I have a music library of mp3s (with correct metadata) organized like so: Music/{artists}/{album}/{title}
For example: Music/Green Day/American Idiot/<songs in the album>
Each mp3 is named like so:
{title} {artists} {album}.mp3
For example:
Jesus of Suburbia Green Day American Idiot.mp3
Keeping the same directory structure, I would like to rename each file so that it is titled like so: {title} - {artists} - {album}.mp3
For example Jesus of Suburbia Green Day American Idiot.mp3
--> Jesus of Suburbia - Green Day - American Idiot.mp3
I was hoping someone would know of a script that could do this?
Thanks for the help.
P.S.
Songs that have multiple artists are organized somewhat differently
For example, in the music library we have both
Music/Fall Out Boy/Save Rock And Roll/<most of the songs in the album>
and
Music/Fall Out Boy,Elton John/Save Rock And Roll/Save Rock And Roll Fall Out Boy,Elton John Save Rock And Roll.mp3
This one isn't the best example, as it may be confusing because that song shares the same name as the album, which is why it appears twice in the mp3's name.
EDIT: Based on your search suggestions, I was able to find a command:
ffprobe -loglevel error -show_entries format_tags=title,artist,album -of default=noprint_wrappers=1:nokey=1 file.mp3
Which can extract the metadata attributes that I need. I'm not sure how to apply this to be able to rename files though...
Solution
Based on your research, you can get title/artist/album from mp3 file by executing: ffprobe -loglevel error -show_entries format_tags=title -of default=noprint_wrappers=1:nokey=1 mymp3.mp3
So we just need to make a function to build mp3 name by concatenating those strings:
function mp3name() {
local title="$(ffprobe -loglevel error -show_entries format_tags=title -of default=noprint_wrappers=1:nokey=1 "$1")"
local artist="$(ffprobe -loglevel error -show_entries format_tags=artist -of default=noprint_wrappers=1:nokey=1 "$1")"
local album="$(ffprobe -loglevel error -show_entries format_tags=album -of default=noprint_wrappers=1:nokey=1 "$1")"
mkdir -p "$artist/$album"
local name="$artist/$album/$title - $artist - $album.mp3"
echo "$name"
mv "$1" "$name"
}
Then we can use find
and it's exec
argument to execute above function on mp3's
export -f mp3name
find -name '*.mp3' -exec bash -c 'mp3name "$@"' bash {} \;
Example mp3 file can be taken from: https://file-examples.com/index.php/sample-audio-files/sample-mp3-download/
Result:
$ ls
'Impact Moderato - Kevin MacLeod - YouTube Audio Library.mp3'
Answered By - Kristian Answer Checked By - David Marino (WPSolving Volunteer)