[Slim-Checkins] r33940 - in /7.7/trunk/server: Changelog7.html Slim/Plugin/RadioTime/Metadata.pm Slim/Plugin/RadioTime/Plugin.pm
[email protected] Thu, 19 Apr 2012 09:37:18 -0000
| Newsgroups | gmane.music.equipment.slimdevices.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mherger
Date: Thu Apr 19 02:37:17 2012
New Revision: 33940
URL: http://svn.slimdevices.com/slim?rev=33940&view=rev
Log:
Bug: n/a
Description: add support for TuneIn Radio artwork
Modified:
7.7/trunk/server/Changelog7.html
7.7/trunk/server/Slim/Plugin/RadioTime/Metadata.pm
7.7/trunk/server/Slim/Plugin/RadioTime/Plugin.pm
Modified: 7.7/trunk/server/Changelog7.html
URL: http://svn.slimdevices.com/slim/7.7/trunk/server/Changelog7.html?rev=33940&r1=33939&r2=33940&view=diff
==============================================================================
--- 7.7/trunk/server/Changelog7.html (original)
+++ 7.7/trunk/server/Changelog7.html Thu Apr 19 02:37:17 2012
@@ -2,6 +2,7 @@
<ul>
<li>Server Changes:</li>
<ul>
+ <li>Improved support for radio station artwork. Improved radio station browsing.</li>
<li>Remove legacy Napster plugin. Napster now is a Rhapsody company.</li>
</ul>
<br />
Modified: 7.7/trunk/server/Slim/Plugin/RadioTime/Metadata.pm
URL: http://svn.slimdevices.com/slim/7.7/trunk/server/Slim/Plugin/RadioTime/Metadata.pm?rev=33940&r1=33939&r2=33940&view=diff
==============================================================================
--- 7.7/trunk/server/Slim/Plugin/RadioTime/Metadata.pm (original)
+++ 7.7/trunk/server/Slim/Plugin/RadioTime/Metadata.pm Thu Apr 19 02:37:17 2012
@@ -8,6 +8,8 @@
use Slim::Formats::XML;
use Slim::Music::Info;
use Slim::Networking::SimpleAsyncHTTP;
+use Slim::Plugin::RadioTime::Plugin;
+use Slim::Utils::Cache;
use Slim::Utils::Log;
use Slim::Utils::Prefs;
@@ -16,7 +18,9 @@
my $log = logger('formats.metadata');
my $prefs = preferences('plugin.radiotime');
-use constant META_URL => 'http://opml.radiotime.com/NowPlaying.aspx?partnerId=16';
+use constant PARTNER_ID => 16;
+use constant META_URL => 'http://opml.radiotime.com/NowPlaying.aspx?partnerId=' . PARTNER_ID;
+use constant CONFIG_URL => 'http://opml.radiotime.com/Config.ashx?c=api&partnerId=' . PARTNER_ID . '&serial=';
my $ICON = Slim::Plugin::RadioTime::Plugin->_pluginDataFor('icon');
@@ -32,6 +36,48 @@
match => qr/(?:radiotime|tunein)\.com/,
func => \&provider,
);
+}
+
+sub getConfig {
+ my $client = shift;
+
+ Slim::Utils::Timers::killTimers( $client, \&getConfig );
+
+ my $http = Slim::Networking::SimpleAsyncHTTP->new(
+ \&_gotConfig,
+ \&_gotConfig, # TODO - error handler
+ {
+ client => $client,
+ timeout => 30,
+ },
+ );
+
+ Slim::Utils::Timers::setTimer(
+ $client,
+ time() + 60*60*23, # repeat at least every 24h
+ \&getConfig,
+ );
+
+ $http->get( CONFIG_URL . Slim::Plugin::RadioTime::Plugin->getSerial($client) );
+}
+
+sub _gotConfig {
+ my $http = shift;
+ my $client = $http->params('client');
+
+ my $feed = eval { Slim::Formats::XML::parseXMLIntoFeed( $http->contentRef ) };
+
+ if ( $@ ) {
+ main::DEBUGLOG && $log->debug( "Error fetching TuneIn artwork configuration: $@" );
+ }
+ elsif ( $feed && $feed->{items} && (my $config = $feed->{items}->[0]) ) {
+ if ( (my $lookup = $config->{'albumart.lookupurl'}) && (my $url = $config->{'albumart.url'}) ) {
+ $client->pluginData( artworkConfig => {
+ lookupurl => $lookup,
+ albumarturl => $url,
+ } );
+ }
+ }
}
sub defaultMeta {
@@ -47,6 +93,10 @@
sub parser {
my ( $client, $url, $metadata ) = @_;
+ if ( $client && !$client->pluginData('artworkConfig') ) {
+ getConfig($client);
+ }
+
# If a station is providing Icy metadata, disable metadata
# provided by RadioTime
if ( $metadata =~ /StreamTitle=\'([^']+)\'/ ) {
@@ -57,6 +107,8 @@
Slim::Utils::Timers::killTimers( $client, \&fetchMetadata );
$client->master->pluginData( metadata => undef );
}
+
+ fetchArtwork($client, $url, 'delayed');
# Let the default metadata handler process the Icy metadata
$client->master->pluginData( hasIcy => $url );
@@ -73,6 +125,8 @@
Slim::Utils::Timers::killTimers( $client, \&fetchMetadata );
$client->master->pluginData( metadata => undef );
}
+
+ fetchArtwork($client, $url, 'delayed');
# Let the default metadata handler process the WMA metadata
$client->master->pluginData( hasIcy => $url );
@@ -216,12 +270,7 @@
# Also cache the image URL in case the stream has other metadata
if ( $meta->{cover} ) {
- my $cache = Slim::Utils::Cache->new();
- $cache->set( "remote_image_$url" => $meta->{cover}, 86400 * 7 );
-
- if ( my $song = $client->playingSong() ) {
- $song->pluginData( httpCover => $meta->{cover} );
- }
+ setArtwork($client, $url, $meta->{cover});
}
if ( main::DEBUGLOG && $log->is_debug ) {
@@ -229,6 +278,8 @@
}
$client->master->pluginData( metadata => $meta );
+
+ fetchArtwork($client, $url);
main::DEBUGLOG && $log->is_debug && $log->debug( "Will check metadata again in $ttl seconds" );
@@ -258,4 +309,125 @@
$client->master->pluginData( metadata => $meta );
}
+
+sub fetchArtwork {
+ my ($client, $url, $delayed) = @_;
+
+ main::DEBUGLOG && $log->debug( "Getting artwork for $url" );
+
+ Slim::Utils::Timers::killTimers( $client, \&_fetchArtwork );
+
+ if ($delayed) {
+ $delayed = Slim::Music::Info::getStreamDelay($client);
+
+ # if the stream has ICY metadata, give it a moment to parse it
+ Slim::Utils::Timers::setTimer(
+ $client,
+ time() + $delayed + 1,
+ \&_fetchArtwork,
+ $url
+ );
+ }
+ else {
+ _fetchArtwork($client, $url);
+ }
+}
+
+sub _fetchArtwork {
+ my ( $client, $url ) = @_;
+
+ my $config = $client->pluginData('artworkConfig') || return;
+ my $handler = Slim::Player::ProtocolHandlers->handlerForURL($url);
+
+ if ( $handler && $handler->can('getMetadataFor') ) {
+ my $track = $handler->getMetadataFor( $client, $url );
+
+ main::DEBUGLOG && $log->debug( 'Getting TuneIn artwork based on metadata:', Data::Dump::dump($track) );
+
+ # keep track of the station logo in case we don't get track artwork
+ # [ps] => podcast or station
+ # t => Thumbnail
+ # q => sQuare
+ # g => Giant
+ # d => meDium
+ if ( !$client->pluginData('stationLogo') && $track->{cover} && $track->{cover} =~ m{/[ps]\d+[tqgd]\.(?:jpg|jpeg|png|gif)$}i ) {
+ main::DEBUGLOG && $log->debug( 'Storing default station artwork: ' . $track->{cover} );
+
+ $client->pluginData( stationLogo => $track->{cover} );
+ }
+
+ if ( $track && $track->{title} && $track->{artist} ) {
+
+ my $lookupurl = sprintf($config->{lookupurl} . '?partnerId=%s&serial=%s&artist=%s&title=%s',
+ PARTNER_ID,
+ Slim::Plugin::RadioTime::Plugin->getSerial($client),
+ $track->{artist},
+ $track->{title},
+ );
+
+ return if $client->master->pluginData('fetchingArtwork') && $client->master->pluginData('fetchingArtwork') eq $lookupurl;
+
+ $client->master->pluginData( fetchingArtwork => $lookupurl );
+
+ my $http = Slim::Networking::SimpleAsyncHTTP->new(
+ \&_gotArtwork,
+ \&_gotArtwork, # we'll happily fall back to the station artwork if we fail
+ {
+ client => $client,
+ url => $url,
+ timeout => 30,
+ },
+ );
+
+ $http->get( $lookupurl );
+ }
+ # fallback to station artwork
+ elsif ( my $artworkUrl = $client->pluginData('stationLogo') ) {
+ setArtwork($client, $url, $artworkUrl);
+ }
+ }
+}
+
+sub _gotArtwork {
+ my $http = shift;
+ my $client = $http->params('client');
+ my $url = $http->params('url');
+
+ $client->master->pluginData( fetchingArtwork => 0 );
+
+ my $feed = eval { Slim::Formats::XML::parseXMLIntoFeed( $http->contentRef ) };
+
+ if ( $@ ) {
+ main::DEBUGLOG && $log->debug( "Error fetching TuneIn artwork: $@" );
+ }
+ else {
+ main::DEBUGLOG && $log->debug( 'Received TuneIn track artwork information: ', Data::Dump::dump($feed) );
+ }
+
+ if ( $feed && $feed->{items} && $feed->{items}->[0] && (my $key = $feed->{items}->[0]->{album_art} || $feed->{items}->[0]->{artist_art}) ) {
+ my $config = $client->pluginData('artworkConfig');
+ my $artworkUrl = $config->{albumarturl} . $key . 'g.jpg';
+
+ setArtwork($client, $url, $artworkUrl);
+ }
+ # fallback to station artwork
+ elsif ( my $artworkUrl = $client->pluginData('stationLogo') ) {
+ setArtwork($client, $url, $artworkUrl);
+ }
+}
+
+sub setArtwork {
+ my ($client, $url, $artworkUrl) = @_;
+
+ my $cache = Slim::Utils::Cache->new();
+ $cache->set( "remote_image_$url", $artworkUrl, 3600 );
+
+ if ( my $song = $client->playingSong() ) {
+ $song->pluginData( httpCover => $artworkUrl );
+
+ main::DEBUGLOG && $log->debug("Updating stream artwork to $artworkUrl");
+ Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] );
+ }
+}
+
1;
Modified: 7.7/trunk/server/Slim/Plugin/RadioTime/Plugin.pm
URL: http://svn.slimdevices.com/slim/7.7/trunk/server/Slim/Plugin/RadioTime/Plugin.pm?rev=33940&r1=33939&r2=33940&view=diff
==============================================================================
--- 7.7/trunk/server/Slim/Plugin/RadioTime/Plugin.pm (original)
+++ 7.7/trunk/server/Slim/Plugin/RadioTime/Plugin.pm Thu Apr 19 02:37:17 2012
@@ -59,7 +59,7 @@
# Bug 15569, special case for RadioTime stations, use their trackinfo menu
my $rtinfo = URI->new($url)->query_form_hash;
- my $serial = Digest::MD5::md5_hex( $client->uuid || $client->id );
+ my $serial = $class->getSerial($client);
my $uri = URI->new('http://opml.radiotime.com/Options.ashx');
$uri->query_form( id => $rtinfo->{id}, partnerId => $rtinfo->{partnerId}, serial => $serial );
@@ -67,4 +67,11 @@
return $uri->as_string;
}
+sub getSerial {
+ my ( $class, $client ) = @_;
+
+ return '' unless $client;
+ return Digest::MD5::md5_hex( $client->uuid || $client->id );
+}
+
1;