Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
877 stars 572 forks source link

[BUG]:Audio can't mix with another app on Ios #1111

Open WNizard opened 2 days ago

WNizard commented 2 days ago

Flutter Sound Version : 9.16.3

├── flutter_sound 9.16.3 │ ├── flutter_sound_platform_interface... │ ├── flutter_sound_web 9.16.3 │ │ ├── flutter_sound_platform_interface... ├── flutter_sound_platform_interface 9.16.3

Severity


Platforms you faced the error


Describe the bug IOS: When I play my audio everything works as expected, but then, when I go on background and that I start for example a youtube video, my audio is not mixing with youtube and will never start again even if I turn it off and on again. The problem with this issue is that I don't have any exception nor error, my stream is just stopping and not starting ever again. Android: it's mixing, but when I turn it off I can't turn it on again because I think that the audioPlayer doesn't want to be closed cause it's in an unfinished state

To Reproduce Steps to reproduce the behavior: -Start a flutterSoundplayer: await soundPlayer.openPlayer(); await soundPlayer.startPlayerFromStream( codec: Codec.pcm16, numChannels: BabyMonitorCallService.channels, sampleRate: BabyMonitorCallService.sampleRate, ); -go on youtube -play a video -try to hear your stream

However, because there is no error, I don't have any interesting logs. I still can receive my audio packets from my audio socket during this bug, but these buffers are never played.

I can show you my AudioSession configuration thought:

`Future configureAudioSession() async {

  final session = await AudioSession.instance;
  await session.configure(AudioSessionConfiguration(
    avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
    avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.defaultToSpeaker | 
                                   AVAudioSessionCategoryOptions.mixWithOthers | 
                                   AVAudioSessionCategoryOptions.allowBluetooth | 
                                   AVAudioSessionCategoryOptions.interruptSpokenAudioAndMixWithOthers,
    avAudioSessionMode: AVAudioSessionMode.voiceChat,
    avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy,
    avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.notifyOthersOnDeactivation,
    androidAudioAttributes: const AndroidAudioAttributes(
      contentType: AndroidAudioContentType.speech,
      flags: AndroidAudioFlags.none,
      usage: AndroidAudioUsage.voiceCommunication,
    ),
    androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
    androidWillPauseWhenDucked: false, // Change this to false to allow mixing
  ));
  await session.setActive(true);

} `


WNizard commented 2 days ago

For the logs, as I said, I don't have anything interesting: the moment where they disappear is at the exact second where I click play on the youtube video Screenshot 2024-10-25 at 12 44 28

WNizard commented 2 days ago

Also, when I try this:

Future<void> _listenForAudioInterruptions() async {
    final session = await AudioSession.instance;
    session.interruptionEventStream.listen((event) {
      if (event.begin) {
        switch (event.type) {
          case AudioInterruptionType.duck:
            _handleDuckInterruption();
            break;
          case AudioInterruptionType.pause:
          case AudioInterruptionType.unknown:
            _handlePauseInterruption();
            break;
        }
      } else {
        switch (event.type) {
          case AudioInterruptionType.duck:
            _handleUnduckInterruption();
            break;
          case AudioInterruptionType.pause:
          case AudioInterruptionType.unknown:
            _handleResumeInterruption();
            break;
        }
      }
    });

    session.becomingNoisyEventStream.listen((_) {
      _handleBecomingNoisy();
    });
  }

  void _handleDuckInterruption() {
    DebugService.printDebug("Audio ducked");
  }

  void _handlePauseInterruption() {
    soundPlayer.pausePlayer();
  }

  void _handleUnduckInterruption() {
    DebugService.printDebug("Audio unducked");
  }

  void _handleResumeInterruption() {
    DebugService.printDebug("Audio resumed after interruption");
    if (_isSoundPlayerAcquired) {
      soundPlayer.resumePlayer();
    }
  }
  }

this is what happens instantly when the interruption stops Screenshot 2024-10-25 at 14 42 39