perl与mp3[2]

[入库:2005年8月28日] [更新:2007年3月25日]

本文简介:选择自 wangaimin 的 Blog

基本的 autotag.pl 函数
我把 autotag.pl 几个功能放在了不同的函数中。首先,contains_word_char() 是一个判断某些文本中是否包含某个词(在 Perl 中是 \w in Perl)中的字符的函数。该函数也会正确地处理未定义的值,尽管在警告打开时,常规表达式在匹配未定义的值时会输出警告信息。该函数是极为有用的,因为它不显示警告信息;为了不使用函数而又达到这个目的,您必须检查是否每次都定义了字符串。

清单 1. contains_word_char() 函数

# {{{ contains_word_char: return 1 if the text contains a word character
sub contains_word_char
{
 my $text = shift @_;
 return $text && length $text && $text =~ m/\w/;
}
# }}}

接下来是输入例程。这些程序相当长,它们试图处理程序所需要的用户交互的大多数情况。

清单 2. get_tag() 函数

# {{{ get_tag: get a ID3 V2 tag, using V1 if necessary
sub get_tag
{
 my $file    = shift @_;
 my $upgrade = shift @_;
 my $mp3 = MP3::Tag->new($file);

 return undef unless defined $mp3;

 $mp3->get_tags();

 my $tag = {};

 if (exists $mp3->{ID3v2})
 {
  my $id3v2 = $mp3->{ID3v2};
  my $frames = $id3v2->supported_frames();
  while (my ($fname, $longname) = each %$frames)
  {
   # only grab the frames we know
   next unless exists $supported_frames{$fname};

   $tag->{$fname} = $id3v2->get_frame($fname);
   delete $tag->{$fname} unless defined $tag->{$fname};
   $tag->{$fname} = $tag->{$fname}->{Text} if $fname eq 'COMM';
   $tag->{$fname} = $tag->{$fname}->{URL} if $fname eq 'WXXX';
   $tag->{$fname} = '' unless defined $tag->{$fname};
  }
 }
 elsif (exists $mp3->{ID3v1})
 {
  warn "No ID3 v2 TAG info in $file, using the v1 tag";
  my $id3v1 = $mp3->{ID3v1};
  $tag->{COMM} = $id3v1->comment();
  $tag->{TIT2} = $id3v1->song();
  $tag->{TPE1} = $id3v1->artist();
  $tag->{TALB} = $id3v1->album();
  $tag->{TYER} = $id3v1->year();
  $tag->{TRCK} = $id3v1->track();
  $tag->{TIT1} = $id3v1->genre();

  if ($upgrade && read_yes_no("Upgrade ID3v1 tag to ID3v2 for $file?", 1))
  {
   set_tag($file, $tag);
  }
 }
 else
 {
  warn "No ID3 TAG info in $file, creating it";
  $tag = {
      TIT2 => '',
      TPE1 => '',
      TALB => '',
      TYER => 9999,
      COMM => '',
      };
 }
 print "Got tag ", Dumper $tag
  if $config->DEBUG();
 return $tag;
}
# }}}

惟一一个稍微与众不同的函数是 read_yes_no(),可以给它一个 Y1 的默认参数来使默认值为真,任何其他的参数都会使默认值为假。这样,当用户按下回车键或者空格键时,我可以让 read_yes_no() 函数接受不同的默认值。另外,Backspace 键或 Delete 键将使默认值反转。这段代码不华丽,但很实用。

autotag.pl 的开头部分
应用程序 autotag.pl 以一些初始化例程开始。

清单 3. 初始化

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

本文关键:wangaimin
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top