iTunesで再生中の曲を取得 on Mac(続き)

iTunesで再生中の曲を取得 on Mac
http://d.hatena.ne.jp/rin1024/20110126/1296025445


上の記事で、取得はできたが、
曲名とかが文字化けする問題があったのですが、
locationまで取得できるから、そこからID Tagとってくればやればいんじゃね?ってことでやってみた。


下記を参考にしつつ
http://search.cpan.org/~ilyaz/MP3-Tag-1.13/lib/MP3/Tag/ID3v2.pm

use MP3::Tag;

$mp3 = MP3::Tag->new($filename);

# read an existing tag
$mp3->get_tags();
$id3v2 = $mp3->{ID3v2} if exists $mp3->{ID3v2};
$frameIDs_hash = $id3v2->get_frame_ids('truename');

foreach my $frame (keys %$frameIDs_hash) {
  my ($name, @info) = $id3v2->get_frames($frame);
  for my $info (@info) {
    if (ref $info) {
      print "$name ($frame):\n";
      while(my ($key,$val)=each %$info) {
        print " * $key => $val\n";
      }
    } else {
      print "$name: $info\n";
    }
  }
}


実際に書いたのは下記

#!/usr/bin/perl --

use strict;
use warnings;
use Data::Dumper;
use Mac::Glue;
use MP3::Tag;

my $itunes = new Mac::Glue 'iTunes';
my %tag_to_keys = (
  'Title/songname/content description' => 'artist',
  'Lead performer(s)/Soloist(s)' => 'artist',
  'Title/songname/content description' => 'title',
  'Album/Movie/Show title' => 'album',
  'Year' => 'year',
  'Track number/Position in set' => 'track_number',
  'Content type' => 'genre',
);

sub get_tags {
  my $filename = shift;
  my $tags = {};

  my $mp3 = MP3::Tag->new($filename);
  $mp3->get_tags();

  my $id3v2 = $mp3->{ID3v2};
  my $frameIDs_hash = $id3v2->get_frame_ids('truename');;
  
  foreach my $frame (keys %$frameIDs_hash) {
    my ($name, @info) = $id3v2->get_frames($frame);
    if (exists($tag_to_keys{$name})) {
      $tags->{$tag_to_keys{$name}} ||= Encode::encode('utf-8', $info[0]);
    }
  }

  return $tags;
}

# 再生中の楽曲
my $ctrack = $itunes->prop('current track');
my $clocation = $itunes->get($itunes->prop(location => $ctrack));
my $ctags = get_tags($clocation);
print "current track:", $/;
print Dumper($ctags);
print $/;

# 再整理すとの楽曲一覧
print "track list:", $/;
my $library = $itunes->obj(library_playlist => 1);
my $tracks  = $itunes->obj(tracks => $library);
my @tracks = $itunes->get($tracks);
foreach my $track(@tracks) {
  my $location = $itunes->get($itunes->prop(location => $track));
  my $tags = get_tags($location);
  
  print Dumper($tags);

  last; # デバッグ用
}

1;


実行結果


Yuki-ANAIs-MacBook-Pro:Desktop yuki$ perl itunes.pl
current track:
$VAR1 = {
'album' => '天龍',
'artist' => '天野月子',
'track_number' => '7',
'title' => '蝶',
'genre' => 'J Rock',
'year' => '2004'
};

track list:
$VAR1 = {
'album' => 'Climax Jump',
'artist' => 'AAA',
'track_number' => '1',
'title' => 'Climax Jump',
'genre' => 'Anime/Game',
'year' => '2007'
};


※追記2:mp3以外のファイルがある場合こちらのが便利そう
http://search.cpan.org/~ealleniii/Music-Tag-0.4103/lib/Music/Tag.pm


m4aの場合はエンコードしなくていいが、
mp3の場合はエンコードしないとだめっぽい。


試してみた結果

#!/usr/bin/perl --
=pod
usage: 
  export VERSIONER_PERL_PREFER_32_BIT=yes && \
  perl itunes.pl && \
  export VERSIONER_PERL_PREFER_32_BIT=no
=cut

use strict;
use warnings;
use Data::Dumper;
use Mac::Glue;
use Music::Tag;

my $itunes = new Mac::Glue 'iTunes';
my @tag_name_list = (
  'artist',
  'album',
  'genre',
  'title',
  'year',
  'tracknum',
  'totaltracks',
  'secs',
  #'rating',
  #'playcount',
  #'picture_filename',
  'comment',
  'filetype',
);

main();

# 実行部分
sub main {
  # 再生中の楽曲
  my $ctrack = $itunes->prop('current track');
  my $clocation = $itunes->get($itunes->prop(location => $ctrack));
  my $ctags = get_tags($clocation);
  print "current track:", $/;
  print Dumper($ctags);
  print $/;

  # 再生リストの楽曲一覧
  print "track list:", $/;
  my $library = $itunes->obj(library_playlist => 1);
  my $tracks  = $itunes->obj(tracks => $library);
  my @tracks = $itunes->get($tracks);
  foreach my $track(@tracks) {
    my $location = $itunes->get($itunes->prop(location => $track));
    my $tags = get_tags($location);

    print Dumper($tags);

    last;
  }
}

# ファイルからIDタグを取得
sub get_tags {
  my $filename = shift;
  my $tags = {};

  my $info = Music::Tag->new($filename,  { quiet => 1 });
  $info->get_tag();

  my $filetype = $info->filetype();
  foreach my $tag(@tag_name_list) {
    $tags->{$tag} = $filetype eq 'mp3' ?
      Encode::encode('utf8', $info->$tag()) : 
      $info->$tag();
  }

  return $tags;
}

1;


※追記
このプログラム、IDタグは2v3じゃないとだめっぽいなー。