#!/usr/bin/perl # # Vorbiscomment from Filename # usage: vcfromfilename [options] # options: # -n: Only set the track number # -0: Leading 0s in track number are preserved # -T: Tag names (not tag content) written to the metadata in all caps # # Adds Vorbiscomment data to ogg vorbis and flac files based on the filename. # Files should be in Anna's arbitrary file name standard, which is: # artist/album/artist-tracknum-title.(ogg|flac|mp3) # # The top-level directory (artist) is optional. Filenames should contain no # spaces; underscores in the filename are converted to spaces in the resulting # metadata # # Requires vorbiscomment and metaflac # # Changelog: # 0.2.4: added -T option # added releasedate support through MusicBrainz # added mp3 support and refactored code heavily # added -y option to explicitly look for the year # 0.2.3: added documentation, -0 command-line option # 0.2.2: added flac support, documentation # 0.2.1: fixed version in help message # fixed handling of dashes in artist name and title # 0.2: aligned version with ds-audiotools # 0.1.1: added version variable # 0.1: initial implementation $VERSION = "0.2.4"; $HELP_MSG = "Vorbiscomment from Filename $VERSION\n\tusage: vcfromfilename [options] \n\nValid options:\n\t-n\tOnly set the track numbers\n\t-0\tPreserve leading 0s in track numbers\n\t-T: Write tag names (not tag content) in all caps\n"; use Music::Tag; chomp($COMMENTFILENAME = '/tmp/vcfromfilename-' . `whoami`); # Look for options foreach (@ARGV) { if (/^(-h)|(--help)$/) { die $HELP_MSG; } elsif (/^-n$/) { $tracknumonly = true; s/.*//g; } elsif (/^-T$/) { $captagnames = true; s/.*//g; } elsif (/^-0$/) { $extrazero = true; s/.*//g; } elsif (/^-y$/) { $get_year = true; s/.*//g; } else { push @tracks, $_; } } # Set the mode if ($tracks[0] =~ /\.flac$/) { $mode = 'flac'; } elsif ($tracks[0] =~ /\.mp3$/) { $mode = 'mp3'; } elsif ($tracks[0] =~ /\.ogg$/) { $mode = 'ogg'; } else { die "Couldn't detect mode"; } # Set the album name $album = `pwd`; # We WANT the newline here $album =~ s/^.*\///; # Remove everything up to the last / $album = formatName($album, 'album=', $captagnames, $mode); # Try to find the release date $year; if ($get_year) { $mbinfo = Music::Tag->new($tracks[0]); if ($mode eq 'ogg') { $mbinfo->add_plugin($mbinfo->plugin("OGG")); } elsif ($mode eq 'flac') { $mbinfo->add_plugin($mbinfo->plugin("FLAC")); } elsif ($mode eq 'mp3') { $mbinfo->add_plugin($mbinfo->plugin("MP3")); } $mbinfo->add_plugin("MusicBrainz"); $mbinfo->get_tag(); $year = formatName($mbinfo->year, 'year=', $captagnames, $mode); } # Parse the file list, set comments foreach (@ARGV) { next if (/^$/); # check filename format next unless (/^\w+-\d{1,2}-(\w|-|\d)+\.(ogg|flac|mp3)$/); if ($mode eq 'flac' || $mode eq 'ogg') { open COMMENTFILE, '>' . $COMMENTFILENAME; } # Remove old comments if ($mode eq 'flac') { system("metaflac --remove-tag=TRACKNUMBER $_"); system("metaflac --remove-tag=tracknumber $_"); if (!$tracknumonly) { system("metaflac --remove-tag=TITLE --remove-tag=ARTIST --remove-tag=ALBUM --remove-tag=YEAR $_"); system("metaflac --remove-tag=title --remove-tag=artist --remove-tag=album --remove-tag=year $_"); } } elsif ($mode eq 'mp3') { system("id3v2 -D $_"); } # For ogg, preserve existing comments, except the ones we'll replace else { foreach (`vorbiscomment -l $_`) { if ($tracknumonly) { print COMMENTFILE $_ unless (/^tracknumber/i); } else { print COMMENTFILE $_ unless (/^(title)|(artist)|(tracknumber)|(album)|(year)/i); } } } # Create new comments from the filename if (!$tracknumonly) { # Add the artist $artist = $_; $artist =~ s/^(.*?)-\d{2}-.*/\1/; # grab everything to the track number $artist = formatName($artist, 'artist=', $captagnames, $mode); # Add the title $title = $_; $title =~ s/.*-\d{2}-(.*)\.(ogg|flac|mp3)$/\1/; # grab everything after the track number $title = formatName($title, 'title=', $captagnames, $mode); # For some modes, print everything to a comment file if ($mode eq 'flac' || $mode eq 'ogg') { print COMMENTFILE $year; print COMMENTFILE $artist; print COMMENTFILE $title; print COMMENTFILE $album; } } # Now get the track number my $tracknum = $_; $tracknum =~ s/.*-(\d{2})-.*/\1/; if (!$extrazero) { $tracknum =~ s/\b0*//; } # removing leading zeros $tracknum = formatName($tracknum, 'tracknumber=', $captagnames, $mode); if ($mode eq 'flac' || $mode eq 'ogg') { print COMMENTFILE $tracknum; close COMMENTFILE; } if ($mode eq 'flac') { system("metaflac --import-tags-from=$COMMENTFILENAME $_"); } elsif ($mode eq 'mp3') { $tags = ""; $tags .= "-T $tracknum" if $tracknum; if (!$tracknumonly) { $tags .= " -a '$artist'" if $artist; $tags .= " -t '$title'" if $title; $tags .= " -A '$album'" if $album; $tags .= " -y $year" if $year; } system("id3v2 $tags $_"); } elsif ($mode eq 'ogg') { system("vorbiscomment -c $COMMENTFILENAME -w $_"); } if ($mode eq 'flac' || $mode eq 'ogg') { system('rm', $COMMENTFILENAME); } } # Formats the first argument, adds the second argument to it # If the third argument is true, the second argument is converted # to upper case sub formatName { my $name = shift; my $prepend = shift; my $upper = shift; my $mode = shift; if ($upper) { $prepend = uc($prepend); } chomp $name; # we add a newline ourselves $name =~ s/_/ /g; # underscore - space $name =~ s/^\s*//; # Remove leading space $name =~ s/\s*$//; # Remove trailing space $name =~ s/\b(\w)/uc($1)/eg; # Cap the words if ($mode eq 'flac' || $mode eq 'ogg') { $name = $prepend . $name . "\n"; } return $name; } # 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA