I am using just_audio
to play audio in my app, along with audio_session
. When my app plays audio, I want audio of other apps to stop or duck, and resume/unduck when my apps stops audio.
This is how I have currently figured audio_session:
final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration(
androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransientMayDuck,
androidWillPauseWhenDucked: false,
));
This is how I play audio:
AudioPlayer activePlayer = AudioPlayer(handleInterruptions: true);
await activePlayer.setAndroidAudioAttributes(AndroidAudioAttributes(
usage: AndroidAudioUsage.alarm,
contentType: AndroidAudioContentType.music,
));
await activePlayer.setLoopMode(loopMode);
await activePlayer.setAudioSource(AudioSource.uri(Uri.parse(ringtoneUri)));
await activePlayer.setVolume(volume);
// Other apps audio should stop/duck here
activePlayer?.play();
...
// Other apps audio should resume/unduck here
await activePlayer?.stop();
Other app's audio does get ducked (reduced in volume) on play()
but it doesn't get unducked (back to normal volume) on stop()
. Tried this with multiple other apps.
Edit: Seems like the other app gains focus when my app gets closed. So that means I need to call something other than stop()
to release focus from my app?
What am I doing wrong here?
I am currently testing on an Android 14 (Google APIs) emulator. But get same behavior on Android 13 devices. Haven't tested on older devices yet.
I don't know if its by design, a bug or due to something wrong I am doing, but just_audio
never abandons audio focus automatically. You have to call it yourself through audio_session
by calling session.setActive(false)
.
AudioPlayer activePlayer = AudioPlayer(handleInterruptions: true);
await activePlayer.setAndroidAudioAttributes(AndroidAudioAttributes(
usage: AndroidAudioUsage.alarm,
contentType: AndroidAudioContentType.music,
));
await activePlayer.setLoopMode(loopMode);
await activePlayer.setAudioSource(AudioSource.uri(Uri.parse(ringtoneUri)));
await activePlayer.setVolume(volume);
// Other apps audio should stop/duck here
await activePlayer?.play();
...
// Other apps audio should resume/unduck here
await activePlayer?.stop();
final session = await AudioSession.instance;
await session.setActive(false); // <-- Need to call this after audio stops