use
vars
qw(@ISA $VERSION)
;
@ISA
=
qw(Audio::Daemon)
;
$VERSION
=
'0.99Beta'
;
sub
new {
my
$class
=
shift
;
my
$self
=
$class
->SUPER::new(
@_
);
bless
$self
,
$class
;
$self
->remote(Xmms::Remote->new);
$self
->config(Xmms::Config->new(Xmms::Config->file));
my
$remote
=
$self
->remote;
unless
(
$remote
->is_running) {
exec
"xmms"
unless
(
fork
());
sleep
1;
}
$self
->{state} = {
random
=>
$remote
->is_shuffle,
repeat
=>
$remote
->is_repeat};
return
$self
;
}
sub
remote {
my
$self
=
shift
;
$self
->{_remote} =
shift
if
(
scalar
@_
);
return
$self
->{_remote};
}
sub
config {
my
$self
=
shift
;
$self
->{_config} =
shift
if
(
scalar
@_
);
return
$self
->{_config};
}
sub
stop {
my
$self
=
shift
;
$self
->remote->stop;
}
sub
play {
my
$self
=
shift
;
my
$remote
=
shift
;
if
(
defined
$remote
->{args}[0]) {
$self
->info(
"trying to play index: "
.
$remote
->{args}[0]);
$self
->remote->set_playlist_pos(
$remote
->{args}[0]);
}
$self
->remote->play;
}
sub
pause {
my
$self
=
shift
;
$self
->remote->pause;
}
sub
add {
my
$self
=
shift
;
my
$remote
=
shift
;
$self
->remote->playlist(
$remote
->{args});
}
sub
del {
my
$self
=
shift
;
my
$remote
=
shift
;
if
(
$remote
->{args}[0] eq
'all'
) {
$self
->remote->stop;
$self
->remote->playlist_clear;
}
else
{
foreach
(
sort
{
$b
<=>
$a
} @{
$remote
->{args}}) {
$self
->debug(
"Trying to remove index: $_"
);
$self
->remote->playlist_delete(
$_
);
}
}
}
sub
next
{
my
$self
=
shift
;
$self
->remote->playlist_next;
}
sub
prev {
my
$self
=
shift
;
$self
->remote->playlist_prev;
}
sub
random {
my
$self
=
shift
;
my
$remote
=
shift
;
$self
->debug(
"Trying to set "
.(
$remote
->{args}[0]));
if
(
defined
$remote
->{args}[0] &&
$self
->remote->is_shuffle !=
$remote
->{args}[0]) {
$self
->remote->toggle_shuffle;
$self
->info(
"Toggled shuffle"
);
}
}
sub
repeat {
my
$self
=
shift
;
my
$remote
=
shift
;
$self
->debug(
"Trying to set "
.(
$remote
->{args}[0]));
if
(
defined
$remote
->{args}[0] &&
$self
->remote->is_repeat !=
$remote
->{args}[0]) {
$self
->remote->toggle_repeat;
$self
->info(
"Toggled repeat"
);
}
}
sub
list {
my
$self
=
shift
;
my
$remote
=
shift
;
$self
->{state}{showlist} = 1;
}
sub
jump {
my
$self
=
shift
;
my
$remote
=
shift
;
my
$move
=
$remote
->{args}[0];
(
my
$dval
=
$move
) =~ s/\D//g;
my
$change
=
$dval
;
if
(
$move
=~/s$/i) {
$dval
*= 1000;
}
if
(
$move
=~/^([\+\-]{1})/) {
$change
= $1;
my
$elapse
=
$self
->remote->get_output_time;
my
$ttime
=
$self
->remote->get_playlist_time(
$self
->remote->get_playlist_pos);
if
(
$change
eq
'+'
) {
$dval
+=
$elapse
;
$dval
=
$ttime
if
(
$dval
>
$ttime
);
}
else
{
$dval
=
$elapse
-
$dval
;
$dval
= 0
if
(
$dval
< 0);
}
}
$self
->info(
"Jumping: rcvd \""
.
$remote
->{args}[0].
"\", sending jump("
.
$change
.
")"
);
$remote
->jump_to_time(
$dval
);
}
sub
vol {
my
$self
=
shift
;
my
$remote
=
shift
;
}
sub
get_info {
my
$self
=
shift
;
my
@out
;
if
(
$self
->remote->is_paused) {
push
@out
,
"state:1"
;
}
elsif
(
$self
->remote->is_playing) {
push
@out
,
"state:2"
;
}
else
{
push
@out
,
"state:0"
;
}
push
@out
,
"random:"
.
$self
->remote->is_shuffle;
push
@out
,
"repeat:"
.
$self
->remote->is_repeat;
push
@out
,
"id:"
.
$self
->remote->get_playlist_pos;
push
@out
,
'rateinfo:'
.(
join
','
,
$self
->remote->get_info);
my
$elapse
=
$self
->remote->get_output_time;
my
$ttime
=
$self
->remote->get_playlist_time(
$self
->remote->get_playlist_pos);
my
$tdiff
=
$ttime
-
$elapse
;
push
@out
,
'frame:'
.
$elapse
.
','
.
$ttime
.
','
.
sprintf
(
'%.2f'
,
$elapse
/1000).
','
.
sprintf
(
'%.2f'
, (
$tdiff
/1000));
my
$tag
= get_mp3tag(
$self
->remote->get_playlist_file(
$self
->remote->get_playlist_pos));
if
(
defined
$tag
&&
ref
$tag
) {
push
@out
,
"title:"
.
$tag
->{TITLE};
push
@out
,
"artist:"
.
$tag
->{ARTIST};
push
@out
,
"album:"
.
$tag
->{ALBIM};
push
@out
,
"genre:"
.
$tag
->{GENRE};
}
push
@out
,
"url:"
.
$self
->remote->get_playlist_file(
$self
->remote->get_playlist_pos);
my
(
$lvol
,
$rvol
) =
$self
->remote->get_volume;
push
@out
,
"vol:$lvol $rvol\n"
;
if
(
$self
->{state}{showlist}) {
push
@out
,
"list:"
.(
join
$self
->{subsep}, @{
$self
->remote->get_playlist_files});
$self
->{state}{showlist} = 0;
}
map
{
$self
->debug(
$_
) }
@out
;
return
\
@out
;
}
sub
mainloop {
my
$self
=
shift
;
my
$socket
=
$self
->
socket
;
my
$s
= IO::Select->new(
$socket
);
while
(1) {
if
(
$s
->can_read(0)) {
$self
->debug(
"-------------------------------------"
);
my
$remote
=
eval
{
$self
->read_client; };
if
($@) {
$self
->crit($@);
next
;
}
if
(!
defined
$remote
) {
$self
->crit(
"big issue, reading from client came back null"
);
next
;
}
my
@cmds
=
qw/add del play next nextlist prev prevlist pause
jump stop info list random repeat vol/
;
if
(
scalar
grep
{/^
$remote
->{cmd}$/}
@cmds
) {
my
$method
=
'$self->'
.
$remote
->{cmd}.
'($remote)'
;
eval
"$method"
;
}
$self
->send_status;
}
}
}
sub
send_status {
my
$self
=
shift
;
my
$socket
=
$self
->
socket
;
my
$out
=
$self
->get_info;
my
$out
=
join
$self
->{sep},
@$out
;
$socket
->
send
(
$out
);
}
1;