nstudio / nativescript-audio

:microphone: NativeScript plugin to record and play audio :musical_note:
Other
150 stars 104 forks source link

Paused audio resumes if app is suspended and then mic/speaker is released #148

Open yringler opened 5 years ago

yringler commented 5 years ago

Problem

If user pauses audio opens up other app uses speaker or recorder from other app when that app releases the speaker/recorder, audio in my app resumes.

Desired Behaviour Release of speaker by another app should only resume playback if playback was paused by that app taking the speaker.

Possible work around I'm going to try calling release resources when app is suspended. Update: Haven't gotten this to work.

masayoshiadachi commented 5 years ago

I have the same issue and I found out a workaround. This issue is caused by regaining the audio focus after other app release the audio focus. When the audio player regain the audio focus, the "resume" method of player instance will be called. So suddenly paused audio start to play. You can see the issue with debug=true option.

My workaround is override the "resume" function.

    this.player = new TNSPlayer();
    // disable resume from getting focus
    this.player.resume = () => {
      console.log("do nothing");
    };

I use "play" and "pause" function from my app, so I don't need "resume" function.

yringler commented 5 years ago

Brilliant! Thank you so much. Tried your work around, it worked great.

7ammer commented 4 years ago

The resume function exists for a reason! :(

I think this issue has something to do with _mOnAudioFocusChangeListener method in the src/android/player.ts file.

I can see that after phoning someone and ending a call that case android.media.AudioManager.AUDIOFOCUS_GAIN: is switched which results in this.resume() getting triggered. What I think maybe going wrong is the user can pause the audio but AUDIOFOCUS_GAIN can still be triggered so it will start playing from a paused state!

code below...

  private _mOnAudioFocusChangeListener = new android.media.AudioManager.OnAudioFocusChangeListener({
    onAudioFocusChange: (focusChange: number) => {
      switch (focusChange) {
        case android.media.AudioManager.AUDIOFOCUS_GAIN:
          TNS_Player_Log('AUDIOFOCUS_GAIN');
.......
          this.resume();
          break;
.....

Perhaps the player state could be saved at AUDIOFOCUS_LOSS_TRANSIENT and then an IF statement could be used in AUDIOFOCUS_GAIN to decided if the player can resume() the audio or not.

7ammer commented 4 years ago

Or... remove the listener when the player is paused and add the listener again when it is playing. I think this may fix some similar issue with iOS as well.