浏览代码

Fix some issues when SqueezeAmp doesn't have a display

* only push simple prefs on the list of automatically managed items - hashes and lists can't be managed by the Settings super class
* only push display/artwork related prefs on the list if deal with a player which has a display
* move most artwork/display handling code out of the plugin to the Player class
* rename `eq` pref to `equalizer`, as `eq` is a reserved word
* automatically update the player when the `equalizer` pref is changed
* strip down Plugin to the bare minimum needed with any SqueezeAMP, no matter whether it has a display or not
Michael Herger 4 年之前
父节点
当前提交
9f23b79818

+ 22 - 21
plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html

@@ -3,74 +3,75 @@
 	[% IF prefs.pref_width %]
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_WIDTH" desc="PLUGIN_SQUEEZEESP32_WIDTH_DESC" %]
 			<!--<input type="text" readonly class="stdedit" name="pref_width" id="width" value="[% prefs.pref_width %]" size="3">-->
+			<input type="hidden" name="pref_width" value="[% prefs.pref_width %]">
 			[% prefs.pref_width %]
 		[% END %]
-	
+
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SMALL_VU" desc="PLUGIN_SQUEEZEESP32_SMALL_VU_DESC" %]
 			<input type="number" min="10" max= "50" step="5"class="stdedit" name="pref_small_VU" id="small_VU" value="[% prefs.pref_small_VU %]" size="3">
 		[% END %]
-	
+
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE" desc="PLUGIN_SQUEEZEESP32_SPECTRUM_SCALE_DESC" %]
 			<input type="number" min="10" max= "50" step="5" class="stdedit" name="pref_spectrum_scale" id="spectrum_scale" value="[% prefs.pref_spectrum.scale %]" size="3">
 		[% END %]
-	
+
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_SMALL_SPECTRUM" desc="PLUGIN_SQUEEZEESP32_SMALL_SPECTRUM_DESC" %]
 			[% "PLUGIN_SQUEEZEESP32_SMALL_SPECTRUM_SIZE" | string %]&nbsp
 			<input type="number" min="10" max= "50" step="5"class="stdedit" name="pref_spectrum_small_size" id="spectrum_small_size" value="[% prefs.pref_spectrum.small.size %]" size="3">
 			[% "PLUGIN_SQUEEZEESP32_SMALL_SPECTRUM_BAND" | string %]&nbsp
 			<input type="text" class="stdedit" name="pref_spectrum_small_band" id="spectrum_small_band" value="[% prefs.pref_spectrum.small.band %]" size="3">
 		[% END %]
-	
+
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND" desc="PLUGIN_SQUEEZEESP32_FULL_SPECTRUM_BAND_DESC" %]
 			<input type="text" class="stdedit" name="pref_spectrum_full_band" id="spectrum_full_band" value="[% prefs.pref_spectrum.full.band %]" size="3">
 		[% END %]
