React Native Environment Info:
System:
OS: macOS 10.14.3
CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
Memory: 93.04 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 8.10.0 - ~/.nvm/versions/node/v8.10.0/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 5.6.0 - ~/.nvm/versions/node/v8.10.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
API Levels: 16, 17, 20, 21, 22, 23, 24, 25, 26, 27, 28
Build Tools: 21.1.2, 22.0.1, 23.0.1, 23.0.2, 23.0.3, 24.0.1, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.2, 28.0.3
System Images: android-16 | ARM EABI v7a, android-16 | MIPS, android-16 | Intel x86 Atom, android-16 | Google APIs ARM EABI v7a, android-16 | Google APIs Intel x86 Atom, android-22 | Google APIs Intel x86 Atom, android-24 | Android TV Intel x86 Atom, android-24 | Android Wear ARM EABI v7a, android-24 | Android Wear Intel x86 Atom, android-24 | ARM 64 v8a, android-24 | ARM EABI v7a, android-24 | Intel x86 Atom, android-24 | Intel x86 Atom_64, android-24 | Google Play Intel x86 Atom, android-25 | Android TV Intel x86 Atom, android-25 | Google APIs ARM EABI v7a, android-25 | Google APIs Intel x86 Atom, android-25 | Google APIs Intel x86 Atom_64, android-26 | Android TV Intel x86 Atom, android-26 | Android Wear Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.2 AI-181.5540.7.32.5056338
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: ^16.6.1 => 16.6.1
react-native: ^0.57.7 => 0.57.7
npmGlobalPackages:
create-react-native-app: 1.0.0
create-react-native-web-app: 0.1.6
What react-native-track-player version are you using?
1.1.4
Android 9.0 users are reporting that our app audio doesn't pause during interruptions such as GPS directions from Google Maps.
I have tested on other versions of Android and the remote-duck events are firing as expected, and the code I have to handle them works as well.
TrackPlayer.addEventListener("remote-duck", async data => {
let {
paused: shouldPause,
ducking: shouldDuck,
permanent: permanentLoss
} = data;
let playerState = await TrackPlayer.getState();
if (shouldPause || shouldDuck) {
TrackPlayer.pause();
if (playerState === TrackPlayer.STATE_PLAYING) {
didPauseTemporarily = !permanentLoss;
if (didPauseTemporarily) {
didPauseTemporarilyTime = Date.now();
}
} else {
didPauseTemporarily = false;
}
} else if (didPauseTemporarily) {
if (playerState === TrackPlayer.STATE_PAUSED) {
let secondsSincePause = (Date.now() - didPauseTemporarilyTime) / 1000;
if (secondsSincePause < 5) {
TrackPlayer.play();
}
}
didPauseTemporarily = false;
}
});
I have confirmed with a friend that this misbehavior is occurring, but I haven't had a chance to debug with a device yet.
We specifically got the google maps issue fixed by adding this.
https://github.com/zetlanddk/react-native-track-player/commit/2b94b036036e376a3ca3f761aaa8bb6b5de06ea8
I was unsure if it needed an interface, and how to make it, so I didn't make a pull request.
This solution from @antontanderup seems to make sense to me. I will try to test it out later this week on our app.
@Guichaguri, if this works, do you think it needs to be optional? Would this be something that you would want to be part of the options for either setupPlayer or updateOptions?
Yep, Android 9 auto-ducks now, so it never sends the event. The only way to control the ducking is through that option.
I think mixing the event with the option might be confusing. Is there any reason to not remove the duck event and automatically handle it in older devices based on the option?
I think removing the ducking parameter and automatically ducking on older versions is not enough. We should redesign the event.
So here's my idea:
remote-duck completelyalwaysPauseOnInterruption option to the updateOptionsremote-pause when there's an interruption, and then remote-play after the track is able to resume.remote-pause and remote-playI'd love to get an input from @anderslemke and @curiousdustin on this
This sounds like a good improvement to me.
The only question that comes to mind is, will react-native-track-player now handle the logic for whether or not to actually resume playback (fire the remote-play event)?
For instance you wouldn't want to actually play anything if the user had paused playback, and not the interruption.
We currently implement this within the handler for remote-duck, setting a flag when the interruption paused playback, so that we know to resume.
Yes, it would work pretty much the same way.
I have a feeling that remote-duck and remote-pause are semantically quite different.
One communicates an interruption and the other an actual user intent.
I think those differences should be visible to app developers, so I would be cautious about substituting a remote-duck with a remote-pause.
Basically, I think react-native-track-player should just forward whatever events the platforms generate, and let app developers handle them.
If react-native-track-player wanted to help app developers with the "ducking situation", however, it could be by making available some docs that describe the differences between the platforms for ducking.
That's a good point. I'll keep the remote-duck event, but I'll still be adding the alwaysPauseOnInterruption property, automate ducking to make older Android versions work like iOS and newer Android versions and remove the ducking property as it's not needed anymore.
@Guichaguri , I finally go around to updating my project to a version with this change in it.
It is still unclear to me if I need to implement the remote-duck event for Android at all if I want to use alwaysPauseOnInterruption: true.
Will the change you made do the following automatically without the app needing to handle remote-duck event?
Taking a quick look at your changes in the commit, there is no logic for number 2. I am assuming it is handled by the AudioFocusRequest?
Ah nvm, I think I understand now.
The pausing and resuming logic is not done automatically. The ducking is, optionally.
Defualt behavior using alwaysPauseOnInterruption: false (or left out):
When ducking is appropriate, audio volume is automatically reduced by RNTP.
remote-duck events are still fired, but only need to handle pause/permanent, no longer need to care about ducking.
New optional behavior using alwaysPauseOnInterruption: true:
Audio volume is never reduced.
When ducking would have occurred, pause events are triggered instead.
Still need to handle pause/permanent by using stop/pause/play as appropriate.
To sum it up:
