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
23 use Audio
::MPD
::Collection
;
25 use Audio
::MPD
::Playlist
;
26 use Audio
::MPD
::Status
;
31 use base qw
[ Class
::Accessor
::Fast
];
32 __PACKAGE__
->mk_accessors(
33 qw
[ _host _password _port
34 collection playlist version
] );
37 our $VERSION = '0.16.2';
44 # my $mpd = Audio::MPD->new( [$hostname], [$port], [$password] )
46 # This is the constructor for Audio::MPD. One can specify a $hostname, a
47 # $port, and a $password.
48 # If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
49 # and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
53 my ($host, $port, $password) = @_;
56 $host = $ENV{MPD_HOST
} || 'localhost' unless defined $host;
57 $port = $ENV{MPD_PORT
} || '6600' unless defined $port;
58 $password = $ENV{MPD_PASSWORD
} || '' unless defined $password;
60 # create & bless the object.
64 _password
=> $password,
68 # create the helper objects and store them.
69 $self->collection( Audio
::MPD
::Collection
->new($self) );
70 $self->playlist ( Audio
::MPD
::Playlist
->new($self) );
72 # try to issue a ping to test connection - this can die.
84 # my @result = $mpd->_send_command( $command );
86 # This method is central to the module. It is responsible for interacting with
87 # mpd by sending the $command and reading output - that will be returned as an
88 # array of chomped lines (status line will not be returned).
90 # Note that currently, this method will connect to mpd before sending any
91 # command, and will disconnect after the command has been issued. This scheme
92 # is far from optimal, but allows us not to care about timeout disconnections.
94 # /!\ Note that we're using high-level, blocking sockets. This means that if
95 # the mpd server is slow, or hangs for whatever reason, or even crash abruptly,
96 # the program will be hung forever in this sub. The POE::Component::Client::MPD
97 # module is way safer - you're advised to use it instead of Audio::MPD.
99 # This method can die on several conditions:
100 # - if the server cannot be reached,
101 # - if it's not an mpd server,
102 # - if the password is incorrect,
103 # - or if the command is an invalid mpd command.
104 # In the latter case, the mpd error message will be returned.
107 my ($self, $command) = @_;
109 # try to connect to mpd.
110 my $socket = IO
::Socket
::INET
->new(
111 PeerAddr
=> $self->_host,
112 PeerPort
=> $self->_port
114 or die "Could not create socket: $!\n";
117 # parse version information.
118 $line = $socket->getline;
120 die "Not a mpd server - welcome string was: [$line]\n"
121 if $line !~ /^OK MPD (.+)$/;
125 if ( $self->_password ) {
126 $socket->print( 'password ' . encode
('utf-8', $self->_password) . "\n" );
127 $line = $socket->getline;
128 die $line if $line =~ s/^ACK //;
131 # ok, now we're connected - let's issue the command.
132 $socket->print( encode
('utf-8', $command) );
134 while (defined ( $line = $socket->getline ) ) {
136 die $line if $line =~ s/^ACK //; # oops - error.
137 last if $line =~ /^OK/; # end of output.
138 push @output, decode
('utf-8', $line);
149 # my @items = $mpd->_cooked_command_as_items( $command );
151 # Lots of Audio::MPD methods are using _send_command() and then parse the
152 # output as a collection of Audio::MPD::Item. This method is meant to
153 # factorize this code, and will parse the raw output of _send_command() in
154 # a cooked list of items.
156 sub _cooked_command_as_items
{
157 my ($self, $command) = @_;
159 my @lines = $self->_send_command($command);
162 # parse lines in reverse order since "file:" or "directory:" lines
163 # come first. therefore, let's first store every other parameter,
164 # and the last line will trigger the object creation.
165 # of course, since we want to preserve the playlist order, this means
166 # that we're going to unshift the objects instead of push.
167 foreach my $line (reverse @lines) {
168 my ($k,$v) = split /:\s+/, $line, 2;
170 next unless $k eq 'file' || $k eq 'directory'; # last param of item
171 unshift @items, Audio
::MPD
::Item
->new(%param);
180 # my @list = $mpd->_cooked_command_strip_first_field( $command );
182 # Lots of Audio::MPD methods are using _send_command() and then parse the
183 # output to remove the first field (with the colon ":" acting as separator).
184 # This method is meant to factorize this code, and will parse the raw output
185 # of _send_command() in a cooked list of strings.
187 sub _cooked_command_strip_first_field
{
188 my ($self, $command) = @_;
191 map { ( split(/:\s+/, $_, 2) )[1] }
192 $self->_send_command($command);
200 # -- MPD interaction: general commands
205 # Sends a ping command to the mpd server.
209 $self->_send_command( "ping\n" );
214 # my $version = $mpd->version;
216 # Return version of MPD server's connected.
218 # sub version {} # implemented as an accessor.
225 # Send a message to the MPD server telling it to shut down.
229 $self->_send_command("kill\n");
234 # $mpd->password( [$password] )
236 # Change password used to communicate with MPD server to $password.
237 # Empty string is assumed if $password is not supplied.
240 my ($self, $passwd) = @_;
242 $self->_password($passwd);
243 $self->ping; # ping sends a command, and thus the password is sent
248 # $mpd->updatedb( [$path] );
250 # Force mpd to recan its collection. If $path (relative to MPD's music
251 # directory) is supplied, MPD will only scan it - otherwise, MPD will rescan
252 # its whole collection.
255 my ($self, $path) = @_;
257 $self->_send_command("update $path\n");
262 # my @handlers = $mpd->urlhandlers;
264 # Return an array of supported URL schemes.
268 return $self->_cooked_command_strip_first_field("urlhandlers\n");
272 # -- MPD interaction: handling volume & output
275 # $mpd->volume( [+][-]$volume );
277 # Sets the audio output volume percentage to absolute $volume.
278 # If $volume is prefixed by '+' or '-' then the volume is changed relatively
282 my ($self, $volume) = @_;
284 if ($volume =~ /^(-|\+)(\d+)/ ) {
285 my $current = $self->status->volume;
286 $volume = $1 eq '+' ?
$current + $2 : $current - $2;
288 $self->_send_command("setvol $volume\n");
293 # $mpd->output_enable( $output );
295 # Enable the specified audio output. $output is the ID of the audio output.
298 my ($self, $output) = @_;
299 $self->_send_command("enableoutput $output\n");
304 # $mpd->output_disable( $output );
306 # Disable the specified audio output. $output is the ID of the audio output.
309 my ($self, $output) = @_;
310 $self->_send_command("disableoutput $output\n");
315 # -- MPD interaction: retrieving info from current state
320 # Return a hashref with the number of artists, albums, songs in the database,
321 # as well as mpd uptime, the playtime of the playlist / the database and the
322 # last update of the database.
327 map { my ($k,$v) = split(/:\s+/, $_, 2); ($k => $v) }
328 $self->_send_command( "stats\n" );
334 # my $status = $mpd->status;
336 # Return an Audio::MPD::Status object with various information on current
337 # MPD server settings. Check the embedded pod for more information on the
338 # available accessors.
342 my @output = $self->_send_command( "status\n" );
343 my $status = Audio
::MPD
::Status
->new( @output );
349 # my $song = $mpd->current;
351 # Return an C<Audio::MPD::Item::Song> representing the song currently playing.
355 my ($item) = $self->_cooked_command_as_items("currentsong\n");
361 # my $song = $mpd->song( [$song] )
363 # Return an C<Audio::MPD::Item::Song> representing the song number C<$song>.
364 # If C<$song> is not supplied, returns the current song.
367 my ($self, $song) = @_;
368 return $self->current unless defined $song;
369 my ($item) = $self->_cooked_command_as_items("playlistinfo $song\n");
375 # my $song = $mpd->songid( [$songid] )
377 # Return an C<Audio::MPD::Item::Song> representing the song with id C<$songid>.
378 # If C<$songid> is not supplied, returns the current song.
381 my ($self, $songid) = @_;
382 return $self->current unless defined $songid;
383 my ($item) = $self->_cooked_command_as_items("playlistid $songid\n");
388 # -- MPD interaction: altering settings
391 # $mpd->repeat( [$repeat] );
393 # Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
394 # the repeat mode is toggled.
397 my ($self, $mode) = @_;
399 $mode = not $self->status->repeat
400 unless defined $mode; # toggle if no param
401 $mode = $mode ?
1 : 0; # force integer
402 $self->_send_command("repeat $mode\n");
407 # $mpd->random( [$random] );
409 # Set the random mode to $random (1 or 0). If $random is not specified then
410 # the random mode is toggled.
413 my ($self, $mode) = @_;
415 $mode = not $self->status->random
416 unless defined $mode; # toggle if no param
417 $mode = $mode ?
1 : 0; # force integer
418 $self->_send_command("random $mode\n");
423 # $mpd->fade( [$seconds] );
425 # Enable crossfading and set the duration of crossfade between songs. If
426 # $seconds is not specified or $seconds is 0, then crossfading is disabled.
429 my ($self, $value) = @_;
431 $self->_send_command("crossfade $value\n");
435 # -- MPD interaction: controlling playback
438 # $mpd->play( [$song] );
440 # Begin playing playlist at song number $song. If no argument supplied,
444 my ($self, $number) = @_;
445 $number = '' unless defined $number;
446 $self->_send_command("play $number\n");
450 # $mpd->playid( [$songid] );
452 # Begin playing playlist at song ID $songid. If no argument supplied,
456 my ($self, $number) = @_;
458 $self->_send_command("playid $number\n");
463 # $mpd->pause( [$sate] );
465 # Pause playback. If $state is 0 then the current track is unpaused, if
466 # $state is 1 then the current track is paused.
468 # Note that if $state is not given, pause state will be toggled.
471 my ($self, $state) = @_;
472 $state ||= ''; # default is to toggle
473 $self->_send_command("pause $state\n");
484 $self->_send_command("stop\n");
491 # Play next song in playlist.
495 $self->_send_command("next\n");
501 # Play previous song in playlist.
505 $self->_send_command("previous\n");
510 # $mpd->seek( $time, [$song]);
512 # Seek to $time seconds in song number $song. If $song number is not specified
513 # then the perl module will try and seek to $time in the current song.
516 my ($self, $time, $song) = @_;
517 $time ||= 0; $time = int $time;
518 $song = $self->status->song if not defined $song; # seek in current song
519 $self->_send_command( "seek $song $time\n" );
524 # $mpd->seekid( $time, $songid );
526 # Seek to $time seconds in song ID $songid. If $song number is not specified
527 # then the perl module will try and seek to $time in the current song.
530 my ($self, $time, $song) = @_;
531 $time ||= 0; $time = int $time;
532 $song = $self->status->songid if not defined $song; # seek in current song
533 $self->_send_command( "seekid $song $time\n" );
539 ###############################################################
541 #-------------------------------------------------------------#
542 # This section contains all methods not directly accessing #
543 # MPD, but may be useful for most people using the module. #
544 ###############################################################
547 sub get_time_format
{
550 # Get the time from MPD; example: 49:395 (seconds so far:total seconds)
551 my ($sofar, $total) = split /:/, $self->status->time;
552 return sprintf "%d:%02d/%d:%02d",
553 ($sofar / 60), # minutes so far
554 ($sofar % 60), # seconds - minutes so far
555 ($total / 60), # minutes total
556 ($total % 60);# seconds - minutes total
562 # Get the time from MPD; example: 49:395 (seconds so far:total seconds)
563 my ($sofar, $total) = split /:/, $self->status->time;
564 my $left = $total - $sofar;
566 # Store seconds for everything
568 $rv->{seconds_so_far
} = $sofar;
569 $rv->{seconds_total
} = $total;
570 $rv->{seconds_left
} = $left;
572 # Store the percentage; use one decimal point
575 ?
100*$rv->{seconds_so_far
}/$rv->{seconds_total
}
577 $rv->{percentage
} = sprintf "%.1f",$rv->{percentage
};
580 # Parse the time so far
581 my $min_so_far = ($sofar / 60);
582 my $sec_so_far = ($sofar % 60);
584 $rv->{time_so_far
} = sprintf("%d:%02d", $min_so_far, $sec_so_far);
585 $rv->{minutes_so_far
} = sprintf("%00d", $min_so_far);
586 $rv->{seconds_so_far
} = sprintf("%00d", $sec_so_far);
589 # Parse the total time
590 my $min_tot = ($total / 60);
591 my $sec_tot = ($total % 60);
593 $rv->{time_total
} = sprintf("%d:%02d", $min_tot, $sec_tot);
594 $rv->{minutes
} = $min_tot;
595 $rv->{seconds
} = $sec_tot;
597 # Parse the time left
598 my $min_left = ($left / 60);
599 my $sec_left = ($left % 60);
600 $rv->{time_left
} = sprintf("-%d:%02d", $min_left, $sec_left);
616 Audio::MPD - Class for talking to MPD (Music Player Daemon) servers
623 my $mpd = Audio::MPD->new();
631 Audio::MPD gives a clear object-oriented interface for talking to and
632 controlling MPD (Music Player Daemon) servers. A connection to the MPD
633 server is established as soon as a new Audio::MPD object is created.
634 Commands are then sent to the server as the class's methods are called.
643 =item new( [$host] [, $port] [, $password] )
645 This is the constructor for Audio::MPD. One can specify a $hostname, a
646 $port, and a $password.
648 If none is specified then defaults to environment vars MPD_HOST, MPD_PORT
649 and MPD_PASSWORD. If those aren't set, defaults to 'localhost', 6600 and ''.
654 =head2 Controlling the server
660 Sends a ping command to the mpd server.
663 =item $mpd->version()
665 Return the version number for the server we are connected to.
670 Send a message to the MPD server telling it to shut down.
673 =item $mpd->password( [$password] )
675 Change password used to communicate with MPD server to $password.
676 Empty string is assumed if $password is not supplied.
679 =item $mpd->updatedb( [$path] )
681 Force mpd to recan its collection. If $path (relative to MPD's music directory)
682 is supplied, MPD will only scan it - otherwise, MPD will rescan its whole
686 =item $mpd->urlhandlers()
688 Return an array of supported URL schemes.
694 =head2 Handling volume & output
698 =item $mpd->volume( [+][-]$volume )
700 Sets the audio output volume percentage to absolute $volume.
701 If $volume is prefixed by '+' or '-' then the volume is changed relatively
705 =item $mpd->output_enable( $output )
707 Enable the specified audio output. $output is the ID of the audio output.
710 =item $mpd->output_disable( $output )
712 Disable the specified audio output. $output is the ID of the audio output.
717 =head2 Retrieving info from current state
723 Return a hashref with the number of artists, albums, songs in the database,
724 as well as mpd uptime, the playtime of the playlist / the database and the
725 last update of the database
730 Return an C<Audio::MPD::Status> object with various information on current
731 MPD server settings. Check the embedded pod for more information on the
735 =item $mpd->current( )
737 Return an C<Audio::MPD::Item::Song> representing the song currently playing.
740 =item $mpd->song( [$song] )
742 Return an C<Audio::MPD::Item::Song> representing the song number C<$song>. If
743 C<$song> is not supplied, returns the current song.
746 =item $mpd->songid( [$songid] )
748 Return an C<Audio::MPD::Item::Song> representing the song with id C<$songid>.
749 If C<$songid> is not supplied, returns the current song.
754 =head2 Altering MPD settings
758 =item $mpd->repeat( [$repeat] )
760 Set the repeat mode to $repeat (1 or 0). If $repeat is not specified then
761 the repeat mode is toggled.
764 =item $mpd->random( [$random] )
766 Set the random mode to $random (1 or 0). If $random is not specified then
767 the random mode is toggled.
770 =item $mpd->fade( [$seconds] )
772 Enable crossfading and set the duration of crossfade between songs.
773 If $seconds is not specified or $seconds is 0, then crossfading is disabled.
778 =head2 Controlling playback
782 =item $mpd->play( [$song] )
784 Begin playing playlist at song number $song. If no argument supplied,
788 =item $mpd->playid( [$songid] )
790 Begin playing playlist at song ID $songid. If no argument supplied,
794 =item $mpd->pause( [$state] )
796 Pause playback. If C<$state> is 0 then the current track is unpaused,
797 if $state is 1 then the current track is paused.
799 Note that if C<$state> is not given, pause state will be toggled.
809 Play next song in playlist.
814 Play previous song in playlist.
817 =item $mpd->seek( $time, [$song])
819 Seek to $time seconds in song number $song. If $song number is not specified
820 then the perl module will try and seek to $time in the current song.
823 =item $mpd->seekid( $time, $songid )
825 Seek to $time seconds in song ID $songid. If $song number is not specified
826 then the perl module will try and seek to $time in the current song.
831 =head2 Retrieving information from current playlist
835 =item $mpd->get_time_format( )
837 Returns the current position and duration of the current song.
838 String is formatted at "M:SS/M:SS", with current time first and total time
842 =item $mpd->get_time_info( )
844 Return current timing information in various different formats
845 contained in a hashref with the following keys:
874 =head2 Searching the collection
876 To search the collection, use the C<collection()> accessor, returning the
877 associated C<Audio::MPD::Collection> object. You will then be able to call:
879 $mpd->collection->random_song();
881 See C<Audio::MPD::Collection> documentation for more details on available
885 =head2 Handling the playlist
887 To update the playlist, use the C<playlist()> accessor, returning the
888 associated C<Audio::MPD::Playlist> object. You will then be able to call:
890 $mpd->playlist->clear;
892 See C<Audio::MPD::Playlist> documentation for more details on available
898 You can find more information on the mpd project on its homepage at
899 L<http://www.musicpd.org>, or its wiki L<http://mpd.wikia.com>.
901 Regarding this Perl module, you can report bugs on CPAN via
902 L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Audio-MPD>.
904 Audio::MPD development takes place on <audio-mpd@googlegroups.com>: feel free
905 to join us. (use L<http://groups.google.com/group/audio-mpd> to sign in). Our
906 subversion repository is located at L<https://svn.musicpd.org>.
912 Jerome Quelin <jquelin@cpan.org>
914 Original code by Tue Abrahamsen <tue.abrahamsen@gmail.com>, documented by
915 Nicholas J. Humfrey <njh@aelius.com>.
919 =head1 COPYRIGHT AND LICENSE
921 Copyright (c) 2005 Tue Abrahamsen <tue.abrahamsen@gmail.com>
923 Copyright (c) 2006 Nicholas J. Humfrey <njh@aelius.com>
925 Copyright (c) 2007 Jerome Quelin <jquelin@cpan.org>
928 This program is free software; you can redistribute it and/or modify
929 it under the terms of the GNU General Public License as published by
930 the Free Software Foundation; either version 2 of the License, or
931 (at your option) any later version.
933 This program is distributed in the hope that it will be useful,
934 but WITHOUT ANY WARRANTY; without even the implied warranty of
935 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
936 GNU General Public License for more details.