File Coverage

blib/lib/Net/MPD.pm
Criterion Covered Total %
statement 44 157 28.0
branch 0 50 0.0
condition 11 33 33.3
subroutine 12 27 44.4
pod 6 7 85.7
total 73 274 26.6


line stmt bran cond sub pod time code
1             package Net::MPD;
2              
3 1     1   949 use strict;
  1         2  
  1         39  
4 1     1   6 use warnings;
  1         3  
  1         39  
5 1     1   880 use version 0.77;
  1         2213  
  1         7  
6              
7 1     1   53 use Carp;
  1         1  
  1         67  
8 1     1   1008 use IO::Socket::INET;
  1         36560  
  1         10  
9 1     1   1356 use Net::MPD::Response;
  1         2  
  1         32  
10 1     1   7 use Scalar::Util qw'looks_like_number';
  1         2  
  1         81  
11              
12 1     1   30 use 5.010;
  1         3  
  1         779  
13              
14             our $VERSION = '0.05';
15              
16             =encoding utf-8
17              
18             =head1 NAME
19              
20             Net::MPD - Communicate with an MPD server
21              
22             =head1 SYNOPSIS
23              
24             use Net::MPD;
25              
26             my $mpd = Net::MPD->connect();
27              
28             $mpd->stop();
29             $mpd->clear();
30             $mpd->search_add(Artist => 'David Bowie');
31             $mpd->shuffle();
32             $mpd->play();
33             $mpd->next();
34              
35             while (1) {
36             my @changes = $mpd->idle();
37             print 'Changed: ' . join(', ', @changes) . "\n";
38             }
39              
40             =head1 DESCRIPTION
41              
42             Net::MPD is designed as a lightweight replacment for L which
43             depends on L and is no longer maintained.
44              
45             =cut
46              
47             sub _debug {
48 0 0   0   0 say STDERR @_ if $ENV{NET_MPD_DEBUG};
49             }
50              
51             sub _connect {
52 0     0   0 my ($self) = @_;
53              
54 0 0       0 my $socket = IO::Socket::INET->new(
55             PeerHost => $self->{hostname},
56             PeerPort => $self->{port},
57             Proto => 'tcp',
58             ) or croak "Unable to connect to $self->{hostname}:$self->{port}";
59 0         0 binmode $socket, ':utf8';
60              
61 0         0 my $versionline = $socket->getline;
62 0         0 my ($version) = ($versionline =~ /^OK MPD (\d+\.\d+\.\d+)$/);
63              
64 0 0       0 croak "Connection not to MPD" unless $version;
65              
66 0         0 $self->{socket} = $socket;
67 0         0 $self->{version} = qv($version);
68              
69 0 0       0 if ($self->{password}) {
70 0         0 my $result = $self->_send('password', $self->{password});
71 0 0       0 croak $result->message if $result->is_error;
72             }
73              
74 0         0 $self->update_status();
75             }
76              
77             sub _send {
78 0     0   0 my ($self, $command, @args) = @_;
79              
80 0         0 my $string = "$command";
81 0         0 foreach my $arg (@args) {
82 0         0 $arg =~ s/"/\\"/g;
83 0         0 $string .= qq{ "$arg"};
84             }
85 0         0 $string .= "\n";
86              
87             # auto reconnect
88 0 0       0 unless ($self->{socket}->connected) {
89 0         0 $self->_connect();
90 0         0 _debug '# Reconnecting';
91             }
92              
93 0         0 $self->{socket}->print($string);
94 0         0 _debug "> $string";
95              
96 0         0 my @lines = ();
97              
98 0         0 while (1) {
99 0         0 my $line = $self->{socket}->getline;
100 0 0       0 croak "Error reading line from socket" if not defined $line;
101 0         0 chomp $line;
102 0         0 _debug "< $line";
103              
104 0 0       0 if ($line =~ /^OK$|^ACK /) {
105 0         0 return Net::MPD::Response->new($line, @lines);
106             } else {
107 0         0 push @lines, $line;
108             }
109             }
110             }
111              
112             sub _require {
113 0     0   0 my ($self, $version) = @_;
114 0         0 $version = qv($version);
115 0 0       0 croak "Requires MPD version $version" if $version > $self->version;
116             }
117              
118             sub _inject {
119 93     93   123 my ($class, $name, $sub) = @_;
120 1     1   6 no strict 'refs';
  1         2  
  1         3457  
121 93         84 *{"${class}::$name"} = $sub;
  93         528  
122             }
123              
124             sub _attribute {
125 21     21   44 my ($class, $name, %options) = @_;
126              
127 21         43 (my $normal_name = $name) =~ s/_//g;
128              
129 21   66     81 $options{key} //= $normal_name;
130 21   66     71 $options{command} //= $normal_name;
131 21   100     61 $options{version} //= 0;
132              
133             my $getter = sub {
134 0     0   0 my ($self) = @_;
135 0         0 $self->_require($options{version});
136 0         0 return $self->{status}{$options{key}};
137 21         66 };
138              
139             my $setter = sub {
140 0     0   0 my ($self, $value) = @_;
141              
142 0         0 $self->_require($options{version});
143              
144 0         0 my $result = $self->_send($options{command}, $value);
145 0 0       0 if ($result->is_error) {
146 0         0 carp $result->message;
147             } else {
148 0         0 $self->{status}{$options{key}} = $value;
149             }
150              
151 0         0 return $getter->(@_);
152 21         71 };
153              
154             $class->_inject($name => sub {
155 0 0 0 0   0 if ($options{readonly} or @_ == 1) {
156 0         0 return $getter->(@_);
157             } else {
158 0         0 return $setter->(@_);
159             }
160 21         128 });
161             }
162              
163             my $default_parser = sub {
164             my $result = shift;
165              
166             my @items = ();
167             my $item = {};
168             foreach my $line ($result->lines) {
169             my ($key, $value) = split /: /, $line, 2;
170             if (exists $item->{$key}) {
171             push @items, 2 > keys %$item ? values %$item : $item;
172             $item = {};
173             }
174             $item->{$key} = $value;
175             }
176              
177             push @items, 2 > keys %$item ? values %$item : $item;
178              
179             return wantarray ? @items : $items[0];
180             };
181              
182             sub _command {
183 72     72   124 my ($class, $name, %options) = @_;
184              
185 72         150 (my $normal_name = $name) =~ s/_//g;
186              
187 72   66     270 $options{command} //= $normal_name;
188 72   50     249 $options{args} //= [];
189 72   66     219 $options{parser} //= $default_parser;
190              
191             $class->_inject($name => sub {
192 0     0     my $self = shift;
193 0           my $result = $self->_send($options{command}, @_);
194 0 0         if ($result->is_error) {
195 0           carp $result->message;
196 0           return undef;
197             } else {
198 0           return $options{parser}->($result);
199             }
200 72         351 });
201             }
202              
203             =head1 METHODS
204              
205             =head2 connect [$address]
206              
207             Connect to the MPD running at the given address. Address takes the form of
208             password@host:port. Both the password and port are optional. If no password is
209             given, none will be used. If no port is given, the default (6600) will be used.
210             If no host is given, C will be used.
211              
212             Return a Net::MPD object on success and croaks on failure.
213              
214             =cut
215              
216             sub connect {
217 0     0 1   my ($class, $address) = @_;
218              
219 0   0       $address ||= 'localhost';
220              
221 0           my ($pass, $host, $port) = ($address =~ /(?:([^@]+)@)?([^:]+)(?::(\d+))?/);
222              
223 0   0       $port ||= 6600;
224              
225 0           my $self = bless {
226             hostname => $host,
227             port => $port,
228             password => $pass,
229             }, $class;
230              
231 0           $self->_connect;
232              
233 0           return $self;
234             }
235              
236             =head2 version
237              
238             Return the API version of the connected MPD server.
239              
240             =cut
241              
242             sub version {
243 0     0 1   my $self = shift;
244 0           return $self->{version};
245             }
246              
247             =head2 update_status
248              
249             Issue a C command to MPD and stores the results in the local object.
250             The results are also returned as a hashref.
251              
252             =cut
253              
254             sub update_status {
255 0     0 1   my ($self) = @_;
256 0           my $result = $self->_send('status');
257 0 0         if ($result->is_error) {
258 0           warn $result->message;
259             } else {
260 0           $self->{status} = $result->make_hash;
261             }
262             }
263              
264             =head1 MPD ATTRIBUTES
265              
266             Most of the "status" attributes have been written as combined getter/setter
267             methods. Calling the L method will update these values. Only
268             the items marked with an asterisk are writable.
269              
270             =over 4
271              
272             =item volume*
273              
274             =item repeat*
275              
276             =item random*
277              
278             =item single*
279              
280             =item consume*
281              
282             =item playlist
283              
284             =item playlist_length
285              
286             =item state
287              
288             =item song
289              
290             =item song_id
291              
292             =item next_song
293              
294             =item next_song_id
295              
296             =item time
297              
298             =item elapsed
299              
300             =item bitrate
301              
302             =item crossfade*
303              
304             =item mix_ramp_db*
305              
306             =item mix_ramp_delay*
307              
308             =item audio
309              
310             =item updating_db
311              
312             =item error
313              
314             =item replay_gain_mode*
315              
316             =back
317              
318             =cut
319              
320             __PACKAGE__->_attribute('volume', command => 'setvol');
321             __PACKAGE__->_attribute('repeat');
322             __PACKAGE__->_attribute('random');
323             __PACKAGE__->_attribute('single', version => 0.15);
324             __PACKAGE__->_attribute('consume', version => 0.15);
325             __PACKAGE__->_attribute('playlist', readonly => 1);
326             __PACKAGE__->_attribute('playlist_length', readonly => 1);
327             __PACKAGE__->_attribute('state', readonly => 1);
328             __PACKAGE__->_attribute('song', readonly => 1);
329             __PACKAGE__->_attribute('song_id', readonly => 1);
330             __PACKAGE__->_attribute('next_song', readonly => 1);
331             __PACKAGE__->_attribute('next_song_id', readonly => 1);
332             __PACKAGE__->_attribute('time', readonly => 1);
333             __PACKAGE__->_attribute('elapsed', readonly => 1, version => 0.16);
334             __PACKAGE__->_attribute('bitrate', readonly => 1);
335             __PACKAGE__->_attribute('crossfade', key => 'xfade');
336             __PACKAGE__->_attribute('mix_ramp_db');
337             __PACKAGE__->_attribute('mix_ramp_delay');
338             __PACKAGE__->_attribute('audio', readonly => 1);
339             __PACKAGE__->_attribute('updating_db', key => 'updating_db', readonly => 1);
340             __PACKAGE__->_attribute('error', readonly => 1);
341              
342             sub replay_gain_mode {
343 0     0 0   my $self = shift;
344              
345 0 0         if (@_) {
346 0           my $result = $self->_send('replay_gain_mode', @_);
347 0 0         carp $result->message if $result->is_error;
348             }
349              
350 0           my $result = $self->_send('replay_gain_status');
351 0 0         if ($result->is_error) {
352 0           carp $result->message;
353 0           return undef;
354             } else {
355 0           return $result->make_hash->{replay_gain_mode};
356             }
357             }
358              
359             =head1 MPD COMMANDS
360              
361             The commands are mostly the same as the L
362             protocol|http://www.musicpd.org/doc/protocol/index.html> but some have been
363             renamed slightly.
364              
365             =head2 clear_error
366              
367             Clear the current error message in status. This can also be done by issuing any
368             command that starts playback.
369              
370             =head2 current_song
371              
372             Return the song info for the current song.
373              
374             =head2 idle [@subsystems]
375              
376             Block until a noteworth change in one or more of MPD's subsystems. As soon as
377             there is one, a list of all changed subsystems will be returned. If any
378             subsystems are given as arguments, only those subsystems will be monitored. The
379             following subsystems are available:
380              
381             =over 4
382              
383             =item database
384              
385             The song database has been changed after an update.
386              
387             =item udpate
388              
389             A database update has started or finished.
390              
391             =item stored_playlist
392              
393             A stored playlist has been modified.
394              
395             =item playlist
396              
397             The current playlist has been modified.
398              
399             =item player
400              
401             Playback has been started stopped or seeked.
402              
403             =item mixer
404              
405             The volume has been adjusted.
406              
407             =item output
408              
409             An audio output has been enabled or disabled.
410              
411             =item sticker
412              
413             The sticket database has been modified.
414              
415             =item subscription
416              
417             A client has subscribed or unsubscribed from a channel.
418              
419             =item message
420              
421             A message was received on a channel this client is watching.
422              
423             =back
424              
425             =head2 stats
426              
427             Return a hashref with some stats about the database.
428              
429             =head2 next
430              
431             Play the next song in the playlist.
432              
433             =head2 pause $state
434              
435             Set the pause state. Use 0 for playing and 1 for paused.
436              
437             =head2 play [$position]
438              
439             Start playback (optionally at the given position).
440              
441             =head2 play_id [$id]
442              
443             Start playback (optionally with the given song).
444              
445             =head2 previous
446              
447             Play the previous song in the playlist.
448              
449             =head2 seek $position $time
450              
451             Seek to $time seconds in the given song position.
452              
453             =head2 seek_id $id $time
454              
455             Seek to $time seconds in the given song.
456              
457             =head2 seek_cur $time
458              
459             Seek to $time seconds in the current song.
460              
461             =head2 stop
462              
463             Stop playing.
464              
465             =head2 add $path
466              
467             Add the file (or directory, recursively) at $path to the current playlist.
468              
469             =head2 add_id $path [$position]
470              
471             Add the file at $path (optionally at $position) to the playlist and return the
472             id.
473              
474             =head2 clear
475              
476             Clear the current playlist.
477              
478             =head2 delete $position
479              
480             Remove the song(s) in the given position from the current playlist.
481              
482             =head2 delete_id $id
483              
484             Remove the song with the given id from the current playlist.
485              
486             =head2 move $from $to
487              
488             Move the song from position $from to $to.
489              
490             =head2 move_id $id $to
491              
492             Move the song with the given id to position $to.
493              
494             =head2 playlist_find $tag $search
495              
496             Search the current playlist for songs with $tag exactly matching $search.
497              
498             =head2 playlist_id $id
499              
500             Return song information for the song with the given id.
501              
502             =head2 playlist_info [$position]
503              
504             Return song information for every song in the current playlist (or optionally
505             the one at the given position).
506              
507             =head2 playlist_search $tag $search
508              
509             Search the current playlist for songs with $tag partially matching $search.
510              
511             =head2 playlist_changes $version
512              
513             Return song information for songs changed since the given version of the current
514             playlist.
515              
516             =head2 playlist_changes_pos_id $version
517              
518             Return position and id information for songs changed since the given version of
519             the current playlist.
520              
521             =head2 prio $priority $position
522              
523             Set the priority of the song at the given position.
524              
525             =head2 prio_id $priority $id
526              
527             Set the priority of the song with the given id.
528              
529             =head2 shuffle
530              
531             Shuffle the current playlist.
532              
533             =head2 swap $pos1 $pos2
534              
535             Swap the positions of the songs at the given positions.
536              
537             =head2 swapid $id1 $id2
538              
539             Swap the positions of the songs with the given ids.
540              
541             =head2 list_playlist $name
542              
543             Return a list of all the songs in the named playlist.
544              
545             =head2 list_playlist_info $name
546              
547             Return all the song information for the named playlist.
548              
549             =head2 list_playlists
550              
551             Return a list of the stored playlists.
552              
553             =head2 load $name
554              
555             Add the named playlist to the current playlist.
556              
557             =head2 playlist_add $name $path
558              
559             Add the given path to the named playlist.
560              
561             =head2 playlist_clear $name
562              
563             Clear the named playlist.
564              
565             =head2 playlist_delete $name $position
566              
567             Remove the song at the given position from the named playlist.
568              
569             =head2 playlist_move $name $id $pos
570              
571             Move the song with the given id to the given position in the named playlist.
572              
573             =head2 rename $name $new_name
574              
575             Rename the named playlist to $new_name.
576              
577             =head2 rm $name
578              
579             Delete the named playlist.
580              
581             =head2 save $name
582              
583             Save the current playlist with the given name.
584              
585             =head2 count $tag $search ...
586              
587             Return a count and playtime for all items with $tag exactly matching $search.
588             Multiple pairs of $tag/$search parameters can be given.
589              
590             =head2 find $tag $search ...
591              
592             Return song information for all items with $tag exactly matching $search. The
593             special tag 'any' can be used to search all tag. The special tag 'file' can be
594             used to search by path.
595              
596             =head2 find_add $tag $search
597              
598             Search as with C and add any matches to the current playlist.
599              
600             =head2 list $tag [$artist]
601              
602             Return all the values for the given tag. If the tag is 'album', an artist can
603             optionally be given to further limit the results.
604              
605             =head2 list_all [$path]
606              
607             Return a list of all the songs and directories (optionally under $path).
608              
609             =head2 list_all_info [$path]
610              
611             Return a list of all the songs as with C but include metadata.
612              
613             =head2 search $tag $search ...
614              
615             As C but with partial, case-insensitive searching.
616              
617             =head2 search_add $tag $search ...
618              
619             As C but adds the results to the current playlist.
620              
621             =head2 search_add_pl $name $tag $search ...
622              
623             As C but adds the results the named playlist.
624              
625             =head2 update [$path]
626              
627             Update the database (optionally under $path) and return a job id.
628              
629             =head2 rescan [$path]
630              
631             As but forces rescan of unmodified files.
632              
633             =head2 sticker_value $type $path $name [$value]
634              
635             Return the sticker value for the given item after optionally setting it to
636             $value. Use an undefined value to delete the sticker.
637              
638             =cut
639              
640             sub sticker_value {
641 0     0 1   my ($self, $type, $path, $name, $value) = @_;
642              
643 0 0         if (@_ > 4) {
644 0 0         if (defined $value) {
645 0           my $result = $self->_send('sticker', 'set', $type, $path, $name, $value);
646 0 0 0       carp $result->message and return undef if $result->is_error;
647 0           return $value;
648             } else {
649 0           my $result = $self->_send('sticker', 'delete', $type, $path, $name);
650 0 0         carp $result->message if $result->is_error;
651 0           return undef;
652             }
653             } else {
654 0           my $result = $self->_send('sticker', 'get', $type, $path, $name);
655 0 0 0       carp $result->message and return undef if $result->is_error;
656              
657 0           my ($line) = $result->lines;
658 0           my ($val) = ($line =~ /^sticker: \Q$name\E=(.*)$/);
659 0           return $val;
660             }
661             }
662              
663             =head2 sticker_list $type $path
664              
665             Return a hashref of the stickers for the given item.
666              
667             =cut
668              
669             sub sticker_list {
670 0     0 1   my ($self, $type, $path) = @_;
671              
672 0           my $result = $self->_send('sticker', 'list', $type, $path);
673 0 0 0       carp $result->message and return undef if $result->is_error;
674              
675 0           my $stickers = {};
676 0           foreach my $line ($result->lines) {
677 0           my ($key, $value) = ($line =~ /^sticker: (.*)=(.*)$/);
678 0           $stickers->{$key} = $value;
679             }
680              
681 0           return $stickers;
682             }
683              
684             =head2 sticker_find $type $name [$path]
685              
686             Return a list of all the items (optionally under $path) with a sticker of the given name.
687              
688             =cut
689              
690             sub sticker_find {
691 0     0 1   my ($self, $type, $name, $path) = @_;
692 0   0       $path //= '';
693              
694 0           my $result = $self->_send('sticker', 'find', $type, $path, $name);
695 0 0 0       carp $result->message and return undef if $result->is_error;
696              
697 0           my @items = ();
698 0           my $file = '';
699              
700 0           foreach my $line ($result->lines) {
701 0           my ($key, $value) = split /: /, $line, 2;
702 0 0         if ($key eq 'file') {
    0          
703 0           $file = $value;
704             } elsif ($key eq 'sticker') {
705 0           my ($val) = ($value =~ /^\Q$name\E=(.*)$/);
706 0           push @items, { file => $file, sticker => $val };
707             }
708             }
709              
710 0           return @items;
711             }
712              
713             =head2 close
714              
715             Close the connection. This is pretty worthless as the library will just
716             reconnect for the next command.
717              
718             =head2 kill
719              
720             Kill the MPD server.
721              
722             =head2 ping
723              
724             Do nothing. This can be used to keep an idle connection open. If you want to
725             wait for noteworthy events, the C command is better suited.
726              
727             =head2 disable_output $id
728              
729             Disable the given output.
730              
731             =head2 enable_output $id
732              
733             Enable the given output.
734              
735             =head2 outputs
736              
737             Return a list of the available outputs.
738              
739             =head2 commands
740              
741             Return a list of the available commands.
742              
743             =head2 not_commands
744              
745             Return a list of the unavailable commands.
746              
747             =head2 tag_types
748              
749             Return a list of all the avalable song metadata.
750              
751             =head2 url_handlers
752              
753             Return a list of available url handlers.
754              
755             =head2 decoders
756              
757             Return a list of available decoder plugins, along with the MIME types and file
758             extensions associated with them.
759              
760             =head2 subscribe $channel
761              
762             Subscribe to the named channel.
763              
764             =head2 unsubscribe $channel
765              
766             Unsubscribe from the named channel.
767              
768             =head2 channels
769              
770             Return a list of the channels with active clients.
771              
772             =head2 read_messages
773              
774             Return a list of any available messages for this clients subscribed channels.
775              
776             =head2 send_message $channel $message
777              
778             Send a message to the given channel.
779              
780             =cut
781              
782             my $song_parser = sub {
783             my $result = shift;
784              
785             my @songs = ();
786             my $song = {};
787              
788             foreach my $line ($result->lines) {
789             my ($key, $value) = split /: /, $line, 2;
790              
791             if ($key =~ /^(?:file|directory|playlist)$/) {
792             push @songs, $song if exists $song->{type};
793             $song = { type => $key, uri => $value };
794             } else {
795             $song->{$key} = $value;
796             }
797             }
798              
799             return @songs, $song;
800             };
801              
802             my $decoder_parser = sub {
803             my $result = shift;
804              
805             my @plugins = ();
806             my $plugin = {};
807              
808             foreach my $line ($result->lines) {
809             my ($key, $value) = split /: /, $line, 2;
810              
811             if ($key eq 'plugin') {
812             push @plugins, $plugin if exists $plugin->{name};
813             $plugin = { name => $value };
814             } else {
815             push @{$plugin->{$key}}, $value;
816             }
817             }
818              
819             return @plugins, $plugin;
820             };
821              
822             __PACKAGE__->_command('clear_error');
823             __PACKAGE__->_command('current_song', parser => $song_parser);
824             __PACKAGE__->_command('idle');
825             __PACKAGE__->_command('stats');
826             __PACKAGE__->_command('next');
827             __PACKAGE__->_command('pause');
828             __PACKAGE__->_command('play');
829             __PACKAGE__->_command('play_id');
830             __PACKAGE__->_command('previous');
831             __PACKAGE__->_command('seek');
832             __PACKAGE__->_command('seek_id');
833             __PACKAGE__->_command('seek_cur');
834             __PACKAGE__->_command('stop');
835             __PACKAGE__->_command('add');
836             __PACKAGE__->_command('add_id');
837             __PACKAGE__->_command('clear');
838             __PACKAGE__->_command('delete');
839             __PACKAGE__->_command('delete_id');
840             __PACKAGE__->_command('move');
841             __PACKAGE__->_command('move_id');
842             __PACKAGE__->_command('playlist_find', parser => $song_parser);
843             __PACKAGE__->_command('playlist_id', parser => $song_parser);
844             __PACKAGE__->_command('playlist_info', parser => $song_parser);
845             __PACKAGE__->_command('playlist_search', parser => $song_parser);
846             __PACKAGE__->_command('playlist_changes', command => 'plchanges', parser => $song_parser);
847             __PACKAGE__->_command('playlist_changes_pos_id', command => 'plchangesposid');
848             __PACKAGE__->_command('prio');
849             __PACKAGE__->_command('prio_id');
850             __PACKAGE__->_command('shuffle');
851             __PACKAGE__->_command('swap');
852             __PACKAGE__->_command('swapid');
853             __PACKAGE__->_command('list_playlist', parser => $song_parser);
854             __PACKAGE__->_command('list_playlist_info', parser => $song_parser);
855             __PACKAGE__->_command('list_playlists');
856             __PACKAGE__->_command('load');
857             __PACKAGE__->_command('playlist_add');
858             __PACKAGE__->_command('playlist_clear');
859             __PACKAGE__->_command('playlist_delete');
860             __PACKAGE__->_command('playlist_move');
861             __PACKAGE__->_command('rename');
862             __PACKAGE__->_command('rm');
863             __PACKAGE__->_command('save');
864             __PACKAGE__->_command('count');
865             __PACKAGE__->_command('find', parser => $song_parser);
866             __PACKAGE__->_command('find_add');
867             __PACKAGE__->_command('list');
868             __PACKAGE__->_command('list_all', parser => $song_parser);
869             __PACKAGE__->_command('list_all_info', parser => $song_parser);
870             __PACKAGE__->_command('ls_info', parser => $song_parser);
871             __PACKAGE__->_command('search', parser => $song_parser);
872             __PACKAGE__->_command('search_add');
873             __PACKAGE__->_command('search_add_pl');
874             __PACKAGE__->_command('update');
875             __PACKAGE__->_command('rescan');
876             __PACKAGE__->_command('sticker');
877             __PACKAGE__->_command('close');
878             __PACKAGE__->_command('kill');
879             __PACKAGE__->_command('ping');
880             __PACKAGE__->_command('disable_output');
881             __PACKAGE__->_command('enable_output');
882             __PACKAGE__->_command('outputs');
883             __PACKAGE__->_command('config');
884             __PACKAGE__->_command('commands');
885             __PACKAGE__->_command('not_commands');
886             __PACKAGE__->_command('tag_types');
887             __PACKAGE__->_command('url_handlers');
888             __PACKAGE__->_command('decoders', parser => $decoder_parser);
889             __PACKAGE__->_command('subscribe');
890             __PACKAGE__->_command('unsubscribe');
891             __PACKAGE__->_command('channels');
892             __PACKAGE__->_command('read_messages');
893             __PACKAGE__->_command('send_message');
894              
895             1;
896              
897             =head1 TODO
898              
899             =head2 Command Lists
900              
901             MPD supports sending batches of commands but that is not yet available with this API.
902              
903             =head2 Asynchronous IO
904              
905             Event-based handling of the idle command would make this module more robust.
906              
907             =head1 BUGS
908              
909             =head2 Idle connections
910              
911             MPD will close the connection if left idle for too long. This module will
912             reconnect if it senses that this has occurred, but the first call after a
913             disconnect will fail and have to be retried. Calling the C command
914             periodically will keep the connection open if you do not have any real commands
915             to issue. Calling the C command will block until something interesting
916             happens.
917              
918             =head2 Reporting
919              
920             Report any issues on L
921              
922             =head1 AUTHOR
923              
924             Alan Berndt Ealan@eatabrick.orgE
925              
926             =head1 COPYRIGHT
927              
928             Copyright 2013 Alan Berndt
929              
930             =head1 LICENSE
931              
932             Permission is hereby granted, free of charge, to any person obtaining a copy of
933             this software and associated documentation files (the "Software"), to deal in
934             the Software without restriction, including without limitation the rights to
935             use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
936             of the Software, and to permit persons to whom the Software is furnished to do
937             so, subject to the following conditions:
938              
939             The above copyright notice and this permission notice shall be included in all
940             copies or substantial portions of the Software.
941              
942             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
943             IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
944             FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
945             AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
946             LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
947             OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
948             SOFTWARE.
949              
950             =head1 SEE ALSO
951              
952             L, L
953              
954             =cut