2008/04/06

iTunesとMac::iTunes

Mac miniのモニタはゲームと兼用で使用しているため、ゲーム中はiTunesの操作ができない。
WindowsのノートからMacのiTunesを操作できれば万事解決すると考え、検索してみるとVNCでどうにかする人が多いようだ。
iTunesだけを操作したいのにVNCは大げさ。
Windows側がへぼいからかVNCのせいかはわからないが、レスポンス悪いし。

Mac同士だとリモート操作用のアプリケーションが出てたりするが、Windows,Mac間となると急に選択肢がなくなった。
結局CPANで検索するとMac::iTunesなるModuleが見つかる。

Mac::iTunesは内部で動的にAppleScriptを生成して、Mac::AppleScriptで実行する実装。
パフォーマンスは高くないが、そもそもそれほど操作する訳でもないのでOK。
Mac::iTunesの作者がApache::iTunesというmod_perlで動くモジュールも公開してたけど、まだAlpha版、すげー遅いって書いてあるので今回はパス。

Term::ReadLineとMac::iTunesで実装してみた。

ショートカットキーやら、表示周りがださいなー。
そして、使ってるうちに日本語の入力が効かないことが発覚。
Macのterminalでは日本語は使えるが、Term::ReadLineを通すとおかしくなる。
WindowsのTera Term経由だとそもそも日本語の入力がおかしい。
まあ、今度考えよう。

一応コードをさらしておく。


#!/usr/bin/perl

use strict;
use warnings;
use Term::ReadLine;
use Mac::iTunes;

our $VERSION = '0.001';

# setup term
my $prompt = 'iTunes> ';
my $term = Term::ReadLine->new($prompt);
my $OUT = $term->OUT || \*STDOUT;
select($OUT);

# setup itunes controller
my $itunes = Mac::iTunes->controller;

my %return_dispatch = (
state => 1,
current_track_name => 1,
pl => 1,
playlist => 1,
get_playlists => 1,
);

my %alias = (
c => 'current_track_name',
p => 'playpause',
s => 'state',
a => 'activate',
q => 'quit',
h => 'help',
pl => 'get_playlists',
playlsit => 'get_playlists',
);

my %show_status = (
p => 1,
play => 1,
stop => 1,
start => 1,
pause => 1,
playpause => 1,
play_track => 1,
);

while ( defined( $_ = $term->readline($prompt) ) ) {
chomp;
my ( $command, @opts ) = split /\x20/, $_;
my $org_command = $command;
$command = $alias{$command} || $command;
if ( $org_command =~ /^(h|help)$/ ) {
help();
}
else {
my $ret = exec_command( $command, @opts );
if ( $show_status{$org_command} ) {
print $itunes->state;
}
my $show_return = $return_dispatch{$command} ? 1 : 0;
$ret = join "\n", @$ret if ref $ret eq 'ARRAY';
print $ret if $show_return;
}
$term->addhistory($_) if /^\S$/;
}

sub exec_command {
my ( $command, @opts ) = @_;
my $ret;
if ( $command eq 'play' and @opts ) {
$command = 'play_track';
unshift @opts, 1;
}
eval { $ret = @opts ? $itunes->$command(@opts) : $itunes->$command; };
warn $@ if $@;
return $ret;
}

sub help {
print << 'HELP';
command list:
a, activate
start itunes if it stopped.
q, quit
quit itunes if it activated.
play [playlist]
start track.
pl, playlist, get_playlists
show list of iTunes playlist.
stop
stop current track.
pause
pause current track.
next
skip current track.
p, playpause
switch play, pause.
c, current_trach_name
show current track name.
h, help
show this message.
HELP
}