#!/usr/bin/perl ###################################################################### # mp3rename -- 2003, Mike Schilli ###################################################################### # PURPOSE ###################################################################### use strict; use warnings; use MP3::Info; use Storable; use File::Copy; my $PERSIST_FILE = glob "~/data/mp3rename.dat"; my $VERSION = "0.02"; our $CVSVERSION = '$Revision: 1.3 $'; my $STORE; if(-e $PERSIST_FILE) { $STORE = retrieve $PERSIST_FILE; } END { store $STORE, $PERSIST_FILE } for(@ARGV) { print "Processing $_\n"; # Read both v1 and v2 info and fill in v1 info where # it's missing and v2 info is present my $mp3 = get_mp3tag($_, 1); my $mp3_2 = get_mp3tag($_, 2); if($mp3_2) { for(keys %$mp3) { $mp3->{$_} = $mp3_2->{$_} if ! length($mp3->{$_}) and length($mp3_2->{$_}) } } die "Cannot read mp3info from $_" unless defined $mp3; my $name = rep($_, "ARTIST", $mp3->{ARTIST}) . "_-_"; $name .= rep($_, "ALBUM", $mp3->{ALBUM}); $name .= sprintf "%02d", track($mp3); $name .= "_-_"; $name .= rep($_, "TITLE", $mp3->{TITLE}); $name .= ".mp3"; print "$_ => $name\n"; move($_, $name) or die "mv $_ $name failed: $!"; } ################################### sub track { ################################### my($mp3) = @_; if($mp3->{TRACKNUM} =~ /(\d+)/) { return $1; } elsif($mp3->{COMMENT} =~ /(\d+)/) { return $1; } else { return undef; } } ################################### sub rep { ################################### my($file, $category, $string) = @_; my $rep; if(exists $STORE->{$category} and exists $STORE->{$category}->{$string}) { $rep = $STORE->{$category}->{$string}; } elsif($category eq "ALBUM") { $rep = album_abbr($string); } else { $rep = rep_specials($string); } print "$category $string\n"; my $result = pick($rep); if($result ne $rep) { my $tag = get_mp3tag($file); $tag->{$category} = $result; set_mp3tag($file); } $result = rep_specials($result); $STORE->{$category}->{$string} = $result; return $result; } ################################### sub rep_specials { ################################### my($string) = @_; $string =~ s/[^A-Za-z0-9,\. _-]//g; $string =~ s/ +/ /g; $string =~ s/^\s+//; $string =~ s/\s+$//; $string =~ s/ /_/g; return $string; } ################################### sub album_abbr { ################################### my($album) = @_; my @words = split ' ', $album, 3; return join '', map { uc(substr($_, 0, 1)) } @words; } ########################################### sub pick { ########################################### my(@options) = @_; my $counter = 1; for(@options) { print "[", $counter++, "] $_\n"; } $| = 1; print "[1]>"; chomp(my $input = ); $input = 1 unless $input; if($input =~ /^\d+$/) { return $options[$input-1]; } else { return $input; } } __DATA__ 'YEAR' => '', 'ARTIST' => 'Nena & Kim Wilde', 'COMMENT' => '', 'TITLE' => 'Anyplace, Anywhere, Anytime', 'ALBUM' => 'Just The Best Vol. 45 Disc 2', 'GENRE' => 'Verschiedenes', 'TRACKNUM' => '1', 'TAGVERSION' => 'ID3v1.1 / ID3v2.3.0' __END__ =head1 NAME mp3rename - Rename MP3 files according to contained MP3 tags =head1 DOWNLOAD _SRC_HERE_ =head1 SYNOPSIS mp3rename somefile.mp3 =head1 DESCRIPTION mp3rename reads out a file's MP3 tags, confirms ambiguities with the user, and then renames the file according to the following naming scheme: Artist_-_AlbumTrack_-_Title.mp3 Like the popular C program, this will abbreviate the album name with its initials. The following MP3 info led to the file name above: Green_Day_-_AI08_-_Shes_A_Rebel.mp3 'YEAR' => '', 'ARTIST' => 'Green Day', 'COMMENT' => 'track08', 'TITLE' => 'She\'s A Rebel', 'ALBUM' => 'American Idiot', 'GENRE' => '', 'TAGVERSION' => 'ID3v1', 'TRACKNUM' => '' By default, all entries never seen by C are being confirmed with the user, who can either accept the entry by hitting Enter or enter a different string. All confirmed entries are stored in a GDBM database, C<~/data/mp3rename.dat> by default. If the same artist or album comes along later, C will pull it out of the database and won't ask the user to confirm it anymore. =head1 EXAMPLES $ mp3rename somefile.mp3 ARTIST Green Day [1] Green_Day [1]> (User hits Enter) ALBUM American Idiot [1] AI [1]> (User hits Enter) TITLE She's A Rebel [1] Shes_A_Rebel [1]> (User hits Enter) somefile.mp3 => Green_Day_-_AI08_-_Shes_A_Rebel.mp3 =head1 LEGALESE Copyright 2004 by Mike Schilli, all rights reserved. This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR 2004, Mike Schilli