Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Perl scripts and MP3
Options
-
20-07-2007 12:02pmHi All,
Was thinking of putting this question in the Unix section but think it would be better here.
Basically in the past I have written Perl code to organise my MP3 collection, or to add new songs to the collection with the same naming conventions
I've added the code at the end. Maybe someone else will find it useful, or indeed suggest ways to improve it.
Anyway I have a fairly modest - large MP3 collection and searching for duplicates is a time consuming process. Does anybody have a perl script that will identify duplicates in an MP3 collection.
What I was thinking was:
First read in the artist and albums and compare, if a match is found display to user
Secondly compare song titles (from compilations etc), and again display matches
Thirdly compare actual file names.
I would write the script myself, but I am not a great Perl programmer, as anyone who looks at the script below should be able to see so I was hoping someone else would have a similar script that I could re-engineer to suit my needs and then put it back up here.
Thanks
Dace#!/usr/bin/perl use MP3::Tag; use File::Copy; use Getopt::Std; sub usage() { print "\n\n *********************************************************************************** This program will scan all sub-directories for mp3 files. Once found a file will be renamed into: Artist Name - Album - Track Number with leading zero - Track Title.mp3 The file will then be moved to a directory structure of: [Destination]\\Artist Name\\Album You can specify the root directory to search, as well as the destination directory as well as whether to copy a file or move it. Errors are written to log file (c:\\rename_log.txt) Extraneous characters are also removed from ID tags ==================================================================================== usage: $0 -[hdtvcs] -h : this (help) message -d : specify destination. Otherwise c:\Temp is the default. -t : specify test mode. Files are not moved. Should use -v aswell -v : verbose output -m : move files, don't copy -s : specify source directory. -r : scan all subdirectories as well (recursion) Example 1: $0 -s c:\\temp -d c:\\music -v -r This will start in c:\\temp and rename all mp3 files in all subdirectories and move them to c:\\music. It will all write info to the screen (verbose mode) Example 2 $0 -t This will start in the current directory and scan all mp3 files in the current directory only (no recursion). Any problems will be logged to c:\\rename_log.txt, but no files will actually be renamed / moved. This is useful for seeing what problems exist in the files. *********************************************************************************** "; exit; } sub recursive { foreach $file (<*>) { if (-d $file and $Recurse) { chdir $file; &recursive(); chdir ".."; } else { if ($file =~ /.mp3$/) { if ($mp3=MP3::Tag->new($file)) { #Get Tag Info. @info=$mp3->autoinfo; $mp3->new_tag("ID3v1"); $mp3->new_tag("ID3v2"); #Update tags to remove ` which is used in allofmp3.com instead of ' #And it drives me demented. $info[0] =~ s/`/'/g; $info[2] =~ s/`/'/g; $info[3] =~ s/`/'/g; #Update tags to remomve stupid punctuation marks $info[0] =~ s/[\/\\?():]//g; $info[2] =~ s/[\/\\?():]//g; $info[3] =~ s/[\/\\?():]//g; #Re-write new Tags back to file. $mp3->{ID3v1}->artist($info[2]); $mp3->{ID3v1}->album($info[3]); $mp3->{ID3v1}->song($info[0]); $mp3->{ID3v2}->artist($info[2]); $mp3->{ID3v2}->album($info[3]); $mp3->{ID3v2}->song($info[0]); #If there is no track info in the Tag, try get it from filename unless($info[1] =~ m#^(\d+)#) { print "Trying to get track number from filename\n" if $Verbose; #Check at the start of the filename unless($file =~ m/^(d+)/g) { open LOG, ">>c:\rename_log.txt"; print LOG "\n*******************************\n"; print LOG "No Track info found for $file\n"; print LOG "Artist\t $info[2]\n"; print LOG "Album \t $info[3]\n"; print LOG "*******************************\n"; close LOG; $errors = 1; next; } } if($1 < 10) { $songtitle = "$info[2] - $info[3] - 0$1 - $info[0].mp3"; } else { $songtitle = "$info[2] - $info[3] - $1 - $info[0].mp3"; } $mp3->{ID3v1}->track($1); $mp3->{ID3v2}->track($1); $mp3->{ID3v1}->write_tag(); $mp3->{ID3v2}->write_tag(); print "new song name will be $songtitle\n" if $Verbose; $mp3->close(); # rename ($file, $songtitle) unless $Test; unless($Test) { $dest = "$Dest"; mkdir $dest; $dest = "$Dest\\$info[2]"; mkdir $dest; $dest = "$Dest\\$info[2]\\$info[3]"; mkdir $dest; } #add in new file name $dest = "$dest\\$songtitle"; if($Move) { move($file, $dest) unless $Test; } else { print "$dest\n"; copy($file, $dest) unless $Test; } } } } } } #Define the options my $opt_string = 'hd:tvmrs:'; if(@ARGV == 0) { usage(); } getopts( "$opt_string", \%opt ); usage() if $opt{h}; #Set destination directory, c:\Temp by default $Dest = "c:\\Temp"; $Dest = $opt{d} if $opt{d}; #Use test mode if -t option is specified. $Test = 1 if $opt{t}; #Use verbose mode if -v option is specified. $Verbose = 1 if $opt{v}; #Copy files don't move $Move = 1 if $opt{m}; #Recursively scan directories $Recurse = 1 if $opt{r}; #Set directory to one specified on command line chdir($opt{s}) if $opt{s}; #Open current directory and get files. &recursive(); [/SIZE]
0
Comments
-
You could use a hash of hashes that will have the artist/album/track as keys. As you add a MP3 to your library (or find one via dir traversal - File::Find), create an element in the hash. If an element already exists then you have duplicate.0
Advertisement