ryanheise / audio_service

Flutter plugin to play audio in the background while the screen is off.
803 stars 480 forks source link

Audio doesn't stop playing when another player starts or a call comes in on Android #403

Closed maker-jr closed 4 years ago

maker-jr commented 4 years ago

Which API doesn't behave as documented, and how does it misbehave? The Audio playback is supposed to pause when another audio player starts playing or when a call comes in. But in this case the audio just continue playing regardless of whether you're on a call or started another player. You have to pause it manually which is a bad user experience.

Minimal reproduction project Provide a link here using one of two options: "The example"

To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:

  1. Go to 'The list of songs'
  2. Click on 'any song'
  3. Minimize to home screen
  4. Start another audio player
  5. The audio played by this library will continue playing alongside the newly started audio

Error messages

If applicable, copy & paste error message here, within the triple quotes to preserve formatting.

Expected behavior The playback controlled by this library should pause or stop when another audio playback from another application starts or when another application needs to use the phone's speaker

Screenshots

Runtime Environment (please complete the following information if relevant):

Flutter SDK version

[✓] Flutter (Channel beta, 1.18.0-11.1.pre, on Mac OS X 10.15.4 19E287, locale en-AU)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.6)
[✓] VS Code (version 1.47.0)
[✓] Connected device (3 available)

• No issues found!

Additional context

ryanheise commented 4 years ago

Minimal reproduction project Provide a link here using one of two options: "The example"

The example works fine according to my own tests.

To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:

1. Go to 'The list of songs'

There is no list of songs in the example, and according to my testing, it doesn't exhibit the behaviour you describe...

The playback controlled by this library should pause or stop when another audio playback from another application starts or when another application needs to use the phone's speaker

If I can clarify, this plugin is not intended to control playback itself, it merely provides the callbacks that you can override in your own app to do that sort of thing if you want to. If your app is not doing that, it is because you have not implemented the callbacks to do that.

Incidentally, I have shown how to implement the callbacks in the example to do just that.

Which API doesn't behave as documented, and how does it misbehave? The Audio playback is supposed to pause when another audio player starts playing or when a call comes in. But in this case the audio just continue playing regardless of whether you're on a call or started another player. You have to pause it manually which is a bad user experience.

I am not clear on which API and which documentation you are referring to here.

maker-jr commented 4 years ago

@ryanheise Am sorry, my bad. I just came across the callbacks you implemented. I was able to achieve the desired behaviour by overriding onAudioFocusLost and onAudioFocusGained.

guptaShantanu commented 3 years ago

@ryanheise please tell me where can I find these callback? I am facing same issue on getting phone call or other music app playing.

guptaShantanu commented 3 years ago

@maker-jr ?

ryanheise commented 3 years ago

You can use audio_session to handle phone call and other interruptions. just_audio also handles this automatically by using audio_session internally.

guptaShantanu commented 3 years ago

@ryanheise I am using just_audio with audio_service but it is not getting interrupted by other music app and call, I tried audiosession in onStart() and configure it to music() and start listening stream but it is also not getting InterruptEvent. This is my onStart() method: @override Future onStart(Map<String, dynamic> params) async { final session = await AudioSession.instance; await session.configure(AudioSessionConfiguration.speech()); // Handle audio interruptions. session.interruptionEventStream.listen((event) { if (event.begin) { if (playing) { onPause(); interrupted = true; } } else { switch (event.type) { case AudioInterruptionType.pause: case AudioInterruptionType.duck: if (!playing && interrupted) { onPlay(); } break; case AudioInterruptionType.unknown: break; } interrupted = false; } }); // Handle unplugged headphones. session.becomingNoisyEventStream.listen(() { if (playing) onPause(); }); playing = true; queue.clear(); var mediaItems = params['data'] as List; for (int i = 0; i < mediaItems.length; i++) { MediaItem mediaItem = MediaItem.fromJson(mediaItems[i] as Map); queue.add(mediaItem); } print("Length ${queue.length}"); unawaited(AudioServiceBackground.setMediaItem(queue.first)); _playerStateSubscription = audioPlayer.playbackStateStream .where((state) => state == AudioPlaybackState.completed) .listen((state) { _handlePlaybackCompleted(); }); _eventSubscription = audioPlayer.playbackEventStream.listen((event) { final bufferingState = event.buffering ? AudioProcessingState.buffering : null; switch (event.state) { case AudioPlaybackState.paused: _setState( processingState: bufferingState ?? AudioProcessingState.ready, position: event.position); break; case AudioPlaybackState.playing: _setState( processingState: bufferingState ?? AudioProcessingState.ready, position: event.position); break; case AudioPlaybackState.connecting: _setState( processingState: _skipState ?? AudioProcessingState.connecting, position: event.position); break; default: print("Default case"); } });

unawaited(audioPlayer.play());
// Start loading something (will play when ready).
await audioPlayer.setUrl(queue.first.id);
// AudioServiceBackground.setQueue(queue);
//

}`

ryanheise commented 3 years ago

You need to call setActive on the audio session. But note this is not the place, you can either ask on StackOverflow or consult the source code to see how I have done it within just_audio, and also how I have done it within the TTS audio_service example.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.