182 lines
3.3 KiB
Perl
Executable File
182 lines
3.3 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
# mp3rename - Rename MP3 files based on their IDv3 tags.
|
|
#
|
|
# Usage: mp3rename [opts] <mp3s>
|
|
#
|
|
# Examples:
|
|
# mp3rename --format '{artist} - {title}' $HOME/Music/*.mp3
|
|
#
|
|
# This script has POD documentation, so `perldoc mp3rename`
|
|
#
|
|
# --Kirsle
|
|
# http://sh.kirsle.net/
|
|
|
|
=head1 NAME
|
|
|
|
mp3rename - Rename MP3 files based on their IDv3 tags.
|
|
|
|
=head1 USAGE
|
|
|
|
mp3rename [opts] <mp3s>
|
|
|
|
=head1 OPTIONS
|
|
|
|
--format <format>
|
|
-f
|
|
|
|
Specify the format to output the files in. Doesn't need to include
|
|
the .mp3 extension. Example: --format "{artist} - {title}"
|
|
|
|
Format tags include:
|
|
{artist} - Artist
|
|
{album} - Album
|
|
{title} - Song title
|
|
{track} - Track number
|
|
|
|
Default is: {artist} - {title}
|
|
|
|
--output <directory>
|
|
-o
|
|
|
|
Specify a directory to putput the files to. Default is the current
|
|
working directory.
|
|
|
|
--recursive
|
|
-r
|
|
|
|
Recursively descend into any directories included in the arguments.
|
|
By default, directories will just be skipped over.
|
|
|
|
--copy
|
|
-c
|
|
|
|
Copy, don't rename.
|
|
|
|
--test
|
|
-t
|
|
|
|
Show what the files would be renamed to, but don't actually rename
|
|
them.
|
|
|
|
--help
|
|
-h
|
|
-?
|
|
|
|
Show this documentation.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Noah Petherbridge, http://www.kirsle.net/
|
|
|
|
=cut
|
|
|
|
use strict;
|
|
use warnings;
|
|
use File::Basename;
|
|
use File::Path qw(mkpath);
|
|
use File::Copy;
|
|
use Getopt::Long;
|
|
use MP3::Info;
|
|
|
|
# Get command-line arguments.
|
|
my %o = (
|
|
format => '{artist} - {title}',
|
|
output => '.',
|
|
copy => 0,
|
|
recursive => 0,
|
|
test => 0,
|
|
help => 0,
|
|
);
|
|
GetOptions (
|
|
'format|f=s' => \$o{format},
|
|
'output|o=s' => \$o{output},
|
|
'recursive|r' => \$o{recursive},
|
|
'copy|c' => \$o{copy},
|
|
'test|t' => \$o{test},
|
|
'help|h|?' => \$o{help},
|
|
);
|
|
|
|
# Help?
|
|
&help() if $o{help};
|
|
|
|
# Get the file list.
|
|
my @files = @ARGV;
|
|
if (scalar(@files) == 0) {
|
|
&help();
|
|
}
|
|
|
|
foreach my $file (@files) {
|
|
if (-d $file && $o{recursive}) {
|
|
&crawldir($file);
|
|
}
|
|
elsif (-d $file) {
|
|
next;
|
|
}
|
|
&rename($file);
|
|
}
|
|
|
|
sub crawldir {
|
|
my $dir = shift;
|
|
|
|
opendir (DIR, $dir) or die "Can't crawl into directory $dir: $!";
|
|
foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
|
|
next if -l "$dir/$file"; # Don't follow links.
|
|
if (-d "$dir/$file") {
|
|
&crawldir("$dir/$file");
|
|
}
|
|
elsif (-f "$dir/$file") {
|
|
&rename("$dir/$file");
|
|
}
|
|
}
|
|
}
|
|
|
|
sub rename {
|
|
my $file = shift;
|
|
|
|
return unless -f $file;
|
|
my $mp3 = get_mp3tag($file);
|
|
return unless $mp3;
|
|
|
|
my $artist = $mp3->{ARTIST} || "Unknown";
|
|
my $album = $mp3->{ALBUM} || "Unknown";
|
|
my $title = $mp3->{TITLE} || basename($file, ".mp3");
|
|
my $track = $mp3->{TRACKNUM} || "";
|
|
|
|
# Make the new file name.
|
|
my $rename = $o{format};
|
|
$rename .= ".mp3" unless $rename =~ /\.mp3$/i;
|
|
$rename =~ s/{artist}/$artist/ig;
|
|
$rename =~ s/{album}/$album/ig;
|
|
$rename =~ s/{title}/$title/ig;
|
|
$rename =~ s/{track}/$track/ig;
|
|
|
|
my $basename = basename($file);
|
|
|
|
# Just testing?
|
|
if ($o{test}) {
|
|
print "$basename -> $rename\n";
|
|
return;
|
|
}
|
|
|
|
# Make the output directory?
|
|
if (!-d $o{output}) {
|
|
warn "Creating output directory: $o{output}";
|
|
mkpath($o{output}) or die "Can't create $o{output}: $!";
|
|
}
|
|
|
|
# Rename it. Or copy?
|
|
if ($o{copy}) {
|
|
print "COPY: $basename -> $o{output}/$rename\n";
|
|
copy($file,"$o{output}/$rename");
|
|
}
|
|
else {
|
|
print "RENAME: $basename -> $o{output}/$rename\n";
|
|
rename($file, "$o{output}/$rename");
|
|
}
|
|
}
|
|
|
|
sub help {
|
|
exec("perldoc $0");
|
|
}
|