[Slim-Checkins] r12809 - in /trunk/server/Slim: Formats/RemoteStream.pm Plugin/Pandora/ProtocolHandler.pm Plugin/RhapsodyDirect/ProtocolHandler.pm Plugin/RhapsodyDirect/RPDS.pm Plugin/RhapsodyDirect/strings.txt Utils/Misc.pm

andy at svn.slimdevices.com andy at svn.slimdevices.com
Thu Aug 30 21:09:38 PDT 2007


Author: andy
Date: Thu Aug 30 21:09:38 2007
New Revision: 12809

URL: http://svn.slimdevices.com?rev=12809&view=rev
Log:
Sync improvements for Pandora and Rhapsody Direct

Modified:
    trunk/server/Slim/Formats/RemoteStream.pm
    trunk/server/Slim/Plugin/Pandora/ProtocolHandler.pm
    trunk/server/Slim/Plugin/RhapsodyDirect/ProtocolHandler.pm
    trunk/server/Slim/Plugin/RhapsodyDirect/RPDS.pm
    trunk/server/Slim/Plugin/RhapsodyDirect/strings.txt
    trunk/server/Slim/Utils/Misc.pm

Modified: trunk/server/Slim/Formats/RemoteStream.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Formats/RemoteStream.pm?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Formats/RemoteStream.pm (original)
+++ trunk/server/Slim/Formats/RemoteStream.pm Thu Aug 30 21:09:38 2007
@@ -129,8 +129,9 @@
 	my $class   = ref $self;
 	my $request = $self->requestString($args->{'client'}, $url, $post);
 	
-	${*$self}{'client'} = $args->{'client'};
-	${*$self}{'create'} = $args->{'create'};
+	${*$self}{'client'}  = $args->{'client'};
+	${*$self}{'create'}  = $args->{'create'};
+	${*$self}{'bitrate'} = $args->{'bitrate'};
 	
 	$log->info("Request: $request");
 

Modified: trunk/server/Slim/Plugin/Pandora/ProtocolHandler.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Plugin/Pandora/ProtocolHandler.pm?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Plugin/Pandora/ProtocolHandler.pm (original)
+++ trunk/server/Slim/Plugin/Pandora/ProtocolHandler.pm Thu Aug 30 21:09:38 2007
@@ -24,23 +24,24 @@
 	my $args   = shift;
 
 	my $client = $args->{client};
+	my $url    = $args->{url};
+	
 	my $track  = $client->pluginData('currentTrack') || {};
+	
+	$log->debug( 'Remote streaming Pandora track: ' . $track->{audioUrl} );
 
 	return unless $track->{audioUrl};
 
 	my $sock = $class->SUPER::new( {
-		url    => $track->{audioUrl},
-		client => $client
+		url     => $track->{audioUrl},
+		client  => $client,
+		bitrate => 128_000,
 	} ) || return;
 	
 	${*$sock}{contentType} = 'audio/mpeg';
-	
-	# XXX: Need some way to get the track length for remote streaming mode
-	
+
 	# XXX: Time counter is not right, it starts from 0:00 as soon as next track 
-	# begins streaming
-	
-	# XXX: Sync not working yet (players will play different tracks)
+	# begins streaming (slimp3/SB1 only)
 	
 	return $sock;
 }
@@ -153,21 +154,23 @@
 	
 	my $track = eval { from_json( $http->content ) };
 	
+	if ( $@ || $track->{error} ) {
+		# We didn't get the next track to play
+		$log->warn( 'Pandora error getting next track: ' . ( $@ || $track->{error} ) );
+		
+		my $url = Slim::Player::Playlist::url($client);
+
+		setCurrentTitle( $client, $url, $client->string('PLUGIN_PANDORA_NO_TRACKS') );
+		
+		$client->update();
+
+		Slim::Player::Source::playmode( $client, 'stop' );
+	
+		return;
+	}
+	
 	if ( $log->is_debug ) {
-		$log->debug( "Got Pandora track: " . Data::Dump::dump($track) );
-	}
-	
-	if ( $track->{error} ) {
-		# We didn't get the next track to play
-		my $url = Slim::Player::Playlist::url($client);
-
-		setCurrentTitle( $client, $url, $client->string('PLUGIN_PANDORA_NO_TRACKS') );
-		
-		$client->update();
-
-		Slim::Player::Source::playmode( $client, 'stop' );
-	
-		return;
+		$log->debug( 'Got Pandora track: ' . Data::Dump::dump($track) );
 	}
 	
 	# Watch for playlist commands
@@ -213,6 +216,19 @@
 sub onDecoderUnderrun {
 	my ( $class, $client, $nextURL, $callback ) = @_;
 	
+	# Special handling needed when synced
+	if ( Slim::Player::Sync::isSynced($client) ) {
+		if ( !Slim::Player::Sync::isMaster($client) ) {
+			# Only the master needs to fetch next track info
+			$log->debug('Letting sync master fetch next Pandora track');
+			return;
+		}
+		else {
+			# XXX: Source does not call skipahead when synced for some reason
+			# Need to restart playback here?
+		}
+	}
+
 	# Flag that we don't want any buffering messages while loading the next track,
 	$client->pluginData( showBuffering => 0 );
 	
@@ -258,7 +274,7 @@
 	my $url     = shift;
 	my @headers = @_;
 	
-	my $bitrate     = 128000;
+	my $bitrate     = 128_000;
 	my $contentType = 'mp3';
 	
 	# Clear previous duration, since we're using the same URL for all tracks
@@ -358,6 +374,13 @@
 sub canDirectStream {
 	my ( $class, $client, $url ) = @_;
 	
+	# We need to check with the base class (HTTP) to see if we
+	# are synced or if the user has set mp3StreamingMethod
+	my $base = $class->SUPER::canDirectStream( $client, $url );
+	if ( !$base ) {
+		return 0;
+	}
+	
 	my $track = $client->pluginData('currentTrack') || {};
 	
 	return $track->{audioUrl} || 0;

Modified: trunk/server/Slim/Plugin/RhapsodyDirect/ProtocolHandler.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Plugin/RhapsodyDirect/ProtocolHandler.pm?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Plugin/RhapsodyDirect/ProtocolHandler.pm (original)
+++ trunk/server/Slim/Plugin/RhapsodyDirect/ProtocolHandler.pm Thu Aug 30 21:09:38 2007
@@ -123,22 +123,6 @@
 	
 	# XXX: When hitting play while currently listening to another Rhapsody track,
 	# no logging is performed
-	
-	# Clear any previous outstanding rpds queries
-	cancel_rpds($client);
-	
-	# Always get a new playback session
-	$log->debug("Requesting new playback session...");
-	
-	# Update the 'Connecting...' text
-	$client->suppressStatus(1);
-	displayStatus( $client, $url, 'PLUGIN_RHAPSODY_DIRECT_GETTING_TRACK_INFO', 30 );
-	
-	# Clear old radio data if any
-	$client->pluginData( radioTrack => 0 );
-	
-	# Display buffering info on loading the next track
-	$client->pluginData( showBuffering => 1 );
 	
 	# Get login info from SN if we don't already have it
 	my $account = $client->pluginData('account');
@@ -169,6 +153,53 @@
 		return;
 	}
 	
+	$log->debug("Ending any previous playback session");
+	
+	my @clients;
+	
+	if ( Slim::Player::Sync::isSynced($client) ) {
+		# if synced, send this packet to all slave players
+		my $master = Slim::Player::Sync::masterOrSelf($client);
+		push @clients, $master, @{ $master->slaves };
+	}
+	else {
+		push @clients, $client;
+	}
+	
+	for my $client ( @clients ) {
+		# Clear any previous outstanding rpds queries
+		cancel_rpds($client);
+		
+		rpds( $client, {
+			data        => pack( 'c', 6 ),
+			callback    => \&getPlaybackSession,
+			onError     => sub {
+				getPlaybackSession( $client, undef, $url, $callback );
+			},
+			passthrough => [ $url, $callback ],
+		} );
+	}
+}
+
+sub getPlaybackSession {
+	my ( $client, $data, $url, $callback ) = @_;
+	
+	# Always get a new playback session
+	$log->debug( $client->id, ' Requesting new playback session...');
+	
+	# Update the 'Connecting...' text
+	$client->suppressStatus(1);
+	displayStatus( $client, $url, 'PLUGIN_RHAPSODY_DIRECT_GETTING_TRACK_INFO', 30 );
+	
+	# Clear old radio data if any
+	$client->pluginData( radioTrack => 0 );
+	
+	# Display buffering info on loading the next track
+	$client->pluginData( showBuffering => 1 );
+	
+	# Get login info
+	my $account = $client->pluginData('account');
+	
 	my $packet = pack 'cC/a*C/a*C/a*C/a*', 
 		2,
 		encode_entities( $account->{username}->[0] ),
@@ -176,6 +207,8 @@
 		encode_entities( decode_base64( $account->{password}->[0] ) ), 
 		$account->{clientType};
 	
+	# When synced, all players will make this request to get a new playback session
+	
 	rpds( $client, {
 		data        => $packet,
 		callback    => \&gotPlaybackSession,
@@ -225,6 +258,12 @@
 			$log->debug("Radio mode: Next track is $url");
 		}
 		else {
+			
+			if ( Slim::Player::Sync::isSynced($client) && !Slim::Player::Sync::isMaster($client) ) {
+				$log->debug('Radio mode: Letting master get next track');
+				return;
+			}
+			
 			# Get the next track and call us back
 			$log->debug('Radio mode: Getting next track...');
 		
@@ -242,13 +281,18 @@
 	my ($trackId) = $url =~ /(Tra\.[^.]+)/;
 	
 	# Get metadata for normal tracks
-	getTrackMetadata( $client, {
-		trackId     => $trackId,
-		callback    => \&gotTrackMetadata,
-		passthrough => [ $client ],
-	} );
+	# If synced, only master should do this
+	
+	if ( !Slim::Player::Sync::isSynced($client) || Slim::Player::Sync::isMaster($client) ) {
+		getTrackMetadata( $client, {
+			trackId     => $trackId,
+			callback    => \&gotTrackMetadata,
+			passthrough => [ $client ],
+		} );
+	}
 	
 	# Get the track URL via the player
+	# When synced, all players will do this to initialize themselves for playback
 	rpds( $client, {
 		data        => pack( 'cC/a*', 3, $trackId ),
 		callback    => \&gotTrackInfo,
@@ -359,18 +403,22 @@
 			onError     => sub {
 				# We don't really care if the logging call fails,
 				# so allow onError to work like the normal callback
-				getNextTrackInfo( $client, undef, $nextURL, $callback );
+				getNextTrackInfo( $client, undef, $nextURL, $callback, 'all' );
 			},
-			passthrough => [ $nextURL, $callback ],
+			passthrough => [ $nextURL, $callback, 'all' ],
 		} );
 	}
 	else {
-		getNextTrackInfo( $client, undef, $nextURL, $callback );
+		getNextTrackInfo( $client, undef, $nextURL, $callback, 'all' );
 	}
 }
 
 sub getNextTrackInfo {
-    my ( $client, undef, $nextURL, $callback ) = @_;
+    my ( $client, undef, $nextURL, $callback, $requestMode ) = @_;
+
+	# requestMode is used when synced to indicate whether only this client
+	# or all clients need to send RPDS 3 packets
+	$requestMode ||= 'client';
 
 	# Radio mode, get next track ID
 	if ( my ($stationId) = $nextURL =~ m{rhapd://(.+)\.rdr} ) {
@@ -381,13 +429,19 @@
 			$log->debug("Radio mode: Next track is $nextURL");
 		}
 		else {
+			
+			if ( Slim::Player::Sync::isSynced($client) && !Slim::Player::Sync::isMaster($client) ) {
+				$log->debug('Radio mode: Letting master get next track');
+				return;
+			}
+			
 			# Get the next track and call us back
 			$log->debug("Radio mode: Getting info about next track ($nextURL)...");
 
 			getNextRadioTrack( $client, {
 				stationId   => $stationId,
 				callback    => \&getNextTrackInfo,
-				passthrough => [ $client, undef, $nextURL, $callback ],
+				passthrough => [ $client, undef, $nextURL, $callback, 'all' ],
 			} );
 			return;
 		}
@@ -397,18 +451,34 @@
 	my ($trackId) = $nextURL =~ /(Tra\.[^.]+)/;
 	
 	# Get metadata for normal tracks
-	getTrackMetadata( $client, {
-		trackId     => $trackId,
-		callback    => \&gotTrackMetadata,
-		passthrough => [ $client ],
-	} );
-	
-	rpds( $client, {
-		data        => pack( 'cC/a*', 3, $trackId ),
-		callback    => \&gotTrackInfo,
-		onError     => \&gotTrackError,
-		passthrough => [ $nextURL, $callback ],
-	} );
+	# If synced, only the master should do this
+	if ( !Slim::Player::Sync::isSynced($client) || Slim::Player::Sync::isMaster($client) ) {
+		getTrackMetadata( $client, {
+			trackId     => $trackId,
+			callback    => \&gotTrackMetadata,
+			passthrough => [ $client ],
+		} );
+	}
+	
+	my @clients;
+	
+	if ( Slim::Player::Sync::isSynced($client) && $requestMode eq 'all' ) {
+		# if synced and requestMode is all, send this packet to all slave players
+		my $master = Slim::Player::Sync::masterOrSelf($client);
+		push @clients, $master, @{ $master->slaves };
+	}
+	else {
+		push @clients, $client;
+	}
+	
+	for my $client ( @clients ) {
+		rpds( $client, {
+			data        => pack( 'cC/a*', 3, $trackId ),
+			callback    => \&gotTrackInfo,
+			onError     => \&gotTrackError,
+			passthrough => [ $nextURL, $callback ],
+		} );
+	}
 }
 
 # On an underrun, restart radio or skip to next track
@@ -659,15 +729,18 @@
 	# When done, callback to Scanner, which will continue on to playback
 	# This is a callback to Source::decoderUnderrun if we are loading the next track
 
-	my $dns = Slim::Networking::Async->new;
-	$dns->open( {
-		Host        => URI->new($mediaUrl)->host,
-		Timeout     => 3, # Default timeout of 10 is too long, 
-		                  # by the time it fails player will underrun and stop
-		onDNS       => $callback,
-		onError     => $callback, # even if it errors, keep going
-		passthrough => [],
-	} );
+	# If synced, only the master calls back
+	if ( !Slim::Player::Sync::isSynced($client) || Slim::Player::Sync::isMaster($client) ) {
+		my $dns = Slim::Networking::Async->new;
+		$dns->open( {
+			Host        => URI->new($mediaUrl)->host,
+			Timeout     => 3, # Default timeout of 10 is too long, 
+			                  # by the time it fails player will underrun and stop
+			onDNS       => $callback,
+			onError     => $callback, # even if it errors, keep going
+			passthrough => [],
+		} );
+	}
 	
 	# Watch for stop commands for logging purposes
 	Slim::Control::Request::subscribe( 
@@ -718,7 +791,8 @@
 		handleError( $error, $client );
 	}
 	else {
-		Slim::Player::Source::jumpto( $client, '+1' );
+		$client->execute([ 'playlist', 'jump', '+1' ]);
+		#Slim::Player::Source::jumpto( $client, '+1' );
 	}
 }
 
@@ -786,17 +860,29 @@
 				$data = pack( 'cC/a*', 4, $songtime );
 			}
 			
