Audio Context
How to manage audio context and interruptions
flutter_soloud handles the playing of audio, but does not handle configuration of the OS level audio sessions and their contexts. If you wish to change the audio session away from OS defaults (for example, to always play over other apps or ignore silent mode), we recommend audio_session.
This page provides a guide on how to use audio_session to manage the audio context.
Basic Usage
Initialize and configure audio_session in your app. A good place to do this is in the initState of your widget and should be done before any audio is played.
import 'package:audio_session/audio_session.dart';
// ...
late final AudioSession session;
@override
void initState() {
super.initState();
AudioSession.instance.then((audioSession) async {
session = audioSession;
await session.configure(
const AudioSessionConfiguration(
androidWillPauseWhenDucked: true,
androidAudioAttributes: AndroidAudioAttributes(
usage: AndroidAudioUsage.media,
contentType: AndroidAudioContentType.music,
),
androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransientMayDuck,
avAudioSessionCategory: AVAudioSessionCategory.playback,
avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.none,
),
);
_handleInterruptions(session);
});
}
When you want to start to play audio, you need to activate the audio session:
await session.setActive(true);
final handle = await SoLoud.instance.play(sound);
Handling Interruptions
You need to listen to interruption events to pause, resume, or duck your audio.
void _handleInterruptions(AudioSession audioSession) {
audioSession.becomingNoisyEventStream.listen((_) {
// The user unplugged headphones, so we should pause.
SoLoud.instance.setPause(soundHandle, true);
});
audioSession.interruptionEventStream.listen((event) {
if (event.begin) {
switch (event.type) {
case AudioInterruptionType.duck:
// Another app started playing audio and we should duck.
SoLoud.instance.fadeGlobalVolume(0.1, const Duration(milliseconds: 300));
break;
case AudioInterruptionType.pause:
case AudioInterruptionType.unknown:
// Another app started playing audio and we should pause.
SoLoud.instance.setPause(soundHandle, true);
break;
}
} else {
switch (event.type) {
case AudioInterruptionType.duck:
// The interruption ended and we should unduck.
SoLoud.instance.fadeGlobalVolume(1, const Duration(milliseconds: 300));
break;
case AudioInterruptionType.pause:
// The interruption ended and we should resume.
SoLoud.instance.setPause(soundHandle, false);
break;
case AudioInterruptionType.unknown:
// The interruption ended but we should not resume.
break;
}
}
});
}
Please, look at the lib/audio_context/audio_context.dart example for a simple implementation to handle audio interruptions.
iOS and Google Ads
If you are using the google_mobile_ads plugin on iOS, you might encounter issues with audio playback. To solve this, you can configure the audio_session adding this line in AppDelegate.swift:
import GoogleMobileAds
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Add this
MobileAds.shared.audioVideoManager.isAudioSessionApplicationManaged = true
...
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}