#!/usr/bin/perl -w #######################--INFO--################################ # By Joshua Curtis http://www.curtisonline.net # # This script was made to help in organizing mp3s. If you have # one directory with allot of mp3's and the names are not very # readable you can run this script against them. It will read # the id tag of a mp3 and rename the file to the title of the # song but with _ instead of spaces. It can also create a # directory structure from the id tag if the -c option is used. # The structure will be put in the same directory the mp3s are. # It will be as follows: "/ARTISTNAME/CDTITLE/SONG.mp3" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # You must always use the absolute path to the mp3s #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # # COPYRIGHT: # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #######################--REVISION LIST--######################## # 2/11/00 v0.1 Script first made public # 2/13/00 v0.11 Cleaned up and enhanced by # Cristian Ionescu-Idbohrn . # Copes with blank instead of null characters # as tag separators. # Corrected some directory inconsistencies. Absolute # paths are now used. # Added -l log option. # Should work on both UNIX like and windoz systems. ################################################################ #==============================================================# use strict; use vars qw/$createdirs $dir $option $null $show_log/; #################################################### # Find out what we have and what to do #################################################### # This is where we check for input and make sure # we have all needed options. if (! @ARGV) { &ShowUsage(); exit; } $show_log = 0; foreach $option (@ARGV) { if ($option =~ /(--help|-h)/) { &ShowUsage(); exit; } elsif ($option =~ /^-d=.*?/) { ($null, $dir) = split(/=/, $option); $dir =~ s/\s*$//; $dir =~ s/\/$//; $dir =~ s/\s*$//; } elsif ($option =~ /^-c$/) { $createdirs = "1"; } elsif ($option =~ /^-l$/) { $show_log = "1"; } else { print "*** Bad option \"$option\"\n"; &ShowUsage(); exit; } } if ($dir) { ReadFiles($dir); } else { &ShowUsage(); exit; } #################################################### # ShowUsage() #################################################### # Shows the usage of the program. # Called with no options. sub ShowUsage { print " Usage: sort_mp3.pl [options] Options should be seperated by a space and my be in any order. -c Create a directory structure from the mp3 tag. It is made inside the directory holding the un-named mp3s. If not set the files will just be renamed. Example: \"/ARTISTNAME/CDTITLE/SONG.mp3\" -d= Path to the directory where mp3's can be found. There should be no spaces in the path name. Example: \"-d=/unsorted_mp3s\" -l Show what's goin' on (default: keeps quiet). CAVEAT Tags may be separated by blank instead of null characters. More than 1 blank character, anywhere in the \"Artist Name\", \"CD Title\" or \"Song Title\" will leed to unpredictible results. "; } #################################################### # ReadFiles() #################################################### # Reads all the file names *.mp3 from the directory # defined with the -d= option. It then passes the # mp3 name to Rename. sub ReadFiles { my ($dir) = @_; my $file; opendir(DIR, $dir) or die "*** Can't open \"$dir\": $!"; while (defined($file = readdir DIR)) { next if $file !~ /.mp3$/ig; &ReNameMP3($dir . "/" . $file); } close(DIR); } #################################################### # ReName() #################################################### # Renames the mp3 by getting the track title from # id tag inside the mp3. It will also make a path # to put the file in if the -c option is set. # the path will be "/ARTISTNAME/CDTITLE/SONG.mp3" sub ReNameMP3 { my ($mp3) = @_; my $tag_uf; my %tag; my $path_created = "No"; my $got_it_all = 0; open(MP3, "< $mp3") or die "*** Can't open \"$mp3\": $!"; binmode(MP3); seek(MP3, -225, 2); read(MP3, $tag_uf, "225"); close(MP3); $tag_uf =~ s/[^A-Za-z0-9_\'\"-.\s\0]//g; $tag_uf =~ s/[ ][ ]+/\0/g; $tag_uf =~ s/[\0]+/:/g; $tag_uf =~ s/.*?TAG(.*?)/:$1/; $tag_uf =~ /:(.*?):(.*?):(.*?):.*?:/; $tag{songtitle} = $tag{filename} = $1; $tag{artist} = $tag{artistfolder} = $2; $tag{cdtitle} = $tag{cdfolder} = $3; $got_it_all = 1 if defined($1) and defined($2) and defined($3); print "*** Song Title missing in \"$mp3\"\n" if ! defined($1); print "*** Artist Name missing in \"$mp3\"\n" if ! defined($2); print "*** CD Title missing in \"$mp3\"\n" if ! defined($3); die "*** Aborting" if ! $got_it_all; if ($tag{cdtitle} and $tag{artist} and $tag{songtitle}) { $tag{filename} =~ s/[\s]+/_/g; $tag{cdfolder} =~ s/[\s]+/_/g; $tag{artistfolder} =~ s/[\s]+/_/g; if ($createdirs) { mkdir("$dir/$tag{artistfolder}", 777); mkdir("$dir/$tag{artistfolder}/$tag{cdfolder}", 777); $tag{filename} = "$dir/$tag{artistfolder}/$tag{cdfolder}/$tag{filename}"; $path_created = "Yes"; } else { $tag{filename} = "$dir/$tag{filename}"; } $tag{filename} = "$tag{filename}.mp3"; rename($mp3, "$tag{filename}") or die "*** Failed to rename \"$mp3\""; # Print a log of the renamed files, if requested. print " Artist Name: $tag{artist} CD Title: $tag{cdtitle} Song Title: $tag{songtitle} Old File Name: $mp3 New File Name: $tag{filename} Created Path: $path_created\n" if $show_log; } }