| Category: | Audio Related Programs |
| Author/Contact Info | sacked |
| Description: | This script reads in a list of mp3s (assumed to be in one directory) and organizes them into directories by artist/album. It first attempts to use the id3 tag, but if one is not found, it falls back to parsing the filename for the artist name. I use this script every so often because I download all my mp3s to one directory, and it gets cluttered quickly. The script doesn't have the desired results, however, if mp3s without id3 tags have a hyphen in the filename, but don't have the artist first (e.g., "ice ice baby - vanilla ice.mp3"). This is my first post, please feel free to offer comments/criticism. Thanks! Update: I removed the system calls to /bin/mv and replaced them with calls to rename, after a tip from salvadors. |
#!/usr/bin/perl -w
#
# attempts to organize mp3s into dirs by:
# 1. checking ID3 tag for Artist name
# 2. scanning the filename
#
# it will further organize the mp3s into subdirectories under the
# artist name by album
#
use strict;
use MP3::Info;
use vars qw( $mp3dir @files %dirs );
# change as necessary
#
$mp3dir = '/opt/mp3/';
chdir $mp3dir or die "can't chdir to $mp3dir: $!\n\n";
# get file list
#
opendir(DIR, $mp3dir) or die "can't open $mp3dir for read: $!\n\n";
@files = grep { /\.[Mm][Pp]3$/ } readdir(DIR);
closedir(DIR) or warn "error closing $mp3dir: $!\n\n";
&make_dir_list;
&move_files;
exit;
# create dir listing
# %dirs = ( 'dirname' => { 'subdir1' => [ file1, file2, ... ], ... },
+... );
#
sub make_dir_list {
foreach ( @files ) {
my ($artist, $album, $tag);
# attempt to find artist name through mp3 tag
#
$tag = get_mp3tag( $_ );
# fall back to scanning filename. we're assuming artist name
# is everything up to the first hyphen
#
unless ( $tag && $tag->{ARTIST} !~ /^\s*$/ && $tag->{ARTIST} ne 'a
+rtist' ) {
($artist) = /^([^-]+?)-.+$/;
$artist ||= 'unsorted';
}
else {
$artist = $tag->{ARTIST};
}
$album = $tag->{ALBUM} || "";
if ( $album =~ /^\s*$/ || $album eq 'title' ) { $album = 'misc' }
$artist = clean_name( $artist ) unless $artist eq 'unsorted';
$album = clean_name( $album ) unless $album eq 'misc';
push @{ $dirs{$artist}{$album} }, $_;
}
}
# sanitize artist name (or filename fragment) for use as a dir name
#
sub clean_name {
my $dir = shift;
return 'unsorted' unless $dir;
$dir = lc($dir);
$dir =~ s/\bthe\b//;
$dir =~ s/_/ /g;
$dir =~ s/^ +//;
$dir =~ s/ +$//;
$dir =~ s/ +/ /g;
$dir =~ s/[,(){}\[\]]//g;
return $dir;
}
# create dirs, put sorted files into them
#
sub move_files {
foreach my $artist ( keys %dirs ) {
# XXX debug
#
#print " $artist\n";
unless ( -d qq{$artist} ) {
mkdir( qq{$artist}, 0755 ) or die "error mkdir($artist): $!\n\n"
+;
}
foreach my $album ( keys %{ $dirs{$artist} } ) {
# XXX debug
#
#print " $album\n", map { "\t$_\n" } @{ $dirs{$artist}{$album
+} }, "\n";
unless ( -d qq{$artist/$album} ) {
mkdir( qq{$artist/$album}, 0755 ) or die "error mkdir($artist/
+$album): $
!\n\n";
}
#system('/bin/mv', @{ $dirs{$artist}{$album} }, qq{$artist/$albu
+m/}) == 0
# or die "system('/bin/mv'): $?\n\n";
foreach my $mp3 ( @{ $dirs{$artist}{$album} } ) {
rename $mp3, qq{$artist/$album/$mp3} or die "can't rename $mp3
+: $!\n\n";
}
}
}
}
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: mp3 organizer
by salvadors (Pilgrim) on Jan 31, 2001 at 20:04 UTC | |
by sacked (Hermit) on Feb 01, 2001 at 13:03 UTC | |
|
Re: mp3 organizer
by Anonymous Monk on Aug 23, 2002 at 18:52 UTC | |
by DamnDirtyApe (Curate) on Aug 23, 2002 at 19:06 UTC |