[project @ 5884]
[audio-mpd.git] / lib / Audio / MPD.pm
blobf6754ddd9548e073497fa0b8bfb5866b0e2b5e74
2 # This program is free software; you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation; either version 2 of the License, or
5 # (at your option) any later version.
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
12 # You should have received a copy of the GNU General Public License
13 # along with this program; if not, write to the Free Software
14 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 package Audio::MPD;
20 use warnings;
21 use strict;
23 use Audio::MPD::Collection;
24 use Audio::MPD::Item;
25 use Audio::MPD::Playlist;
26 use Audio::MPD::Stats;
27 use Audio::MPD::Status;
28 use Encode;
29 use IO::Socket;
32 use base qw[ Class::Accessor::Fast ];
33 __PACKAGE__->mk_accessors(
34 qw[ _host _password _port
35 collection playlist version ] );
38 our $VERSION = '0.17.2';
41 #--
42 # Constructor
45 # my $mpd = Audio::MPD->new( [$hostname], [$port], [$password] )
47 # This is the constructor for Audio::MPD. One can specify a $hostname, a
48 # $port, and a $password.
49 # If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
50 # and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
52 sub new {
53 my $class = shift;
54 my ($host, $port, $password) = @_;
56 # use mpd defaults.
57 $host = $ENV{MPD_HOST} || 'localhost' unless defined $host;
58 $port = $ENV{MPD_PORT} || '6600' unless defined $port;
59 $password = $ENV{MPD_PASSWORD} || '' unless defined $password;
61 # create & bless the object.
62 my $self = {
63 _host => $host,
64 _port => $port,
65 _password => $password,
67 bless $self, $class;
69 # create the helper objects and store them.
70 $self->collection( Audio::MPD::Collection->new($self) );
71 $self->playlist ( Audio::MPD::Playlist->new($self) );
73 # try to issue a ping to test connection - this can die.
74 $self->ping;
76 return $self;
80 #--
81 # Private methods
85 # my @result = $mpd->_send_command( $command );
87 # This method is central to the module. It is responsible for interacting with
88 # mpd by sending the $command and reading output - that will be returned as an
89 # array of chomped lines (status line will not be returned).
91 # Note that currently, this method will connect to mpd before sending any
92 # command, and will disconnect after the command has been issued. This scheme
93 # is far from optimal, but allows us not to care about timeout disconnections.
95 # /!\ Note that we're using high-level, blocking sockets. This means that if
96 # the mpd server is slow, or hangs for whatever reason, or even crash abruptly,
97 # the program will be hung forever in this sub. The POE::Component::Client::MPD
98 # module is way safer - you're advised to use it instead of Audio::MPD.
100 # This method can die on several conditions:
101 # - if the server cannot be reached,
102 # - if it's not an mpd server,
103 # - if the password is incorrect,
104 # - or if the command is an invalid mpd command.
105 # In the latter case, the mpd error message will be returned.
107 sub _send_command {
108 my ($self, $command) = @_;
110 # try to connect to mpd.
111 my $socket = IO::Socket::INET->new(
112 PeerAddr => $self->_host,
113 PeerPort => $self->_port
115 or die "Could not create socket: $!\n";
116 my $line;
118 # parse version information.
119 $line = $socket->getline;
120 chomp $line;
121 die "Not a mpd server - welcome string was: [$line]\n"
122 if $line !~ /^OK MPD (.+)$/;
123 $self->version($1);
125 # send password.
126 if ( $self->_password ) {
127 $socket->print( 'password ' . encode('utf-8', $self->_password) . "\n" );
128 $line = $socket->getline;
129 die $line if $line =~ s/^ACK //;
132 # ok, now we're connected - let's issue the command.
133 $socket->print( encode('utf-8', $command) );
134 my @output;
135 while (defined ( $line = $socket->getline ) ) {
136 chomp $line;
137 die $line if $line =~ s/^ACK //; # oops - error.
138 last if $line =~ /^OK/; # end of output.
139 push @output, decode('utf-8', $line);
142 # close the socket.
143 $socket->close;
145 return @output;
150 # my @items = $mpd->_cooked_command_as_items( $command );
152 # Lots of Audio::MPD methods are using _send_command() and then parse the
153 # output as a collection of Audio::MPD::Item. This method is meant to
154 # factorize this code, and will parse the raw output of _send_command() in
155 # a cooked list of items.
157 sub _cooked_command_as_items {
158 my ($self, $command) = @_;
160 my @lines = $self->_send_command($command);
161 my (@items, %param);
163 # parse lines in reverse order since "file:" or "directory:" lines
164 # come first. therefore, let's first store every other parameter,
165 # and the last line will trigger the object creation.
166 # of course, since we want to preserve the playlist order, this means
167 # that we're going to unshift the objects instead of push.
168 foreach my $line (reverse @lines) {
169 my ($k,$v) = split /:\s+/, $line, 2;
170 $param{$k} = $v;
171 next unless $k eq 'file' || $k eq 'directory'; # last param of item
172 unshift @items, Audio::MPD::Item->new(%param);
173 %param = ();
176 return @items;
181 # my %hash = $mpd->_cooked_command_as_kv( $command );
183 # Lots of Audio::MPD methods are using _send_command() and then parse the
184 # output to get a list of key / value (with the colon ":" acting as separator).
185 # This method is meant to factorize this code, and will parse the raw output
186 # of _send_command() in a cooked hash.
188 sub _cooked_command_as_kv {
189 my ($self, $command) = @_;
190 my %hash =
191 map { split(/:\s+/, $_, 2) }
192 $self->_send_command($command);
193 return %hash;
197 # my @list = $mpd->_cooked_command_strip_first_field( $command );
199 # Lots of Audio::MPD methods are using _send_command() and then parse the
200 # output to remove the first field (with the colon ":" acting as separator).
201 # This method is meant to factorize this code, and will parse the raw output
202 # of _send_command() in a cooked list of strings.
204 sub _cooked_command_strip_first_field {
205 my ($self, $command) = @_;
207 my @list =
208 map { ( split(/:\s+/, $_, 2) )[1] }
209 $self->_send_command($command);
210 return @list;
215 # Public methods
217 # -- MPD interaction: general commands
220 # $mpd->ping;
222 # Sends a ping command to the mpd server.
224 sub ping {
225 my ($self) = @_;
226 $self->_send_command( "ping\n" );
231 # my $version = $mpd->version;
233 # Return version of MPD server's connected.
235 # sub version {} # implemented as an accessor.
240 # $mpd->kill;
242 # Send a message to the MPD server telling it to shut down.
244 sub kill {
245 my ($self) = @_;
246 $self->_send_command("kill\n");
251 # $mpd->password( [$password] )
253 # Change password used to communicate with MPD server to $password.
254 # Empty string is assumed if $password is not supplied.
256 sub password {
257 my ($self, $passwd) = @_;
258 $passwd ||= '';
259 $self->_password($passwd);
260 $self->ping; # ping sends a command, and thus the password is sent
265 # $mpd->updatedb( [$path] );
267 # Force mpd to recan its collection. If $path (relative to MPD's music
268 # directory) is supplied, MPD will only scan it - otherwise, MPD will rescan
269 # its whole collection.
271 sub updatedb {
272 my ($self, $path) = @_;
273 $path ||= '';
274 $self->_send_command("update $path\n");
279 # my @handlers = $mpd->urlhandlers;
281 # Return an array of supported URL schemes.
283 sub urlhandlers {
284 my ($self) = @_;
285 return $self->_cooked_command_strip_first_field("urlhandlers\n");
289 # -- MPD interaction: handling volume & output
292 # $mpd->volume( [+][-]$volume );
294 # Sets the audio output volume percentage to absolute $volume.
295 # If $volume is prefixed by '+' or '-' then the volume is changed relatively
296 # by that value.
298 sub volume {
299 my ($self, $volume) = @_;
301 if ($volume =~ /^(-|\+)(\d+)/ ) {
302 my $current = $self->status->volume;
303 $volume = $1 eq '+' ? $current + $2 : $current - $2;
305 $self->_send_command("setvol $volume\n");
310 # $mpd->output_enable( $output );
312 # Enable the specified audio output. $output is the ID of the audio output.
314 sub output_enable {
315 my ($self, $output) = @_;
316 $self->_send_command("enableoutput $output\n");
321 # $mpd->output_disable( $output );
323 # Disable the specified audio output. $output is the ID of the audio output.
325 sub output_disable {
326 my ($self, $output) = @_;
327 $self->_send_command("disableoutput $output\n");
332 # -- MPD interaction: retrieving info from current state
335 # $mpd->stats;
337 # Return an Audio::MPD::Stats object with the current statistics of MPD.
339 sub stats {
340 my ($self) = @_;
341 my %kv = $self->_cooked_command_as_kv( "stats\n" );
342 return Audio::MPD::Stats->new(%kv);
347 # my $status = $mpd->status;
349 # Return an Audio::MPD::Status object with various information on current
350 # MPD server settings. Check the embedded pod for more information on the
351 # available accessors.
353 sub status {
354 my ($self) = @_;
355 my %kv = $self->_cooked_command_as_kv( "status\n" );
356 my $status = Audio::MPD::Status->new( %kv );
357 return $status;
362 # my $song = $mpd->current;
364 # Return an C<Audio::MPD::Item::Song> representing the song currently playing.
366 sub current {
367 my ($self) = @_;
368 my ($item) = $self->_cooked_command_as_items("currentsong\n");
369 return $item;
374 # my $song = $mpd->song( [$song] )
376 # Return an C<Audio::MPD::Item::Song> representing the song number C<$song>.
377 # If C<$song> is not supplied, returns the current song.
379 sub song {
380 my ($self, $song) = @_;
381 return $self->current unless defined $song;
382 my ($item) = $self->_cooked_command_as_items("playlistinfo $song\n");
383 return $item;
388 # my $song = $mpd->songid( [$songid] )
390 # Return an C<Audio::MPD::Item::Song> representing the song with id C<$songid>.
391 # If C<$songid> is not supplied, returns the current song.
393 sub songid {
394 my ($self, $songid) = @_;
395 return $self->current unless defined $songid;
396 my ($item) = $self->_cooked_command_as_items("playlistid $songid\n");
397 return $item;
401 # -- MPD interaction: altering settings
404 # $mpd->repeat( [$repeat] );
406 # Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
407 # the repeat mode is toggled.
409 sub repeat {
410 my ($self, $mode) = @_;
412 $mode = not $self->status->repeat
413 unless defined $mode; # toggle if no param
414 $mode = $mode ? 1 : 0; # force integer
415 $self->_send_command("repeat $mode\n");
420 # $mpd->random( [$random] );
422 # Set the random mode to $random (1 or 0). If $random is not specified then
423 # the random mode is toggled.
425 sub random {
426 my ($self, $mode) = @_;
428 $mode = not $self->status->random
429 unless defined $mode; # toggle if no param
430 $mode = $mode ? 1 : 0; # force integer
431 $self->_send_command("random $mode\n");
436 # $mpd->fade( [$seconds] );
438 # Enable crossfading and set the duration of crossfade between songs. If
439 # $seconds is not specified or $seconds is 0, then crossfading is disabled.
441 sub fade {
442 my ($self, $value) = @_;
443 $value ||= 0;
444 $self->_send_command("crossfade $value\n");
448 # -- MPD interaction: controlling playback
451 # $mpd->play( [$song] );
453 # Begin playing playlist at song number $song. If no argument supplied,
454 # resume playing.
456 sub play {
457 my ($self, $number) = @_;
458 $number = '' unless defined $number;
459 $self->_send_command("play $number\n");
463 # $mpd->playid( [$songid] );
465 # Begin playing playlist at song ID $songid. If no argument supplied,
466 # resume playing.
468 sub playid {
469 my ($self, $number) = @_;
470 $number ||= '';
471 $self->_send_command("playid $number\n");
476 # $mpd->pause( [$sate] );
478 # Pause playback. If $state is 0 then the current track is unpaused, if
479 # $state is 1 then the current track is paused.
481 # Note that if $state is not given, pause state will be toggled.
483 sub pause {
484 my ($self, $state) = @_;
485 $state ||= ''; # default is to toggle
486 $self->_send_command("pause $state\n");
491 # $mpd->stop;
493 # Stop playback.
495 sub stop {
496 my ($self) = @_;
497 $self->_send_command("stop\n");
502 # $mpd->next;
504 # Play next song in playlist.
506 sub next {
507 my ($self) = @_;
508 $self->_send_command("next\n");
512 # $mpd->prev;
514 # Play previous song in playlist.
516 sub prev {
517 my($self) = shift;
518 $self->_send_command("previous\n");
523 # $mpd->seek( $time, [$song]);
525 # Seek to $time seconds in song number $song. If $song number is not specified
526 # then the perl module will try and seek to $time in the current song.
528 sub seek {
529 my ($self, $time, $song) = @_;
530 $time ||= 0; $time = int $time;
531 $song = $self->status->song if not defined $song; # seek in current song
532 $self->_send_command( "seek $song $time\n" );
537 # $mpd->seekid( $time, $songid );
539 # Seek to $time seconds in song ID $songid. If $song number is not specified
540 # then the perl module will try and seek to $time in the current song.
542 sub seekid {
543 my ($self, $time, $song) = @_;
544 $time ||= 0; $time = int $time;
545 $song = $self->status->songid if not defined $song; # seek in current song
546 $self->_send_command( "seekid $song $time\n" );
554 __END__
556 =pod
558 =head1 NAME
560 Audio::MPD - class to talk to MPD (Music Player Daemon) servers
563 =head1 SYNOPSIS
565 use Audio::MPD;
567 my $mpd = Audio::MPD->new();
568 $mpd->play();
569 sleep 10;
570 $mpd->next();
573 =head1 DESCRIPTION
575 Audio::MPD gives a clear object-oriented interface for talking to and
576 controlling MPD (Music Player Daemon) servers. A connection to the MPD
577 server is established as soon as a new Audio::MPD object is created.
578 Commands are then sent to the server as the class's methods are called.
581 =head1 METHODS
583 =head2 Constructor
585 =over 4
587 =item new( [$host] [, $port] [, $password] )
589 This is the constructor for Audio::MPD. One can specify a $hostname, a
590 $port, and a $password.
592 If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
593 and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
595 =back
598 =head2 Controlling the server
600 =over 4
602 =item $mpd->ping()
604 Sends a ping command to the mpd server.
607 =item $mpd->version()
609 Return the version number for the server we are connected to.
612 =item $mpd->kill()
614 Send a message to the MPD server telling it to shut down.
617 =item $mpd->password( [$password] )
619 Change password used to communicate with MPD server to $password.
620 Empty string is assumed if $password is not supplied.
623 =item $mpd->updatedb( [$path] )
625 Force mpd to recan its collection. If $path (relative to MPD's music directory)
626 is supplied, MPD will only scan it - otherwise, MPD will rescan its whole
627 collection.
630 =item $mpd->urlhandlers()
632 Return an array of supported URL schemes.
635 =back
638 =head2 Handling volume & output
640 =over 4
642 =item $mpd->volume( [+][-]$volume )
644 Sets the audio output volume percentage to absolute $volume.
645 If $volume is prefixed by '+' or '-' then the volume is changed relatively
646 by that value.
649 =item $mpd->output_enable( $output )
651 Enable the specified audio output. $output is the ID of the audio output.
654 =item $mpd->output_disable( $output )
656 Disable the specified audio output. $output is the ID of the audio output.
658 =back
661 =head2 Retrieving info from current state
663 =over 4
665 =item $mpd->stats()
667 Return an C<Audio::MPD::Stats> object with the current statistics of MPD.
668 See the associated pod for more information.
671 =item $mpd->status()
673 Return an C<Audio::MPD::Status> object with various information on current
674 MPD server settings. Check the embedded pod for more information on the
675 available accessors.
678 =item $mpd->current()
680 Return an C<Audio::MPD::Item::Song> representing the song currently playing.
683 =item $mpd->song( [$song] )
685 Return an C<Audio::MPD::Item::Song> representing the song number C<$song>. If
686 C<$song> is not supplied, returns the current song.
689 =item $mpd->songid( [$songid] )
691 Return an C<Audio::MPD::Item::Song> representing the song with id C<$songid>.
692 If C<$songid> is not supplied, returns the current song.
694 =back
697 =head2 Altering MPD settings
699 =over 4
701 =item $mpd->repeat( [$repeat] )
703 Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
704 the repeat mode is toggled.
707 =item $mpd->random( [$random] )
709 Set the random mode to $random (1 or 0). If $random is not specified then
710 the random mode is toggled.
713 =item $mpd->fade( [$seconds] )
715 Enable crossfading and set the duration of crossfade between songs.
716 If $seconds is not specified or $seconds is 0, then crossfading is disabled.
718 =back
721 =head2 Controlling playback
723 =over 4
725 =item $mpd->play( [$song] )
727 Begin playing playlist at song number $song. If no argument supplied,
728 resume playing.
731 =item $mpd->playid( [$songid] )
733 Begin playing playlist at song ID $songid. If no argument supplied,
734 resume playing.
737 =item $mpd->pause( [$state] )
739 Pause playback. If C<$state> is 0 then the current track is unpaused,
740 if $state is 1 then the current track is paused.
742 Note that if C<$state> is not given, pause state will be toggled.
745 =item $mpd->stop()
747 Stop playback.
750 =item $mpd->next()
752 Play next song in playlist.
755 =item $mpd->prev()
757 Play previous song in playlist.
760 =item $mpd->seek( $time, [$song])
762 Seek to $time seconds in song number $song. If $song number is not specified
763 then the perl module will try and seek to $time in the current song.
766 =item $mpd->seekid( $time, $songid )
768 Seek to $time seconds in song ID $songid. If $song number is not specified
769 then the perl module will try and seek to $time in the current song.
771 =back
774 =head2 Searching the collection
776 To search the collection, use the C<collection()> accessor, returning the
777 associated C<Audio::MPD::Collection> object. You will then be able to call:
779 $mpd->collection->random_song();
781 See C<Audio::MPD::Collection> documentation for more details on available
782 methods.
785 =head2 Handling the playlist
787 To update the playlist, use the C<playlist()> accessor, returning the
788 associated C<Audio::MPD::Playlist> object. You will then be able to call:
790 $mpd->playlist->clear;
792 See C<Audio::MPD::Playlist> documentation for more details on available
793 methods.
796 =head1 SEE ALSO
798 You can find more information on the mpd project on its homepage at
799 L<http://www.musicpd.org>, or its wiki L<http://mpd.wikia.com>.
801 Regarding this Perl module, you can report bugs on CPAN via
802 L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Audio-MPD>.
804 Audio::MPD development takes place on <audio-mpd@googlegroups.com>: feel free
805 to join us. (use L<http://groups.google.com/group/audio-mpd> to sign in). Our
806 subversion repository is located at L<https://svn.musicpd.org>.
810 =head1 AUTHORS
812 Jerome Quelin <jquelin@cpan.org>
814 Original code by Tue Abrahamsen <tue.abrahamsen@gmail.com>, documented by
815 Nicholas J. Humfrey <njh@aelius.com>.
819 =head1 COPYRIGHT AND LICENSE
821 Copyright (c) 2005 Tue Abrahamsen <tue.abrahamsen@gmail.com>
823 Copyright (c) 2006 Nicholas J. Humfrey <njh@aelius.com>
825 Copyright (c) 2007 Jerome Quelin <jquelin@cpan.org>
828 This program is free software; you can redistribute it and/or modify
829 it under the terms of the GNU General Public License as published by
830 the Free Software Foundation; either version 2 of the License, or
831 (at your option) any later version.
833 This program is distributed in the hope that it will be useful,
834 but WITHOUT ANY WARRANTY; without even the implied warranty of
835 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
836 GNU General Public License for more details.
838 =cut