#!/usr/bin/perl # # xmms2-psipeptune -- updates Psi tune file with data from XMMS2 # Copyright (c)2008 Kacper Gutowski mwgamera at gmail dot com # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # use strict; use Audio::XMMSClient; # your $PSIDATADIR/tune here use constant TUNEPATH => $ENV{HOME}.'/.psi/tune'; # connect to demon my $xc = Audio::XMMSClient->new('xmms2-psipeptune'); $xc->connect or die $xc->get_last_error; # data my $status = eval { $xc->playback_status->wait->value }; my $cid = eval { $xc->playback_current_id->wait->value }; my %info = eval { %{$xc->medialib_get_info($cid)->wait->value} }; # publish initial values save(); # catch termination to clear tune file $xc->disconnect_callback_set( sub { $cid = $status = -1; undef %info; save(); print STDERR"Abnormal termination.\n"; exit 1; }); eval { $xc->broadcast_quit->notifier_set( sub { $cid = $status = -1; undef %info; save(); print STDERR"Server quit.\n"; exit 0; }); 1 } or die $xc->get_last_error; # catch signals $SIG{INT} = $SIG{TERM} = sub { $cid = $status = -1; undef %info; save(); exit 0; }; # setup event handlers eval { $xc->broadcast_medialib_entry_changed->notifier_set( sub { if ($cid == (my$r=shift->value)) { my %i = getinfo(); my %ti = %info; %info = %i; save() if inse(%ti) ne inse(%i); } }); 1 } or die $xc->get_last_error; eval { $xc->broadcast_playback_status->notifier_set( sub { my$r=shift->value; my $ts = $status; $status = $r; save() if $ts != $r && $r != 2; }); 1 } or die $xc->get_last_error; eval { $xc->broadcast_playback_current_id->notifier_set( sub { my $r=shift->value; my $tc = $cid; $cid = $r; %info = getinfo(); save() if $tc != $r; }); 1 } or die $xc->get_last_error; # main loop $xc->loop; exit; # get info hash of current (ID=$cid) position sub getinfo { return eval{%{$xc->medialib_get_info($cid)->wait->value}} } # synchronise data with file sub save { if ($status!=1) { print STDERR"Stopped.\n" if $status<1; truncate TUNEPATH, 0; return 0; } # diagnostic print STDERR"Publishing #$cid $info{artist} - $info{title} ". ($info{duration}?sprintf("[%d:%02d]", int($info{duration}/60000), int($info{duration}/1000)%60):'')."\n"; # publish ( http://psi-im.org/wiki/Publish_Tune ) open F,'>'.TUNEPATH or die $!; print F "$info{title}\n"; print F "$info{artist}\n"; print F "$info{album}\n"; print F "$info{tracknr}\n"; print F int($info{duration}/1000)."\n"; close F or die $!; return 0; } # serialise info hash for comparison sub inse { (%_) = @_; return "$_{id}\1$_{tracknr}\1$_{title}\1" ."$_{artist}\1$_{duration}\1$_{url}\1"; } __END__