-			# Call endPlaybackSession when stopping
-			rpds( $client, {
-				data        => $data,
-				callback    => \&endPlaybackSession,
-				onError     => sub {
-					# We don't really care if the logging call fails,
-					# so allow onError to work like the normal callback
-					endPlaybackSession( $client );
-				},
-				passthrough => [],
-			} );
+			my @clients;
+
+			if ( Slim::Player::Sync::isSynced($client) ) {
+				# if synced, send this packet to all slave players
+				my $master = Slim::Player::Sync::masterOrSelf($client);
+				push @clients, $master, @{ $master->slaves };
+			}
+			else {
+				push @clients, $client;
+			}
+			
+			for my $client ( @clients ) {
+				rpds( $client, {
+					data        => $data,
+					callback    => \&endPlaybackSession,
+					onError     => sub {
+						# We don't really care if the logging call fails,
+						# so allow onError to work like the normal callback
+						endPlaybackSession( $client );
+					},
+					passthrough => [],
+				} );
+			}
 		}
 	}
 }
@@ -807,7 +893,7 @@
 	rpds( $client, {
 		data        => pack( 'c', 6 ),
 		callback    => sub {},
-		onError     => sub {}, # doesn't matter if this one fails
+		onError     => sub {},
 		passthrough => [],
 	} );
 }

Modified: trunk/server/Slim/Plugin/RhapsodyDirect/RPDS.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Plugin/RhapsodyDirect/RPDS.pm?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Plugin/RhapsodyDirect/RPDS.pm (original)
+++ trunk/server/Slim/Plugin/RhapsodyDirect/RPDS.pm Thu Aug 30 21:09:38 2007
@@ -9,6 +9,7 @@
 use Exporter::Lite;
 use HTML::Entities qw(encode_entities);
 use MIME::Base64 qw(decode_base64);
+use Scalar::Util qw(blessed);
 
 use Slim::Utils::Log;
 use Slim::Utils::Misc;
@@ -35,6 +36,8 @@
 	
 	Slim::Utils::Timers::killTimers( $client, \&rpds_timeout );
 	Slim::Utils::Timers::killTimers( $client, \&rpds_resend );
+	
+	return unless blessed($client);
 	
 	# Save callback info for rpds_handler
 	$rpds_args->{$client} = $args;
@@ -125,6 +128,7 @@
 		if ( $ENV{SLIM_SERVICE} ) {
 			logError( $client, 'RPDS_EA_FAILED' );
 		}
+		$log->debug('RPDS: getEA failed');
 		return;
 	}
 	
@@ -151,9 +155,6 @@
 			
 			my $error = $client->string('PLUGIN_RHAPSODY_DIRECT_INVALID_SESSION');
 			
-			# Stop the player
-			Slim::Player::Source::playmode( $client, 'stop' );
-			
 			# Track session errors so we don't get in a loop
 			my $sessionErrors = $client->pluginData('sessionErrors') || 0;
 			$sessionErrors++;
@@ -163,6 +164,9 @@
 			if ( $sessionErrors > 1 ) {
 				# On the second error, give up
 				$log->debug("Giving up after multiple invalid session errors");
+				
+				# Stop the player
+				Slim::Player::Source::playmode( $client, 'stop' );
 				
 				handleError( $error, $client );
 				
@@ -170,6 +174,16 @@
 			}
 			
 			$client->pluginData( sessionErrors => $sessionErrors );
+			
+			# Retry if command was 3 to get track info
+			if ( $sent_cmd eq '3' ) {
+				$log->debug( $client->id, ' Getting a new session and retrying' );
+				retry_new_session( $client, $rpds );
+				return;
+			}
+			
+			# Stop the player
+			Slim::Player::Source::playmode( $client, 'stop' );
 			
 			my $restart = sub {
 				# Clear radio data if any, so we always get a new radio track
@@ -201,57 +215,22 @@
 	elsif ( $got_cmd eq '-2' ) {
 		# Player indicates it needs a new session
 		
+		# Ignore if command was 6 to end a session
+		if ( $sent_cmd eq '6' ) {
+			my $cb = $rpds->{onError} || sub {};
+			$cb->();
+			return;
+		}
+		
 		$log->warn( $client->id . " Received RPDS -2, player needs a new session");
 		
 		if ( $ENV{SLIM_SERVICE} ) {
 			logError( $client, 'RPDS_NO_SESSION' );
 		}
-
-		my $account = $client->pluginData('account');
-		
-		if ( !$account ) {
-			my $accountURL = Slim::Networking::SqueezeNetwork->url( '/api/rhapsody/account' );
-
-			my $http = Slim::Networking::SqueezeNetwork->new(
-				\&Slim::Plugin::RhapsodyDirect::ProtocolHandler::gotAccount,
-				\&Slim::Plugin::RhapsodyDirect::ProtocolHandler::gotAccountError,
-				{
-					client => $client,
-					cb     => sub {
-						# reset the rpds and try again
-						$rpds_args->{$client} = $rpds;
-						$data_ref = pack 'c', '-2';
-						rpds_handler( $client, \$data_ref );
-					},
-					ecb    => sub {
-						my $error = shift;
-						$error = $client->string('PLUGIN_RHAPSODY_DIRECT_ERROR_ACCOUNT') . ": $error";
-						handleError( $error, $client );
-					},
-				},
-			);
-
-			$log->debug("Getting Rhapsody account from SqueezeNetwork");
-
-			$http->get( $accountURL );
-
-			return;
-		}
-
-		my $packet = pack 'cC/a*C/a*C/a*C/a*', 
-			2,
-			encode_entities( $account->{username}->[0] ),
-			$account->{cobrandId}, 
-			encode_entities( decode_base64( $account->{password}->[0] ) ), 
-			$account->{clientType};
-		
-		rpds( $client, {
-			data        => $packet,
-			callback    => \&rpds_resend,
-			onError     => \&handleError,
-			passthrough => [ $rpds ],
-		} );
-		
+		
+		# Get a new session and retry the previous rpds command
+		retry_new_session( $client, $rpds );
+
 		return;
 	}
 	elsif ( $got_cmd eq '-3' ) {
@@ -292,7 +271,7 @@
 	}	
 	
 	if ( !$rpds || $got_cmd ne $sent_cmd ) {
-		$log->warn( $client->id . ' Received unrequested or old RPDS packet, ignoring' );
+		$log->warn( $client->id . " Ignoring unrequested or old RPDS packet (got $got_cmd, expected $sent_cmd)" );
 		
 		if ( $ENV{SLIM_SERVICE} ) {
 			logError( $client, 'RPDS_OLD', "got $got_cmd, ignoring" );
@@ -317,7 +296,9 @@
 sub rpds_resend {
 	my ( $client, undef, $rpds ) = @_;
 	
-	$log->warn( $client->id . ' Re-sending RPDS packet');
+	if ( $log->is_debug ) {
+		$log->debug( $client->id . ' Re-sending RPDS packet: ' . Data::Dump::dump( $rpds->{data} ) );
+	}
 	
 	rpds( $client, {
 		data        => $rpds->{data},
@@ -327,5 +308,56 @@
 	} );
 }
 
+sub retry_new_session {
+	my ( $client, $rpds ) = @_;
+	
+	my $account = $client->pluginData('account');
+	
+	if ( !$account ) {
+		my $accountURL = Slim::Networking::SqueezeNetwork->url( '/api/rhapsody/account' );
+
+		my $http = Slim::Networking::SqueezeNetwork->new(
+			\&Slim::Plugin::RhapsodyDirect::ProtocolHandler::gotAccount,
+			\&Slim::Plugin::RhapsodyDirect::ProtocolHandler::gotAccountError,
+			{
+				client => $client,
+				cb     => sub {
+					# try again
+					retry_new_session( $client, $rpds );
+				},
+				ecb    => sub {
+					my $error = shift;
+					$error = $client->string('PLUGIN_RHAPSODY_DIRECT_ERROR_ACCOUNT') . ": $error";
+					handleError( $error, $client );
+				},
+			},
+		);
+
+		$log->debug("Getting Rhapsody account from SqueezeNetwork");
+
+		$http->get( $accountURL );
+
+		return;
+	}
+	
+	if ( $log->is_debug ) {
+		$log->debug( $client->id, ' Getting a new session and then retrying ' . Data::Dump::dump( $rpds->{data} ) );
+	}
+
+	my $packet = pack 'cC/a*C/a*C/a*C/a*', 
+		2,
+		encode_entities( $account->{username}->[0] ),
+		$account->{cobrandId}, 
+		encode_entities( decode_base64( $account->{password}->[0] ) ), 
+		$account->{clientType};
+	
+	rpds( $client, {
+		data        => $packet,
+		callback    => \&rpds_resend,
+		onError     => \&handleError,
+		passthrough => [ $rpds ],
+	} );
+}
+
 1;
 

Modified: trunk/server/Slim/Plugin/RhapsodyDirect/strings.txt
URL: http://svn.slimdevices.com/trunk/server/Slim/Plugin/RhapsodyDirect/strings.txt?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Plugin/RhapsodyDirect/strings.txt (original)
+++ trunk/server/Slim/Plugin/RhapsodyDirect/strings.txt Thu Aug 30 21:09:38 2007
@@ -99,4 +99,7 @@
 
 PLUGIN_RHAPSODY_DIRECT_ERROR_ACCOUNT
 	DE	Konnte über das SqueezeNetwork keine Account-Informationen finden.
-	EN	Unable to retrieve account details from SqueezeNetwork.
+	EN	Unable to retrieve account details from SqueezeNetwork.
+
+PLUGIN_RHAPSODY_DIRECT_INVALID_SESSION
+	EN	Invalid playback session.

Modified: trunk/server/Slim/Utils/Misc.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Utils/Misc.pm?rev=12809&r1=12808&r2=12809&view=diff
==============================================================================
--- trunk/server/Slim/Utils/Misc.pm (original)
+++ trunk/server/Slim/Utils/Misc.pm Thu Aug 30 21:09:38 2007
@@ -855,7 +855,7 @@
 
 	opendir(DIR, $dirname) || do {
 
-		logError("opendir on [$dirname] failed: $!");
+		$log->debug("opendir on [$dirname] failed: $!");
 
 		return @diritems;
 	};



More information about the checkins mailing list