Search code examples
flutteraudio-service

The playback of "audiolayers" and "audio_service" is interrupted by other media applications


I use audiolayers and audio_service plays audio. It works well. When I open other audio applications (such as Apple Music) to play music, my app will stop playing. This is OK. But when I return to my app to query the current playing status, it is still playing.

This is my code:

Container(
    height: 60.w,
    width: 60.w,
    decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(30.w),
        gradient: const LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: [Color(0xFFD54381), Color(0xFF7644AD)]),
        ),
        child: StreamBuilder<PlaybackState>(
           stream: customAudioHandler?.playbackState,
           builder: (context, snapshot) {
             final playing = snapshot.data?.playing ?? false;
             return GestureDetector(
                onTap: () => _playOrPause(context, playing),
                  child: Icon(
                    playing ? FontIcons.stop : FontIcons.play,
                    color: Colors.white,
                    size: 40.w,
                 ),
              );
           },
        ),
   ),

I try to use WidgetsBindingObserver

such:

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.inactive:
        break;
      case AppLifecycleState.paused:
        break;
      case AppLifecycleState.resumed:
        var audioHandlerState = customAudioHandler?.playbackState.value.playing;
        var audioPlayerState = audioPlayer.state;

        // print true
        debugPrint('didChangeAppLifecycleState-resumed: $audioHandlerState'); 

        // print PlayerState.playing
        debugPrint('didChangeAppLifecycleState-resumed: $audioPlayerState'); 

        break;
      case AppLifecycleState.detached:
        break;
    }
    super.didChangeAppLifecycleState(state);
  }

Their output status is playing

Any help would be appreciated.


Solution

  • When your app's audio session is interrupted by another app's audio session, you will want to be notified in some way so that you can update your app's state (in your case, broadcast a new playbackState with playing=false).

    You can access the audio session via the Flutter audio_session package. With your instance of the session, you can listen to when your session is interrupted by another app:

    session.interruptionEventStream.listen((event) {
      if (event.begin) {
        switch (event.type) {
          case AudioInterruptionType.duck:
            // Here you could lower the volume
            break;
          case AudioInterruptionType.pause:
          case AudioInterruptionType.unknown:
            // Here you should pause your audio
            player.pause();
            // AND ALSO broadcast the new state
            playbackState.add(playbackState.value.copyWith(playing: false));
            break;
        }
      }
    });
    

    The official audio_service example also demonstrates this use case, although with a different audio player plugin (just_audio) which uses audio_session under the hood to make this use case easier.