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
This commit is contained in:
Michael Herger
2020-05-05 22:45:54 +02:00
parent 4f324b90d7
commit 9f23b79818
4 changed files with 183 additions and 154 deletions

View File

@@ -3,6 +3,7 @@
[% 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 %]
@@ -27,7 +28,7 @@
[% 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
@@ -42,34 +43,34 @@
[% 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 %]

View File

@@ -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,7 +19,7 @@ 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)
@@ -40,7 +43,7 @@ sub playerSettingsFrame {
$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);
}
}
@@ -51,6 +54,73 @@ 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', '');

View File

@@ -30,7 +30,8 @@ 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);
}
@@ -42,14 +43,16 @@ sub handler {
if ($paramRef->{'saveSettings'}) {
if ($client->displayWidth) {
$cprefs->set('small_VU', $paramRef->{'pref_small_VU'} || 15);
my $spectrum = { scale => $paramRef->{'pref_spectrum_scale'} || 25,
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'},
my $artwork = {
enable => $paramRef->{'pref_artwork_enable'},
x => $paramRef->{'pref_artwork_x'} || 0,
y => $paramRef->{'pref_artwork_y'} || 0,
};
@@ -59,33 +62,27 @@ sub handler {
# 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);
$client->config_artwork();
}
}
my $eq = $cprefs->get('eq');
for my $i (0 .. $#{$eq}) {
$eq->[$i] = $paramRef->{"pref_eq.$i"};
my $equalizer = $cprefs->get('equalizer');
for my $i (0 .. $#{$equalizer}) {
$equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0;
}
$cprefs->set('eq', $eq);
Plugins::SqueezeESP32::Plugin::send_equalizer($client);
$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);
}

View File

@@ -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;
@@ -18,6 +16,18 @@ my $log = Slim::Utils::Log->addLogCategory({
'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;
@@ -31,106 +41,57 @@ sub initPlugin {
$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");
main::INFOLOG && $log->is_info && $log->info("Added class 100 for SqueezeESP32");
Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['newmetadata'] ] );
Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['playlist'], ['open', 'newsong'] ]);
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');
my $client = $request->client || return;
if ($client->model eq 'squeezeesp32' && $artwork->{'enable'}) {
my $reqstr = $request->getRequestString();
$log->info("artwork stop/clear $reqstr");
$client->pluginData('artwork_md5', '')
if ($client->isa('Plugins::SqueezeESP32::Player')) {
$client->clear_artwork($request);
}
}
sub onPlayer {
my $request = shift;
my $client = $request->client;
my $client = $request->client || return;
if ($client->model eq 'squeezeesp32') {
main::INFOLOG && $log->is_info && $log->info("SqueezeESP player connected: " . $client->id);
$prefs->client($client)->init( {
eq => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
equalizer => [(0) x 10],
} );
Plugins::SqueezeESP32::Plugin::send_equalizer($client);
send_equalizer($client);
}
}
sub onNotification {
my $request = shift;
my $client = $request->client;
my $client = $request->client || return;
my $reqstr = $request->getRequestString();
update_artwork($client);
}
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;
}
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;
if ($client->isa('Plugins::SqueezeESP32::Player')) {
$client->update_artwork();
}
}
sub send_equalizer {
my ($client) = @_;
my $equalizer = $prefs->client($client)->get('eq');
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 );
}
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 );
}
}
1;