I am using just_audio
with audio_serivce
package. Everything else working fine, now I want to implement an Equalizer
. I saw the example in just_audio
regarding adding equalizer. But I'm not really sure how to implement it with audio_service
.
I have initialized Audio Player like this in the background service:
_player = AudioPlayer(
handleInterruptions: true,
androidApplyAudioAttributes: true,
handleAudioSessionActivation: true,
audioPipeline: AudioPipeline(
androidAudioEffects: [
_equalizer,
],
),
);
and using the code in example for flutter UI. But how to use _equalizer
of Background service in the UI part? I tried accessing it using customAction
but had no success.
Although controlling the equalizer is not one of the standard media controls understood by smart watches and cars, you can still add this as a custom action: one to set a band's gain, and another to read the the current bands and the min/max decibels supported by the equalizer. You can read about custom actions in the FAQ
For example, with a custom action, from the UI you might set the gain for a band like this:
// audio_service 0.17.x
AudioService.customAction('setBandGain', {'band': 0, 'gain': gain});
// audio_service 0.18.x
audioHandler.customAction('setBandGain', {'band': 0, 'gain': gain});
And in your background audio task (0.17.x) or audio handler (0.18.x) you can define the callback handler like this:
// 0.17.x
Future<dynamic> onCustomAction(String name, dynamic arguments) async {
if (name == 'setBandGain') {
final bandIdx = arguments['band'] as int;
final gain = arguments['gain'] as double;
await _eqParams.bands[bandIdx].setGain(gain);
}
}
// 0.18.x
Future<dynamic> customAction(String name, [Map<String, dynamic>? extras]) async {
if (name == 'setBandGain') {
final bandIdx = extras!['band'] as int;
final gain = extras!['gain'] as double;
await _eqParams.bands[bandIdx].setGain(gain);
}
}
Alternatively, if you want a quick and dirty approach, then the following is also possible in 0.18.0 since it runs everything in the same isolate and the whole equalizer parameters object can be passed by reference:
Future<dynamic> customAction(String name, [Map<String, dynamic>? extras]) async {
if (name == 'getEqParams') {
return await _equalizer.parameters;
}
}
Now from your UI you can just obtain the equalizer parameters directly, and then through that object reference you can access its full API (set gain values and also read min/max decibels):
// in UI
final eqParams = await audioHandler.customAction('getEqParams');
// Now use eqParams as desired.
Sure, this breaks encapsulation (but that's why I call this the quick and dirty approach.)