#!/usr/bin/perl # # command-line iTunes controller # use strict; my $opts = { usage => \&usage, play => sub { return "play" }, pause => sub { return "playpause" }, stop => sub { return "stop" }, 'next' => sub { return "next track" }, previous => sub { return "previous track" }, url => sub { return "open location " . shift @_ }, info => sub { return ("get artist of current track", "get name of current track") }, state => sub { return "get player state" }, status => sub { return "get player state" }, shuffle => sub { my $arg = shift @_; my $rv = q(set currentPlaylist to view of front window tell currentPlaylist set shuffle to %s end tell); if (defined $arg && lc $arg eq 'off' || $arg eq '0') { $rv = sprintf $rv, "false"; } else { $rv = sprintf $rv, "true"; } return $rv; }, reshuffle => sub { my $num_times = shift @_ || 3; return qq(set currentPlaylist to view of front window repeat $num_times times tell currentPlaylist set shuffle to false set shuffle to true end tell end); }, }; my $op = shift @ARGV || ''; if (exists $opts->{$op}) { my $s = join ', ', map { $_ = osascript($_); chomp; $_ } $opts->{$op}->(@ARGV); print "$s\n" if $s; } else { if ($op =~ m!^http://!i) { osascript($opts->{url}->($op, @ARGV)); } else { usage(); } } # Doesn't return sub usage { print "usage: $0 [operation]\n"; print " where operation is one of: ", join(', ', keys %$opts), "\n"; print "Special operations\n"; print " $0 http://someurl # is the same as $0 url http://someurl\n"; print " $0 reshuffle number_of_times\n"; print " $0 shuffle off # to turn off shuffling\n"; exit; } sub osascript { my $script = shift; require IPC::Open2; my ($read, $write); my $pid = IPC::Open2::open2($read, $write, 'osascript'); print $write qq(tell application "iTunes"\n), $script, qq(\nend tell\n); close $write; my $data = do { local $/; <$read> }; close $read; waitpid $pid, 0; return $data; }