zmxv / react-native-sound

React Native module for playing sound clips
MIT License
2.78k stars 748 forks source link

Playback from other source is not resumed after playing is finished #762

Open andkom opened 2 years ago

andkom commented 2 years ago

:beetle: Description

If I disable mixWithOthers flag, playback from other source is paused, but not resumed after playing is finished.

:beetle: What is the observed behavior?

Playback from external source is not resumed after playing is finished. Audio focus is not abandoned?

:beetle: What is the expected behavior?

Playback from external source is resumed after playing is finished.

:beetle: Please post your code:

import Sound from 'react-native-sound';

Sound.setCategory('Playback', false);

const whoosh = new Sound('whoosh.mp3', Sound.MAIN_BUNDLE, (error) => {
  // pause playback from other source
  whoosh.play((success) => {
     // resume playback from other source
  });
});

:bulb: Does the problem have a test case?

:bulb: **Possible solution**

:bulb: Is there a workaround?

:bulb: If the bug is confirmed, would you be willing to create a pull request?

Is your issue with...

Are you using...

Which versions are you using?

Does the problem occur on...

If your problem is happening on a device, which device?

GaylordP commented 2 years ago

I have same problem, do you have a solution ? :)

Thanks you very much

andkom commented 2 years ago

@GaylordP i had to modify the package to fix the issue

diff --git a/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java b/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
index e6f51ec..af3c50b 100644
--- a/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
+++ b/node_modules/react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java
@@ -34,11 +34,13 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa
   Boolean mixWithOthers = true;
   Double focusedPlayerKey;
   Boolean wasPlayingBeforeFocusChange = false;
+  AudioManager audioManager;

   public RNSoundModule(ReactApplicationContext context) {
     super(context);
     this.context = context;
     this.category = null;
+    audioManager = (AudioManager) context.getApplicationContext().getSystemService(context.AUDIO_SERVICE);
   }

   private void setOnPlay(boolean isPlaying, final Double playerKey) {
@@ -237,13 +239,12 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa

     // Request audio focus in Android system
     if (!this.mixWithOthers) {
-      AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-
-      audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
-
+      audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
       this.focusedPlayerKey = key;
     }

+    RNSoundModule that = this;
+
     player.setOnCompletionListener(new OnCompletionListener() {
       boolean callbackWasCalled = false;

@@ -251,6 +252,12 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa
       public synchronized void onCompletion(MediaPlayer mp) {
         if (!mp.isLooping()) {
           setOnPlay(false, key);
+
+          // Release audio focus in Android system
+          if (!that.mixWithOthers && key == that.focusedPlayerKey) {
+            audioManager.abandonAudioFocus(that);
+          }
+
           if (callbackWasCalled) return;
           callbackWasCalled = true;
           try {
@@ -303,7 +310,6 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa

     // Release audio focus in Android system
     if (!this.mixWithOthers && key == this.focusedPlayerKey) {
-      AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
       audioManager.abandonAudioFocus(this);
     }

@@ -328,7 +334,6 @@ public class RNSoundModule extends ReactContextBaseJavaModule implements AudioMa

       // Release audio focus in Android system
       if (!this.mixWithOthers && key == this.focusedPlayerKey) {
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         audioManager.abandonAudioFocus(this);
       }
     }
ElChawich commented 2 years ago

i have same issue, and editing the node modules file is not valid.. are there any valid solutions for this?

yanush commented 2 years ago

I have the same issue on iOS. Will this solution fix it?

andkom commented 2 years ago

@yanush this is for android

Bort-777 commented 2 years ago

@andkom Hi, I solved this issue in another way, could you check this one:

https://github.com/zbranevichfinstek/react-native-sound/commit/00191c249fed9eb23d36b23f17eaa12863b3a218

  1. Changes option to AUDIOFOCUS_GAIN_TRANSIENT (is more preferable for my case)
  2. I realized that key == this.focusedPlayerKey doesn't return true when player during the research, so I changed compare method to key.equals(this.focusedPlayerKey). I think for double it's more correct.
Bort-777 commented 2 years ago

@yanush

I have the same issue on iOS. Will this solution fix it?

this one have to allow resume audio from other sources on ios https://github.com/zbranevichfinstek/react-native-sound/commit/9a0382cb5ad5f437d98e9541c67f64ee2f429531

keep in mind this setup Sound.setCategory("Playback", false) on finish call Sound.setActive(false); for resume

bvelasquez commented 2 years ago

@Bort-777 Is there a PR for this?

Bort-777 commented 2 years ago

@Bort-777 Is there a PR for this?

@bvelasquez it has to be more upgraded to a more flexible config before PR creating

taccarlo commented 2 years ago

@yanush

I have the same issue on iOS. Will this solution fix it?

this one have to allow resume audio from other sources on ios zbranevichfinstek@9a0382c

keep in mind this setup Sound.setCategory("Playback", false) on finish call Sound.setActive(false); for resume

I had the same problem in IOS, solved switching on Sound.setCategory("Alarm", false) instead of "Playback"

ucheNkadiCode commented 2 years ago

Check out the solution I posted on https://github.com/zmxv/react-native-sound/issues/788. That solution is for if you want your sound to play over other sounds seamlessly, but it might not suit your scenario