perl与mp3
惟一一个稍微与众不同的函数是 read_yes_no(),可以给它一个 Y 或 1 的默认参数来使默认值为真,任何其他的参数都会使默认值为假。这样,当用户按下回车键或者空格键时,我可以让 read_yes_no() 函数接受不同的默认值。另外,Backspace 键或 Delete 键将使默认值反转。这段代码不华丽,但很实用。
autotag.pl 的开头部分
应用程序 autotag.pl 以一些初始化例程开始。
use constant SEARCH_ALL => 'all';
my %freedb_searches = (
artist => { keywords => [], abbrev => 'I', tagequiv => 'TPE1' },
title => { keywords => [], abbrev => 'T', tagequiv => 'TALB' },
track => { keywords => [], abbrev => 'K', tagequiv => 'TIT2' },
rest => { keywords => [], abbrev => 'R', tagequiv => 'COMM' },
);
# maps ID3 v2 tag info to WebService::FreeDB info
my %info2freedb = (
TALB => 'cdname',
TPE1 => 'artist',
);
my %supported_frames = (
TIT1 => 1,
TIT2 => 1,
TRCK => 1,
TALB => 1,
TPE1 => 1,
COMM => 1,
WXXX => 1,
TYER => 1,
);
my @supported_frames = keys %supported_frames;
my $term = new Term::ReadLine 'Input> '; # global input
|
EARCH_ALL 是一个常数,当用户想在任何地方搜寻一个词的时候,比如曲目名、艺术家名等,就会使用它。为了防止有人想把它改为另外某个值,我把它设定为常数,但它也可能已经被硬编码为“all”。
%freedb_searches 散列将 FreeDB 字段映射到有关它们的信息上,包括 ID3v2 标签元素。例如,它说明 FreeDB 怎样称呼那些在 MP3 标签中被称为“TPE1”的“artist”。在该散列条目中的“abbrev”字段被用来定义命令行开关,这样,随后我可以基于 %freedb_searches 信息定义一个 -artist 开关,它可以被简写为 -i 。
%info2freedb 散列将光盘中的所有曲目的 FreeDB 字段都映射到 ID3v2 字段。它们不是 %freedb_searches 中的字段,这是一种不同的映射,它表明,对于一个光盘集的所有曲目而言,“cdname”和 “artists”(也分别被称为“TALB”和“TPE1”)是相同的。
我将用 %supported_frames 散列和 @supported_frames 列表来表示我支持哪些 ID3v2 标签元素。我是从该列表生成了这个散列,而不是从该散列中获得这个列表(解释两者之间的差别离题太远,所以不再赘述)。大规模加注标签时,以及在编写 ID3v2 标签时,都要用到已获支持的框架(我只是修改已获支持的框架而已)。
最后,为了让用户在整个应用程序中输入数据,我创建了一个 Term::ReadLine 对象。
下面,我初始化 AppConfig 选项,这样做虽然加重了我的负担,但是有益的。
清单 4. AppConfig 的初始化
# {{{ set up AppConfig and process -help
my $config = AppConfig->new();
$config->define(
DEBUG =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => 0, ALIAS => 'D' },
CONFIG_FILE =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => 0, ALIAS => 'F' },
HELP =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'H' },
DUMP =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0 },
ACCEPT_ALL =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'C' },
DRYRUN =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'N' },
GUESS_TRACK_NUMBERS_ONLY =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'G' },
STRIP_COMMENT_ONLY =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'SC' },
MASS_TAG_ONLY =>
{ ARGCOUNT => ARGCOUNT_HASH, ALIAS => 'M' },
RENAME_ONLY =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => 0, ALIAS => 'RO' },
RENAME_MAX_CHARS =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => 30},
RENAME_FORMAT =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => '%a-%t-%n-%c-%s.mp3'},
RENAME_BADCHARS =>
{ ARGCOUNT => ARGCOUNT_LIST, ALIAS => 'RB' },
RENAME_REPLACECHARS =>
{ ARGCOUNT => ARGCOUNT_LIST, ALIAS => 'RR' },
RENAME_REPLACEMENT =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => '_' },
FREEDB_HOST =>
{ ARGCOUNT => ARGCOUNT_ONE, DEFAULT => 'http://www.freedb.org', },
OR =>
{ ARGCOUNT => ARGCOUNT_NONE, DEFAULT => '0', },
SEARCH_ALL() =>
{ ARGCOUNT => ARGCOUNT_LIST, ALIAS => 'A' },
);
foreach my $search (keys %freedb_searches)
{
$config->define($search => {
ARGCOUNT => ARGCOUNT_LIST,
ALIAS => $freedb_searches{$search}->{abbrev},
});
}
$config->args();
$config->file($config->CONFIG_FILE())
if $config->CONFIG_FILE();
unless (scalar @{$config->RENAME_BADCHARS()})
{
push @{$config->RENAME_BADCHARS()}, split(//, "\"`!'?&[]()/;\n\t");
}
unless (scalar @{$config->RENAME_REPLACECHARS()})
{
push @{$config->RENAME_REPLACECHARS()}, split(//, " ");
}
if ($config->HELP())
{
print <<EOHIPPUS;
$0 [options] File1.mp3 File2.mp3 ...
Options:
-help (-h) : print this help
-config_file (-f) N : use this config file, see AppConfig module docs for format
-debug (-d) N : print debugging information (level N, 0 is lowest)
-dump : just dump the list of albums and tracks within them
-dryrun (-n) : do everything but modify the MP3 files
-freedb_host H : set the FreeDB host, default "www.freedb.org"
-or : search for keyword A or keyword B, not A and B as usual
-accept_all (c) : accept all search results for consideration for each file,
also accept all renames without asking
-rename_badchars (-rb) A -rb B : characters A and B to remove when renaming
-rename_replacechars (-rr) A -rr B : characters A and B to replace
when renaming
-rename_maxchars N : use at most this many characters from a tag
element when renaming, default: ${\$config->RENAME_MAX_CHARS()}
-rename_replacement X : character to use when replacing,
default: [${\$config->RENAME_REPLACEMENT()}]
-rename_format (-f) F : format for renaming; default "${\$config->RENAME_FORMAT()}"
%a -> Artist
%t -> Track number
%n -> Album name
%c -> Comment
%s -> Song title
-guess_track_numbers_only (-g) : guess track numbers using the file
name, then exit
-rename_only (-ro) : rename tracks using the given format (see
-rename_format), then exit
-mass_tag_only (-m) A=X -m B=Y : mass-tag files (tag element A is X,
B is Y), then exit (tag elements
available: @supported_frames)
-strip_comment_only (-sc) : strip comments and URLs, then exit
Repeatable options (you can specify them more than once, K is the keyword):
-all (-a) K : search everywhere
-artist (-i) K : search for these artists
-title (-t) K : search for these titles
-track (-k) K : search for these tracks
-rest (-r) K : search for these keywords everywhere else
Note that the repeatable options are cumulative, so artist A and title
B will produce matches for A and B, not A or B. In the same way,
artist A and artist B will produce matches for A and B, not A or B.
If you want to match A or B terms, use -or, for instance:
$0 -or -artist "pink floyd" -artist "fred flintstone"
EOHIPPUS
exit;
}
# }}}
|
Tags:perl,mp

