All pastes #1005695 Raw Edit

xmms2-psipeptune

public text v1 · immutable
#1005695 ·published 2008-05-03 04:18 UTC
rendered paste body
#!/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 <http://www.gnu.org/licenses/>.
#
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__