-	
+
 		[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_ARTWORK" desc="PLUGIN_SQUEEZEESP32_ARTWORK_DESC" %]
 			[% "PLUGIN_SQUEEZEESP32_ARTWORK_ENABLE" | string %]&nbsp
-			<input type="checkbox" name="pref_artwork_enable" [% IF prefs.pref_artwork.enable %] checked [% END %]>
+			<input type="checkbox" name="pref_artwork_enable" [% IF prefs.pref_artwork.enable %] checked [% END %]>&nbsp;
 			[% "PLUGIN_SQUEEZEESP32_ARTWORK_X" | string %]&nbsp
 			<input type="text" class="stdedit" name="pref_artwork_x" id="artwork_x" value="[% prefs.pref_artwork.x %]" size="2">
 			[% "PLUGIN_SQUEEZEESP32_ARTWORK_Y" | string %]&nbsp
 			<input type="text" class="stdedit" name="pref_artwork_y" id="artwork_y" value="[% prefs.pref_artwork.y %]" size="2">
 		[% END %]
 
-		<hr>	
-	[% END %]	
-	
+		<hr>
+	[% END %]
+
 	[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_EQUALIZER" desc="" %]
 	[% END %]
-	
+
 	[% WRAPPER settingSection %]
 		[% WRAPPER settingGroup title='31Hz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.0" id="pref_eq.0" value="[% prefs.pref_eq.0 %]" size="2"">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.0" id="pref_equalizer.0" value="[% pref_equalizer.0 %]" size="2"">
 		[% END %]
 		[% WRAPPER settingGroup title='62Hz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.1" id="pref_eq.1" value="[% prefs.pref_eq.1 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.1" id="pref_equalizer.1" value="[% pref_equalizer.1 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='125Hz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.2" id="pref_eq.2" value="[% prefs.pref_eq.2 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.2" id="pref_equalizer.2" value="[% pref_equalizer.2 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='250Hz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.3" id="pref_eq.3" value="[% prefs.pref_eq.3 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.3" id="pref_equalizer.3" value="[% pref_equalizer.3 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='500Hz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.4" id="pref_eq.4" value="[% prefs.pref_eq.4 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.4" id="pref_equalizer.4" value="[% pref_equalizer.4 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='1kHz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.5" id="pref_eq.5" value="[% prefs.pref_eq.5 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.5" id="pref_equalizer.5" value="[% pref_equalizer.5 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='2kHz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.6" id="pref_eq.6" value="[% prefs.pref_eq.6 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.6" id="pref_equalizer.6" value="[% pref_equalizer.6 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='4kHz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.7" id="pref_eq.7" value="[% prefs.pref_eq.7 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.7" id="pref_equalizer.7" value="[% pref_equalizer.7 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='8kHz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.8" id="pref_eq.8" value="[% prefs.pref_eq.8 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.8" id="pref_equalizer.8" value="[% pref_equalizer.8 %]" size="2">
 		[% END %]
 		[% WRAPPER settingGroup title='16kHz' desc="" %]
-			<input type="text" class="stdedit sliderInput_-13_20" name="pref_eq.9" id="pref_eq.9" value="[% prefs.pref_eq.9 %]" size="2">
+			<input type="text" class="stdedit sliderInput_-13_20" name="pref_equalizer.9" id="pref_equalizer.9" value="[% pref_equalizer.9 %]" size="2">
 		[% END %]
 	[% END %]
-	
+
 [% PROCESS settings/footer.html %]

+ 80 - 10
plugin/SqueezeESP32/Player.pm

@@ -3,6 +3,9 @@ package Plugins::SqueezeESP32::Player;
 use strict;
 use base qw(Slim::Player::SqueezePlay);
 
+use Digest::MD5 qw(md5);
+use List::Util qw(min);
+
 use Slim::Utils::Log;
 use Slim::Utils::Prefs;
 
@@ -16,34 +19,34 @@ sub hasIR { 0 }
 sub init {
 	my $client = shift;
 	$client->SUPER::init(@_);
-	Plugins::SqueezeESP32::Plugin::config_artwork($client);
+	$client->config_artwork();
 }
 
 # Allow the player to define it's display width (and probably more)
 sub playerSettingsFrame {
 	my $client   = shift;
 	my $data_ref = shift;
-	
+
 	my $value;
 	my $id = unpack('C', $$data_ref);
-	
+
 	# New SETD command 0xfe for display width & height
-	if ($id == 0xfe) { 
+	if ($id == 0xfe) {
 		$value = (unpack('Cn', $$data_ref))[1];
 		if ($value > 100 && $value < 400) {
 			$prefs->client($client)->set('width', $value);
-			
+
 			my $height = (unpack('Cnn', $$data_ref))[2];
 			$prefs->client($client)->set('height', $height || 0);
 
 			$client->display->modes($client->display->build_modes);
 			$client->display->widthOverride(1, $value);
 			$client->update;
-			
-			$log->info("Setting player $value" . "x" . "$height for ", $client->name);
-		} 
+
+			main::INFOLOG && $log->is_info && $log->info("Setting player $value" . "x" . "$height for ", $client->name);
+		}
 	}
-	
+
 	$client->SUPER::playerSettingsFrame($data_ref);
 }
 
@@ -51,10 +54,77 @@ sub hasScrolling {
 	return 1;
 }
 
+sub update_artwork {
+	my $client = shift;
+	my $cprefs = $prefs->client($client);
+
+	my $artwork = $cprefs->get('artwork') || return;
+
+	return unless $artwork->{'enable'};
+
+	my $s = min($cprefs->get('height') - $artwork->{'y'}, $cprefs->get('width') - $artwork->{'x'});
+
+	my $params = { force => shift || 0 };
+	my $path = 'music/current/cover_' . $s . 'x' . $s . '_o.jpg';
+	my $body = Slim::Web::Graphics::artworkRequest($client, $path, $params, \&send_artwork, undef, HTTP::Response->new);
+
+	send_artwork($client, undef, \$body) if $body;
+}
+
+sub send_artwork {
+	my ($client, $params, $dataref) = @_;
+
+	# I'm not sure why we are called so often, so only send when needed
+	my $md5 = md5($$dataref);
+	return if $client->pluginData('artwork_md5') eq $md5 && !$params->{'force'};
+
+	$client->pluginData('artwork', $dataref);
+	$client->pluginData('artwork_md5', $md5);
+
+	my $artwork = $prefs->client($client)->get('artwork') || {};
+	my $length = length $$dataref;
+	my $offset = 0;
+
+	$log->info("got resized artwork (length: ", length $$dataref, ")");
+
+	my $header = pack('Nnn', $length, $artwork->{'x'}, $artwork->{'y'});
+
+	while ($length > 0) {
+		$length = 1280 if $length > 1280;
+		$log->info("sending grfa $length");
+
+		my $data = $header . pack('N', $offset) . substr( $$dataref, 0, $length, '' );
+
+		$client->sendFrame( grfa => \$data );
+		$offset += $length;
+		$length = length $$dataref;
+	}
+}
+
+sub clear_artwork {
+	my ($client, $request) = @_;
+
+	my $artwork = $prefs->client($client)->get('artwork');
+
+	if ($artwork && $artwork->{'enable'}) {
+		main::INFOLOG && $log->is_info && $log->info("artwork stop/clear " . $request->getRequestString());
+		$client->pluginData('artwork_md5', '');
+	}
+}
+
+sub config_artwork {
+	my ($client) = @_;
+
+	if ( my $artwork = $prefs->client($client)->get('artwork') ) {
+		my $header = pack('Nnn', $artwork->{'enable'}, $artwork->{'x'}, $artwork->{'y'});
+		$client->sendFrame( grfa => \$header );
+	}
+}
+
 sub reconnect {
 	my $client = shift;
 	$client->pluginData('artwork_md5', '');
 	$client->SUPER::reconnect(@_);
-}	
+}
 
 1;

+ 33 - 36
plugin/SqueezeESP32/PlayerSettings.pm

@@ -30,63 +30,60 @@ sub page {
 
 sub prefs {
 	my ($class, $client) = @_;
-	my @prefs = qw(width small_VU spectrum artwork eq);
+	my @prefs;
+	push @prefs, qw(width small_VU) if $client->displayWidth;
 	return ($prefs->client($client), @prefs);
 }
 
 sub handler {
 	my ($class, $client, $paramRef) = @_;
-	
+
 	my ($cprefs, @prefs) = $class->prefs($client);
-	
+
 	if ($paramRef->{'saveSettings'}) {
 		if ($client->displayWidth) {
 			$cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15);
-			my $spectrum =	{	scale => $paramRef->{'pref_spectrum_scale'} || 25,
-								small => { 	size => $paramRef->{'pref_spectrum_small_size'} || 25, 
-											band => $paramRef->{'pref_spectrum_small_band'} || 5.33 },
-								full  => { 	band => $paramRef->{'pref_spectrum_full_band'} } || 8,
-					};
+			my $spectrum = {
+				scale => $paramRef->{'pref_spectrum_scale'} || 25,
+				small => { 	size => $paramRef->{'pref_spectrum_small_size'} || 25,
+				band  => $paramRef->{'pref_spectrum_small_band'} || 5.33 },
+				full  => { 	band => $paramRef->{'pref_spectrum_full_band'} } || 8,
+			};
 			$cprefs->set('spectrum', $spectrum);
-			
-			my $artwork =	{	enable => $paramRef->{'pref_artwork_enable'},
-								x => $paramRef->{'pref_artwork_x'} || 0, 
-								y => $paramRef->{'pref_artwork_y'} || 0,
-					};
-			$cprefs->set('artwork', $artwork);				
+
+			my $artwork = {
+				enable => $paramRef->{'pref_artwork_enable'},
+				x => $paramRef->{'pref_artwork_x'} || 0,
+				y => $paramRef->{'pref_artwork_y'} || 0,
+			};
+			$cprefs->set('artwork', $artwork);
 			$client->display->modes($client->display->build_modes);
 			$client->display->update;
-		
+
 			# force update or disable artwork
 			if ($artwork->{'enable'}) {
-				Plugins::SqueezeESP32::Plugin::update_artwork($client, 1);
+				$client->update_artwork(1);
 			} else {
-				Plugins::SqueezeESP32::Plugin::config_artwork($client);
-			}	
-		}	
-		
-		my $eq = $cprefs->get('eq');
-		for my $i (0 .. $#{$eq}) {
-			$eq->[$i] = $paramRef->{"pref_eq.$i"};
+				$client->config_artwork();
+			}
 		}
-		$cprefs->set('eq', $eq);
-		Plugins::SqueezeESP32::Plugin::send_equalizer($client);		
+
+		my $equalizer = $cprefs->get('equalizer');
+		for my $i (0 .. $#{$equalizer}) {
+			$equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0;
+		}
+		$cprefs->set('equalizer', $equalizer);
 	}
-	
+
 	if ($client->displayWidth) {
-		# as there is nothing captured, we need to re-set these variables
-		$paramRef->{'pref_width'} = $cprefs->get('width'); 
-	
-		# here I don't know why you need to set again spectrum which is a reference
-		# to a hash. Using $paramRef->{prefs} does not work either. It seems that 
-		# some are copies of value, some are references, can't figure out. This whole
-		# logic of "Settings" is beyond me and I really hate it
+		# the Settings super class can't handle anything but scalar values
+		# we need to populate the $paramRef for the other prefs manually
 		$paramRef->{'pref_spectrum'} = $cprefs->get('spectrum');
 		$paramRef->{'pref_artwork'} = $cprefs->get('artwork');
 	}
-	
-	$paramRef->{'pref_eq'} = $cprefs->get('eq');
-	
+
+	$paramRef->{'pref_equalizer'} = $cprefs->get('equalizer');
+
 	return $class->SUPER::handler($client, $paramRef);
 }
 

+ 49 - 88
plugin/SqueezeESP32/Plugin.pm

@@ -4,8 +4,6 @@ use strict;
 
 use base qw(Slim::Plugin::Base);
 
-use Digest::MD5 qw(md5);
-use List::Util qw(min);
 use Slim::Utils::Prefs;
 use Slim::Utils::Log;
 use Slim::Web::ImageProxy;
@@ -16,121 +14,84 @@ my $log = Slim::Utils::Log->addLogCategory({
 	'category'     => 'plugin.squeezeesp32',
 	'defaultLevel' => 'INFO',
 	'description'  => Slim::Utils::Strings::string('SqueezeESP32'),
-}); 
+});
+
+# migrate 'eq' pref, as that's a reserved word and could cause problems in the future
+$prefs->migrateClient(1, sub {
+	my ($cprefs, $client) = @_;
+	$cprefs->set('equalizer', $cprefs->get('eq'));
+	$cprefs->remove('eq');
+	1;
+});
+
+$prefs->setChange(sub {
+	send_equalizer($_[2]);
+}, 'equalizer');
 
 sub initPlugin {
 	my $class = shift;
-	
+
 	if ( main::WEBUI ) {
 		require Plugins::SqueezeESP32::PlayerSettings;
 		Plugins::SqueezeESP32::PlayerSettings->new;
-		
+
 		# require Plugins::SqueezeESP32::Settings;
 		# Plugins::SqueezeESP32::Settings->new;
 	}
-	
+
 	$class->SUPER::initPlugin(@_);
 	Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
-	$log->info("Added class 100 for SqueezeESP32");
-	
-	Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['newmetadata'] ] );
-	Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['playlist'], ['open', 'newsong'] ]);
+	main::INFOLOG && $log->is_info && $log->info("Added class 100 for SqueezeESP32");
+
+	Slim::Control::Request::subscribe( \&onNotification, [ ['newmetadata'] ] );
+	Slim::Control::Request::subscribe( \&onNotification, [ ['playlist'], ['open', 'newsong'] ]);
 	Slim::Control::Request::subscribe( \&onStopClear, [ ['playlist'], ['stop', 'clear'] ]);
+
+	# the custom player class is only initialized if it has a display - thus we need to listen to connect events in order to initializes other player prefs
 	Slim::Control::Request::subscribe( \&onPlayer,[ ['client'], [ 'new', 'reconnect' ] ] );
 }
 
 sub onStopClear {
-    my $request = shift;
-    my $client  = $request->client;
-	my $artwork = $prefs->client($client)->get('artwork');
-	
-	if ($client->model eq 'squeezeesp32' && $artwork->{'enable'}) {
-		my $reqstr = $request->getRequestString();
-		$log->info("artwork stop/clear $reqstr");
-		$client->pluginData('artwork_md5', '')
-	}	
-}
+	my $request = shift;
+	my $client  = $request->client || return;
 
-sub onPlayer {
-    my $request = shift;
-    my $client  = $request->client;
-
-    if ($client->model eq 'squeezeesp32') {
-		$prefs->client($client)->init( { 
-					eq => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-				} );
-		Plugins::SqueezeESP32::Plugin::send_equalizer($client);
+	if ($client->isa('Plugins::SqueezeESP32::Player')) {
+		$client->clear_artwork($request);
 	}
 }
 
-sub onNotification {
-    my $request = shift;
-    my $client  = $request->client;
-	
-	my $reqstr     = $request->getRequestString();
+sub onPlayer {
+	my $request = shift;
+	my $client  = $request->client || return;
 
-	update_artwork($client);
-}
+	if ($client->model eq 'squeezeesp32') {
+		main::INFOLOG && $log->is_info && $log->info("SqueezeESP player connected: " . $client->id);
 
-sub update_artwork {
-    my $client  = shift;
-	my $params = { force => shift || 0 };
-	my $cprefs = $prefs->client($client);
-	my $artwork = $cprefs->get('artwork');
-		
-	return unless $client->model eq 'squeezeesp32' && $artwork->{'enable'};
-
-	my $s = min($cprefs->get('height') - $artwork->{'y'}, $cprefs->get('width') - $artwork->{'x'});
-	
-	my $path = 'music/current/cover_' . $s . 'x' . $s . '_o.jpg';
-	my $body = Slim::Web::Graphics::artworkRequest($client, $path, $params, \&send_artwork, undef, HTTP::Response->new);
-	
-	send_artwork($client, undef, \$body) if $body;
+		$prefs->client($client)->init( {
+			equalizer => [(0) x 10],
+		} );
+		send_equalizer($client);
+	}
 }
 
-sub send_artwork {
-	my ($client, $params, $dataref) = @_;
-	
-	# I'm not sure why we are called so often, so only send when needed
-	my $md5 = md5($$dataref);
-	return if $client->pluginData('artwork_md5') eq $md5 && !$params->{'force'};
-	
-	$client->pluginData('artwork', $dataref);
-	$client->pluginData('artwork_md5', $md5);
-	
-	my $artwork = $prefs->client($client)->get('artwork');
-	my $length = length $$dataref;
-	my $offset = 0;
-	
-	$log->info("got resized artwork (length: ", length $$dataref, ")");
-	
-	my $header = pack('Nnn', $length, $artwork->{'x'}, $artwork->{'y'});
-	
-	while ($length > 0) {
-		$length = 1280 if $length > 1280;
-		$log->info("sending grfa $length");
-			
-		my $data = $header . pack('N', $offset) . substr( $$dataref, 0, $length, '' );
-			
-		$client->sendFrame( grfa => \$data );
-		$offset += $length;			
-		$length = length $$dataref;
+sub onNotification {
+	my $request = shift;
+	my $client  = $request->client || return;
+
+	if ($client->isa('Plugins::SqueezeESP32::Player')) {
+		$client->update_artwork();
 	}
-}	
+}
 
 sub send_equalizer {
 	my ($client) = @_;
-	my $equalizer = $prefs->client($client)->get('eq');
-	my $size = @$equalizer;
-	my $data = pack("c[$size]", @{$equalizer});
-	$client->sendFrame( eqlz => \$data );
-}
 
-sub config_artwork {
-	my ($client) = @_;
-	my $artwork = $prefs->client($client)->get('artwork');
-	my $header = pack('Nnn', $artwork->{'enable'}, $artwork->{'x'}, $artwork->{'y'});
-	$client->sendFrame( grfa => \$header );
+	if ($client->model eq 'squeezeesp32') {
+		my $equalizer = $prefs->client($client)->get('equalizer') || [(0) x 10];
+		my $size = @$equalizer;
+		my $data = pack("c[$size]", @{$equalizer});
+		$client->sendFrame( eqlz => \$data );
+	}
 }
 
 1;