diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/install.xml squeezeserver/Slim/Plugin/RadioInfo/install.xml
--- squeezeserver/Slim/Plugin/RadioInfo.orig/install.xml 1970-01-01 01:00:00.000000000 +0100
+++ squeezeserver/Slim/Plugin/RadioInfo/install.xml 2013-03-31 19:55:53.000000000 +0200
@@ -0,0 +1,18 @@
+
+
+ PLUGIN_RADIOINFO_META
+ Claus Muus
+ enabled
+ PLUGIN_RADIOINFO_META
+ mld@clausmuus.de
+ http://www.minidvbinux.de
+ A97BFFEF-7654-42B1-B75B-775930D0BA49
+ Plugins::RadioInfo::Plugin
+
+ SqueezeCenter
+ *
+ 7.5
+
+ 2
+ 1.0
+
diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/Plugin.pm squeezeserver/Slim/Plugin/RadioInfo/Plugin.pm
--- squeezeserver/Slim/Plugin/RadioInfo.orig/Plugin.pm 1970-01-01 01:00:00.000000000 +0100
+++ squeezeserver/Slim/Plugin/RadioInfo/Plugin.pm 2013-03-31 19:55:53.000000000 +0200
@@ -0,0 +1,267 @@
+package Plugins::RadioInfo::Plugin;
+
+use strict;
+
+use vars qw($VERSION);
+use HTML::Entities;
+use Digest::SHA1;
+use HTTP::Request;
+
+use Slim::Networking::SimpleAsyncHTTP;
+use Slim::Networking::SqueezeNetwork;
+use Slim::Utils::Log;
+use Slim::Utils::Prefs;
+
+
+my $log = Slim::Utils::Log->addLogCategory({
+ 'category' => 'plugin.RadioInfo',
+ 'description' => 'PLUGIN_RADIOINFO_META',
+});
+
+my $prefs = preferences('server');
+
+use constant cacheTTL => 15;
+
+my $stations = {
+ NDR1 => {
+ # http://opml.radiotime.com/Tune.ashx?id=s25044&formats=aac,ogg,mp3&partnerId=16&serial=7ea275cff83ed4601509c1592260b72f
+ regex => qr/opml.radiotime.com\/Tune.ashx\?id\=s25044/i,
+ parse => \&parseNDR,
+ url => 'http://www.ndr.de/public/playlist/wn.txt',
+ logo => 'http://d1i6vahw24eb07.cloudfront.net/s25044q.png'
+ },
+ NDR2 => {
+ # http://opml.radiotime.com/Tune.ashx?id=s56867&formats=aac,ogg,mp3&partnerId=16&serial=7ea275cff83ed4601509c1592260b72f
+ regex => qr/opml.radiotime.com\/Tune.ashx\?id\=s56867/i,
+ parse => \&parseNDR,
+ url => 'http://www.ndr.de/public/playlist/ndr2.txt',
+ logo => 'http://d1i6vahw24eb07.cloudfront.net/s17492q.png'
+ },
+};
+
+my $meta = {};
+
+
+
+sub getDisplayName {
+ return 'PLUGIN_RADIOINFO_META';
+}
+
+sub initPlugin {
+ my $class = shift;
+
+ $VERSION = $class->_pluginDataFor('version');
+
+ foreach my $name (keys $stations) {
+ main::DEBUGLOG && $log->is_debug && $log->debug("Register $name");
+
+ Slim::Formats::RemoteMetadata->registerProvider(
+ match => $stations->{$name}->{regex},
+ func => \&provider,
+ );
+ }
+}
+
+sub _pluginDataFor {
+ my $class = shift;
+ my $key = shift;
+
+ my $pluginData = Slim::Utils::PluginManager->dataForPlugin($class);
+
+ if ($pluginData && ref($pluginData) && $pluginData->{$key}) {
+ return $pluginData->{$key};
+ }
+
+ return undef;
+}
+
+sub provider {
+ my ( $client, $url ) = @_;
+ my $station;
+
+ foreach my $name (keys $stations) {
+ if ($url =~ $stations->{$name}->{regex}) {
+ $station = $name;
+ }
+ }
+
+# main::DEBUGLOG && $log->is_debug && $log->debug("RadioInfo received for $station: $url");
+
+ # don't query the meta data every time we're called
+ if ( $client->isPlaying && (!$meta->{$station} || $meta->{$station}->{ttl} <= time) && !$meta->{$station}->{busy} ) {
+ main::DEBUGLOG && $log->is_debug && $log->debug('Fetching data for station ' . $station);
+
+ $meta->{$station}->{busy} = 1;
+
+ my $http = Slim::Networking::SimpleAsyncHTTP->new(
+ sub {
+ $meta->{ $station } = $stations->{$station}->{parse}($client, shift->content, $station);
+ },
+ sub {
+ # in case of an error, don't try too hard...
+ $meta->{ $station } = $stations->{$station}->{parse}($client, '', $station);
+ }
+ );
+ $http->get($stations->{$station}->{url});
+ }
+
+ return $meta->{$station};
+}
+
+
+sub parseNDR {
+ my ( $client, $content, $station ) = @_;
+
+ main::DEBUGLOG && $log->is_debug && $log->debug('Parse ' . $station . ' - ' . $content);
+
+ my $info = {
+ icon => $stations->{$station}->{logo},
+ cover => $stations->{$station}->{logo},
+ artist => undef,
+ title => undef,
+ ttl => time + cacheTTL,
+ };
+
+ # "song_now": "Mrs. Greenbird: Box of colors",
+ if ($content =~ /"song_now"\: "(.*?):(.*?)"/sig) {
+ $info->{artist} = HTML::Entities::decode($1);
+ $info->{title} = HTML::Entities::decode($2);
+ }
+
+ Slim::Control::Request::notifyFromArray( $client, [ 'playlist', 'newsong', $info->{title} ] );
+
+ return $info;
+}
+
+
+=p1
+sub parseContent {
+ my ( $client, $content, $station ) = @_;
+
+ main::DEBUGLOG && $log->is_debug && $log->debug('Parse ' . $station . ' - ' . $content);
+
+ my $info = {
+ icon => $icons->{$station},
+ cover => $icons->{$station},
+ artist => undef,
+ title => undef,
+ ttl => time + cacheTTL,
+ };
+
+ # hopefully we get title/artist information
+ if ($content =~ /"active_with_icon"[^>]*>(.*?)<\/span/sig) {
+ $content = HTML::Entities::decode($1);
+ }
+
+ # if no song is available, try to get the current show's name
+ elsif ($content =~ /(.*?)<\/b>.*class="inactive_with_icon"/sig) {
+ $content = '';
+ $info->{title} = HTML::Entities::decode($1);
+ }
+
+ # ...otherwise try to get the last played song
+ elsif ($content =~ /"active"[^>]*>(.*?)<\/span/sig) {
+ $content = HTML::Entities::decode($1);
+ }
+
+ # oh well...
+ else {
+ $content = '';
+ }
+
+ if ( $content ) {
+ my $i = 0;
+ map {
+ $info->{ ('artist', 'title', '__playtime', '__dummy1', '__dummy2')[$i++] } = _lowercase($_);
+ } split(/
/i, $content);
+ }
+
+ $info->{title} ||= uc($station);
+
+ main::DEBUGLOG && $log->is_debug && $log->debug("Got station information for $station - artist: $info->{artist}, title: $info->{title}");
+
+ $info->{busy} = 0;
+
+ if ( $info->{title} ne $meta->{$station}->{title}
+ || $info->{artist} ne $meta->{$station}->{artist} ) {
+
+ getArtwork( $client, $station, $info );
+ }
+
+ Slim::Control::Request::notifyFromArray( $client, [ 'playlist', 'newsong', $info->{title} ] );
+
+ return $info;
+}
+
+
+sub getArtwork {
+ my ( $client, $station, $info ) = @_;
+
+ return if $station ne 'drs3';
+ return unless $info->{artist};
+
+ main::DEBUGLOG && $log->is_debug && $log->debug("Let's get some artwork...");
+
+ my $args = '?track=' . URI::Escape::uri_escape_utf8( $info->{title} || '' )
+ . '&artist=' . URI::Escape::uri_escape_utf8( $info->{artist} || '' );
+
+ my $http = Slim::Networking::SimpleAsyncHTTP->new(
+ sub {
+ my $html = shift;
+
+ if ( $html && $html->content && $html->content =~ /^http/ ) {
+ my $imageUrl = $html->content;
+
+ main::DEBUGLOG && $log->is_debug && $log->debug("Found title artwork: " . $imageUrl);
+
+ #$meta->{$station}->{icon} = $meta->{$station}->{cover} = $imageUrl;
+
+ $client->playingSong->pluginData( wmaMeta => {
+ icon => $imageUrl,
+ cover => $imageUrl,
+ artist => $info->{artist},
+ title => $info->{title},
+ } );
+
+ Slim::Control::Request::notifyFromArray( $client, [ 'newmetadata' ] );
+ }
+ elsif ( $html && $html->content ) {
+
+ main::DEBUGLOG && $log->is_debug && $log->debug("Nothing found: " . $html->content);
+
+ }
+ else {
+
+ main::DEBUGLOG && $log->is_debug && $log->debug(Data::Dump::dump($html));
+
+ }
+ },
+ sub {
+ logError(Data::Dump::dump(shift));
+ },
+ );
+
+ $http->get( SEARCH_URL . $args );
+
+ return 1;
+}
+
+sub _lowercase {
+ my $s = shift;
+
+ return $s if $s =~ /[a-z]+/;
+
+ # uppercase all first characters
+ $s =~ s/([\w'\`[:alpha:]äöüéàèçôî]+)/\u\L$1/ig;
+
+ # fallback in case locale is wrong
+# $s =~ tr/äöüàéèçôî/ÄÖÜÀÉÈÇÔÎ/;
+
+ $s =~ s/^\s+//;
+ $s =~ s/[\:\s]+$//;
+
+ return $s;
+}
+=cut
+
+1;
\ Kein Zeilenumbruch am Dateiende.
diff -Nur squeezeserver/Slim/Plugin/RadioInfo.orig/strings.txt squeezeserver/Slim/Plugin/RadioInfo/strings.txt
--- squeezeserver/Slim/Plugin/RadioInfo.orig/strings.txt 1970-01-01 01:00:00.000000000 +0100
+++ squeezeserver/Slim/Plugin/RadioInfo/strings.txt 2013-03-31 19:55:53.000000000 +0200
@@ -0,0 +1,3 @@
+PLUGIN_RADIOINFO_META
+ EN Extended radio title info
+ DE Erweiterte Radio Titel Informationen
\ Kein Zeilenumbruch am Dateiende.