[project @ 7036]
[audio-mpd.git] / lib / Audio / MPD.pm
blobb73a0971c464a6e03003e8081e8e986c76aef6f1
2 # This file is part of Audio::MPD
3 # Copyright (c) 2007 Jerome Quelin, all rights reserved.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the same terms as Perl itself.
10 package Audio::MPD;
12 use warnings;
13 use strict;
15 use Audio::MPD::Collection;
16 use Audio::MPD::Common::Item;
17 use Audio::MPD::Common::Stats;
18 use Audio::MPD::Common::Status;
19 use Audio::MPD::Playlist;
20 use Encode;
21 use IO::Socket;
24 use base qw[ Class::Accessor::Fast ];
25 __PACKAGE__->mk_accessors(
26 qw[ _host _password _port
27 collection playlist version ] );
30 our $VERSION = '0.18.2';
33 #--
34 # Constructor
37 # my $mpd = Audio::MPD->new( [$hostname], [$port], [$password] )
39 # This is the constructor for Audio::MPD. One can specify a $hostname, a
40 # $port, and a $password.
41 # If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
42 # and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
44 sub new {
45 my $class = shift;
46 my ($host, $port, $password) = @_;
48 # use mpd defaults.
49 $host = $ENV{MPD_HOST} || 'localhost' unless defined $host;
50 $port = $ENV{MPD_PORT} || '6600' unless defined $port;
51 $password = $ENV{MPD_PASSWORD} || '' unless defined $password;
53 # create & bless the object.
54 my $self = {
55 _host => $host,
56 _port => $port,
57 _password => $password,
59 bless $self, $class;
61 # create the helper objects and store them.
62 $self->collection( Audio::MPD::Collection->new($self) );
63 $self->playlist ( Audio::MPD::Playlist->new($self) );
65 # try to issue a ping to test connection - this can die.
66 $self->ping;
68 return $self;
72 #--
73 # Private methods
77 # my @result = $mpd->_send_command( $command );
79 # This method is central to the module. It is responsible for interacting with
80 # mpd by sending the $command and reading output - that will be returned as an
81 # array of chomped lines (status line will not be returned).
83 # Note that currently, this method will connect to mpd before sending any
84 # command, and will disconnect after the command has been issued. This scheme
85 # is far from optimal, but allows us not to care about timeout disconnections.
87 # /!\ Note that we're using high-level, blocking sockets. This means that if
88 # the mpd server is slow, or hangs for whatever reason, or even crash abruptly,
89 # the program will be hung forever in this sub. The POE::Component::Client::MPD
90 # module is way safer - you're advised to use it instead of Audio::MPD.
92 # This method can die on several conditions:
93 # - if the server cannot be reached,
94 # - if it's not an mpd server,
95 # - if the password is incorrect,
96 # - or if the command is an invalid mpd command.
97 # In the latter case, the mpd error message will be returned.
99 sub _send_command {
100 my ($self, $command) = @_;
102 # try to connect to mpd.
103 my $socket = IO::Socket::INET->new(
104 PeerAddr => $self->_host,
105 PeerPort => $self->_port
107 or die "Could not create socket: $!\n";
108 my $line;
110 # parse version information.
111 $line = $socket->getline;
112 chomp $line;
113 die "Not a mpd server - welcome string was: [$line]\n"
114 if $line !~ /^OK MPD (.+)$/;
115 $self->version($1);
117 # send password.
118 if ( $self->_password ) {
119 $socket->print( 'password ' . encode('utf-8', $self->_password) . "\n" );
120 $line = $socket->getline;
121 die $line if $line =~ s/^ACK //;
124 # ok, now we're connected - let's issue the command.
125 $socket->print( encode('utf-8', $command) );
126 my @output;
127 while (defined ( $line = $socket->getline ) ) {
128 chomp $line;
129 die $line if $line =~ s/^ACK //; # oops - error.
130 last if $line =~ /^OK/; # end of output.
131 push @output, decode('utf-8', $line);
134 # close the socket.
135 $socket->close;
137 return @output;
142 # my @items = $mpd->_cooked_command_as_items( $command );
144 # Lots of Audio::MPD methods are using _send_command() and then parse the
145 # output as a collection of AMC::Item. This method is meant to factorize
146 # this code, and will parse the raw output of _send_command() in a cooked
147 # list of items.
149 sub _cooked_command_as_items {
150 my ($self, $command) = @_;
152 my @lines = $self->_send_command($command);
153 my (@items, %param);
155 # parse lines in reverse order since "file:" or "directory:" lines
156 # come first. therefore, let's first store every other parameter,
157 # and the last line will trigger the object creation.
158 # of course, since we want to preserve the playlist order, this means
159 # that we're going to unshift the objects instead of push.
160 foreach my $line (reverse @lines) {
161 my ($k,$v) = split /:\s+/, $line, 2;
162 $param{$k} = $v;
163 next unless $k eq 'file' || $k eq 'directory'; # last param of item
164 unshift @items, Audio::MPD::Common::Item->new(%param);
165 %param = ();
168 return @items;
173 # my %hash = $mpd->_cooked_command_as_kv( $command );
175 # Lots of Audio::MPD methods are using _send_command() and then parse the
176 # output to get a list of key / value (with the colon ":" acting as separator).
177 # This method is meant to factorize this code, and will parse the raw output
178 # of _send_command() in a cooked hash.
180 sub _cooked_command_as_kv {
181 my ($self, $command) = @_;
182 my %hash =
183 map { split(/:\s+/, $_, 2) }
184 $self->_send_command($command);
185 return %hash;
189 # my @list = $mpd->_cooked_command_strip_first_field( $command );
191 # Lots of Audio::MPD methods are using _send_command() and then parse the
192 # output to remove the first field (with the colon ":" acting as separator).
193 # This method is meant to factorize this code, and will parse the raw output
194 # of _send_command() in a cooked list of strings.
196 sub _cooked_command_strip_first_field {
197 my ($self, $command) = @_;
199 my @list =
200 map { ( split(/:\s+/, $_, 2) )[1] }
201 $self->_send_command($command);
202 return @list;
207 # Public methods
209 # -- MPD interaction: general commands
212 # $mpd->ping;
214 # Sends a ping command to the mpd server.
216 sub ping {
217 my ($self) = @_;
218 $self->_send_command( "ping\n" );
223 # my $version = $mpd->version;
225 # Return version of MPD server's connected.
227 # sub version {} # implemented as an accessor.
232 # $mpd->kill;
234 # Send a message to the MPD server telling it to shut down.
236 sub kill {
237 my ($self) = @_;
238 $self->_send_command("kill\n");
243 # $mpd->password( [$password] )
245 # Change password used to communicate with MPD server to $password.
246 # Empty string is assumed if $password is not supplied.
248 sub password {
249 my ($self, $passwd) = @_;
250 $passwd ||= '';
251 $self->_password($passwd);
252 $self->ping; # ping sends a command, and thus the password is sent
257 # $mpd->updatedb( [$path] );
259 # Force mpd to rescan its collection. If $path (relative to MPD's music
260 # directory) is supplied, MPD will only scan it - otherwise, MPD will rescan
261 # its whole collection.
263 sub updatedb {
264 my ($self, $path) = @_;
265 $path ||= '';
266 $self->_send_command("update $path\n");
271 # my @handlers = $mpd->urlhandlers;
273 # Return an array of supported URL schemes.
275 sub urlhandlers {
276 my ($self) = @_;
277 return $self->_cooked_command_strip_first_field("urlhandlers\n");
281 # -- MPD interaction: handling volume & output
284 # $mpd->volume( [+][-]$volume );
286 # Sets the audio output volume percentage to absolute $volume.
287 # If $volume is prefixed by '+' or '-' then the volume is changed relatively
288 # by that value.
290 sub volume {
291 my ($self, $volume) = @_;
293 if ($volume =~ /^(-|\+)(\d+)/ ) {
294 my $current = $self->status->volume;
295 $volume = $1 eq '+' ? $current + $2 : $current - $2;
297 $self->_send_command("setvol $volume\n");
302 # $mpd->output_enable( $output );
304 # Enable the specified audio output. $output is the ID of the audio output.
306 sub output_enable {
307 my ($self, $output) = @_;
308 $self->_send_command("enableoutput $output\n");
313 # $mpd->output_disable( $output );
315 # Disable the specified audio output. $output is the ID of the audio output.
317 sub output_disable {
318 my ($self, $output) = @_;
319 $self->_send_command("disableoutput $output\n");
324 # -- MPD interaction: retrieving info from current state
327 # $mpd->stats;
329 # Return an AMC::Stats object with the current statistics of MPD.
331 sub stats {
332 my ($self) = @_;
333 my %kv = $self->_cooked_command_as_kv( "stats\n" );
334 return Audio::MPD::Common::Stats->new(\%kv);
339 # my $status = $mpd->status;
341 # Return an AMC::Status object with various information on current
342 # MPD server settings. Check the embedded pod for more information on the
343 # available accessors.
345 sub status {
346 my ($self) = @_;
347 my %kv = $self->_cooked_command_as_kv( "status\n" );
348 my $status = Audio::MPD::Common::Status->new( \%kv );
349 return $status;
354 # my $song = $mpd->current;
356 # Return an AMC::Item::Song representing the song currently playing.
358 sub current {
359 my ($self) = @_;
360 my ($item) = $self->_cooked_command_as_items("currentsong\n");
361 return $item;
366 # my $song = $mpd->song( [$song] )
368 # Return an AMC::Item::Song representing the song number $song.
369 # If $song is not supplied, returns the current song.
371 sub song {
372 my ($self, $song) = @_;
373 return $self->current unless defined $song;
374 my ($item) = $self->_cooked_command_as_items("playlistinfo $song\n");
375 return $item;
380 # my $song = $mpd->songid( [$songid] )
382 # Return an AMC::Item::Song representing the song with id $songid.
383 # If $songid is not supplied, returns the current song.
385 sub songid {
386 my ($self, $songid) = @_;
387 return $self->current unless defined $songid;
388 my ($item) = $self->_cooked_command_as_items("playlistid $songid\n");
389 return $item;
393 # -- MPD interaction: altering settings
396 # $mpd->repeat( [$repeat] );
398 # Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
399 # the repeat mode is toggled.
401 sub repeat {
402 my ($self, $mode) = @_;
404 $mode = not $self->status->repeat
405 unless defined $mode; # toggle if no param
406 $mode = $mode ? 1 : 0; # force integer
407 $self->_send_command("repeat $mode\n");
412 # $mpd->random( [$random] );
414 # Set the random mode to $random (1 or 0). If $random is not specified then
415 # the random mode is toggled.
417 sub random {
418 my ($self, $mode) = @_;
420 $mode = not $self->status->random
421 unless defined $mode; # toggle if no param
422 $mode = $mode ? 1 : 0; # force integer
423 $self->_send_command("random $mode\n");
428 # $mpd->fade( [$seconds] );
430 # Enable crossfading and set the duration of crossfade between songs. If
431 # $seconds is not specified or $seconds is 0, then crossfading is disabled.
433 sub fade {
434 my ($self, $value) = @_;
435 $value ||= 0;
436 $self->_send_command("crossfade $value\n");
440 # -- MPD interaction: controlling playback
443 # $mpd->play( [$song] );
445 # Begin playing playlist at song number $song. If no argument supplied,
446 # resume playing.
448 sub play {
449 my ($self, $number) = @_;
450 $number = '' unless defined $number;
451 $self->_send_command("play $number\n");
455 # $mpd->playid( [$songid] );
457 # Begin playing playlist at song ID $songid. If no argument supplied,
458 # resume playing.
460 sub playid {
461 my ($self, $number) = @_;
462 $number ||= '';
463 $self->_send_command("playid $number\n");
468 # $mpd->pause( [$sate] );
470 # Pause playback. If $state is 0 then the current track is unpaused, if
471 # $state is 1 then the current track is paused.
473 # Note that if $state is not given, pause state will be toggled.
475 sub pause {
476 my ($self, $state) = @_;
477 $state ||= ''; # default is to toggle
478 $self->_send_command("pause $state\n");
483 # $mpd->stop;
485 # Stop playback.
487 sub stop {
488 my ($self) = @_;
489 $self->_send_command("stop\n");
494 # $mpd->next;
496 # Play next song in playlist.
498 sub next {
499 my ($self) = @_;
500 $self->_send_command("next\n");
504 # $mpd->prev;
506 # Play previous song in playlist.
508 sub prev {
509 my($self) = shift;
510 $self->_send_command("previous\n");
515 # $mpd->seek( $time, [$song] );
517 # Seek to $time seconds in song number $song. If $song number is not specified
518 # then the perl module will try and seek to $time in the current song.
520 sub seek {
521 my ($self, $time, $song) = @_;
522 $time ||= 0; $time = int $time;
523 $song = $self->status->song if not defined $song; # seek in current song
524 $self->_send_command( "seek $song $time\n" );
529 # $mpd->seekid( $time, [$songid] );
531 # Seek to $time seconds in song ID $songid. If $songid number is not specified
532 # then the perl module will try and seek to $time in the current song.
534 sub seekid {
535 my ($self, $time, $song) = @_;
536 $time ||= 0; $time = int $time;
537 $song = $self->status->songid if not defined $song; # seek in current song
538 $self->_send_command( "seekid $song $time\n" );
546 __END__
548 =pod
550 =head1 NAME
552 Audio::MPD - class to talk to MPD (Music Player Daemon) servers
555 =head1 SYNOPSIS
557 use Audio::MPD;
559 my $mpd = Audio::MPD->new();
560 $mpd->play();
561 sleep 10;
562 $mpd->next();
565 =head1 DESCRIPTION
567 Audio::MPD gives a clear object-oriented interface for talking to and
568 controlling MPD (Music Player Daemon) servers. A connection to the MPD
569 server is established as soon as a new Audio::MPD object is created.
570 Commands are then sent to the server as the class's methods are called.
573 =head1 METHODS
575 =head2 Constructor
577 =over 4
579 =item new( [$host] [, $port] [, $password] )
581 This is the constructor for Audio::MPD. One can specify a $hostname, a
582 $port, and a $password.
584 If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
585 and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
587 =back
590 =head2 Controlling the server
592 =over 4
594 =item $mpd->ping()
596 Sends a ping command to the mpd server.
599 =item $mpd->version()
601 Return the version number for the server we are connected to.
604 =item $mpd->kill()
606 Send a message to the MPD server telling it to shut down.
609 =item $mpd->password( [$password] )
611 Change password used to communicate with MPD server to $password.
612 Empty string is assumed if $password is not supplied.
615 =item $mpd->updatedb( [$path] )
617 Force mpd to recan its collection. If $path (relative to MPD's music directory)
618 is supplied, MPD will only scan it - otherwise, MPD will rescan its whole
619 collection.
622 =item $mpd->urlhandlers()
624 Return an array of supported URL schemes.
627 =back
630 =head2 Handling volume & output
632 =over 4
634 =item $mpd->volume( [+][-]$volume )
636 Sets the audio output volume percentage to absolute $volume.
637 If $volume is prefixed by '+' or '-' then the volume is changed relatively
638 by that value.
641 =item $mpd->output_enable( $output )
643 Enable the specified audio output. $output is the ID of the audio output.
646 =item $mpd->output_disable( $output )
648 Disable the specified audio output. $output is the ID of the audio output.
650 =back
653 =head2 Retrieving info from current state
655 =over 4
657 =item $mpd->stats()
659 Return an C<Audio::MPD::Common::Stats> object with the current statistics
660 of MPD. See the associated pod for more information.
663 =item $mpd->status()
665 Return an C<Audio::MPD::Common::Status> object with various information on
666 current MPD server settings. Check the embedded pod for more information on
667 the available accessors.
670 =item $mpd->current()
672 Return an C<Audio::MPD::Common::Item::Song> representing the song currently
673 playing.
676 =item $mpd->song( [$song] )
678 Return an C<Audio::MPD::Common::Item::Song> representing the song number
679 C<$song>. If C<$song> is not supplied, returns the current song.
682 =item $mpd->songid( [$songid] )
684 Return an C<Audio::MPD::Common::Item::Song> representing the song with id
685 C<$songid>. If C<$songid> is not supplied, returns the current song.
687 =back
690 =head2 Altering MPD settings
692 =over 4
694 =item $mpd->repeat( [$repeat] )
696 Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
697 the repeat mode is toggled.
700 =item $mpd->random( [$random] )
702 Set the random mode to $random (1 or 0). If $random is not specified then
703 the random mode is toggled.
706 =item $mpd->fade( [$seconds] )
708 Enable crossfading and set the duration of crossfade between songs.
709 If $seconds is not specified or $seconds is 0, then crossfading is disabled.
711 =back
714 =head2 Controlling playback
716 =over 4
718 =item $mpd->play( [$song] )
720 Begin playing playlist at song number $song. If no argument supplied,
721 resume playing.
724 =item $mpd->playid( [$songid] )
726 Begin playing playlist at song ID $songid. If no argument supplied,
727 resume playing.
730 =item $mpd->pause( [$state] )
732 Pause playback. If C<$state> is 0 then the current track is unpaused,
733 if $state is 1 then the current track is paused.
735 Note that if C<$state> is not given, pause state will be toggled.
738 =item $mpd->stop()
740 Stop playback.
743 =item $mpd->next()
745 Play next song in playlist.
748 =item $mpd->prev()
750 Play previous song in playlist.
753 =item $mpd->seek( $time, [$song])
755 Seek to $time seconds in song number $song. If $song number is not specified
756 then the perl module will try and seek to $time in the current song.
759 =item $mpd->seekid( $time, $songid )
761 Seek to $time seconds in song ID $songid. If $song number is not specified
762 then the perl module will try and seek to $time in the current song.
764 =back
767 =head2 Searching the collection
769 To search the collection, use the C<collection()> accessor, returning the
770 associated C<Audio::MPD::Collection> object. You will then be able to call:
772 $mpd->collection->random_song();
774 See C<Audio::MPD::Collection> documentation for more details on available
775 methods.
778 =head2 Handling the playlist
780 To update the playlist, use the C<playlist()> accessor, returning the
781 associated C<Audio::MPD::Playlist> object. You will then be able to call:
783 $mpd->playlist->clear;
785 See C<Audio::MPD::Playlist> documentation for more details on available
786 methods.
789 =head1 SEE ALSO
791 You can find more information on the mpd project on its homepage at
792 L<http://www.musicpd.org>, or its wiki L<http://mpd.wikia.com>.
794 Regarding this Perl module, you can report bugs on CPAN via
795 L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Audio-MPD>.
797 Audio::MPD development takes place on <audio-mpd@googlegroups.com>: feel free
798 to join us. (use L<http://groups.google.com/group/audio-mpd> to sign in). Our
799 subversion repository is located at L<https://svn.musicpd.org>.
802 =head1 AUTHOR
804 Jerome Quelin, C<< <jquelin at cpan.org> >>
806 Original code by Tue Abrahamsen C<< <tue.abrahamsen at gmail.com> >>,
807 documented by Nicholas J. Humfrey C<< <njh at aelius.com> >>.
810 =head1 COPYRIGHT & LICENSE
812 Copyright (c) 2005 Tue Abrahamsen, all rights reserved.
813 Copyright (c) 2006 Nicolas J. Humfrey, all rights reserved.
814 Copyright (c) 2007 Jerome Quelin, all rights reserved.
816 This program is free software; you can redistribute it and/or modify
817 it under the same terms as Perl itself.
819 =cut