Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
maker-jr opened this issue Jul 17, 2020 · 8 comments
Assignees
Labels
1 backlog bug Something isn't working

Comments

@maker-jr
Copy link

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):

  • Device: [e.g. Samsung S8]
  • OS: [e.g. Android 9.0.0]

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

@maker-jr maker-jr added 1 backlog bug Something isn't working labels Jul 17, 2020
@ryanheise
Copy link
Owner

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
Copy link
Author

@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
Copy link

@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
Copy link

@maker-jr ?

@ryanheise
Copy link
Owner

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

@guptaShantanu
Copy link

@ryanheise I am using just_audio with audio_service but it is not getting interrupted by other music app and call, I tried audio_session 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
Copy link
Owner

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
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
1 backlog bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants