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

[Feature]: Video Player play/pause during incoming calling #3871

Open
Sumeeth-24 opened this issue Jun 2, 2024 · 7 comments
Open

[Feature]: Video Player play/pause during incoming calling #3871

Sumeeth-24 opened this issue Jun 2, 2024 · 7 comments
Labels

Comments

@Sumeeth-24
Copy link

Description

We need functionality where the video player pauses when a call is incoming and resumes when the call ends. This should not happen automatically but should be controlled via a prop value so that our custom functionality can handle the play/pause actions.

There is an old npm package named react-native-call-detection which is outdated (last updated 4 years ago) and incompatible with the newer Android/iOS versions. This package detects different call states like Incoming, Disconnected, Dialing, and Connected for iOS. For Android, it provides states like Offhook, Incoming, Disconnected, and Missed.

Our goal is to handle at least the Incoming and Disconnected events to implement custom controls for playing and pausing the video.

Why it is needed ?

Every ott platform like Amazon Prime, Netflix, Disney plus HotStar has this functionality where any video is playing and call is coming in between then automatically the player pause and when its disconnected then it automatically starts playing. Atleast need those two event listener (Incoming and Disconnected) and then video player would be completed. Its a much needed functionality for any video player. If possible please release it as early as possible as we have made an ott platform completed with this package and react-native and only this functionality and android pip support is missing.

Possible implementation

Refer this package for idea " react-native-call-detection".

Code sample

Code sample

@MdAbubakar
Copy link

MdAbubakar commented Jun 3, 2024

@Sumeeth-24 Bro I have tried this approach after lots of tries using the library you provided and finally this approach works for me,

Add this line in the video component

onAudioFocusChanged={event => {
if (!event.hasAudioFocus) {
setPaused(true);
setActiveCall(true);
} else {
setPaused(false);
setActiveCall(false);
}
}}

And disable your play pause button

<Pressable
style={{
marginHorizontal: moderateScale(50),
padding: scale(10),
borderRadius: 100,
justifyContent: "center",
alignItems: "center",
// backgroundColor: "rgba(0,0,0, 0.3)",
display: isLoading ? "none" : "flex",
}}
disabled={activeCall}
onPress={() => {
setPaused(!paused);
handleControlInteraction(true);
}}>
{paused ? (
<Icon
name="play"
type="ionicon"
size={showFullscreen ? moderateScale(30) : moderateScale(35)}
color={"#FFFFFF"}
/>
) : (
<Icon
name="pause"
type="ionicon"
size={showFullscreen ? moderateScale(30) : moderateScale(35)}
color={"#FFFFFF"}
/>
)}

@paulrinaldi
Copy link
Contributor

paulrinaldi commented Jun 4, 2024

The player works already as you describe in Android @Sumeeth-24 . See the example/basic. Run it by:
yarn install
cd examples/basic
yarn install
yarn run android
yarn run start a

However, I'm on 6.1.2 and my video player in my pure RN app I'm developing keeps playing on Android when it receives a call in simulator which is different from what the basic app does.

It looks like they handle it with this.onAudioFocusChanged in examples/basic...

@paulrinaldi
Copy link
Contributor

For iOS, there is started work on refactoring so that iOS audio category can be set more easily so that interruptions are handled well. #3850 For now, see #3652 for a patch I made.

@paul-rinaldi
Copy link
Contributor

@Sumeeth-24
On Android, you can simply follow their examples/basic's implementation:

  onAudioBecomingNoisy = () => {
    this.setState({paused: true});
  };

  onAudioFocusChanged = (event: OnAudioFocusChangedData) => {
    this.setState({paused: !event.hasAudioFocus});
  };
  ...
  <Video
    onAudioBecomingNoisy={this.onAudioBecomingNoisy}
    onAudioFocusChanged={this.onAudioFocusChanged}
    .../>

https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/basic/src/VideoPlayer.tsx#L387

@paulrinaldi
Copy link
Contributor

This would be a great addition.

@seyedmostafahasani
Copy link
Collaborator

I will work on it this weekend.

@paulrinaldi
Copy link
Contributor

paulrinaldi commented Oct 14, 2024

One way that this can be implemented partially is by breaking other functionality fyi @Sumeeth-24. You can let exoplayer manage its own audioFocus. If you don't need to know when audio focus is lost/gained, this is an easy solution.

Edit node_modules/react-native-video/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java

@@ -1256,10 +1273,10 @@ public class ReactExoplayerView extends FrameLayout implements
         }
 
         if (playWhenReady) {
-            this.hasAudioFocus = requestAudioFocus();
-            if (this.hasAudioFocus) {
-                player.setPlayWhenReady(true);
-            }
+            // this.hasAudioFocus = requestAudioFocus();
+            // if (this.hasAudioFocus) {
+            player.setPlayWhenReady(true);
+            // }
         } else {
             // ensure playback is not ENDED, else it will trigger another ended event
             if (player.getPlaybackState() != Player.STATE_ENDED) {
@@ -2134,7 +2151,7 @@ public class ReactExoplayerView extends FrameLayout implements
             AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(usage)
                     .setContentType(contentType)
                     .build();
-            player.setAudioAttributes(audioAttributes, false);
+            player.setAudioAttributes(audioAttributes, true);
             AudioManager audioManager = (AudioManager) themedReactContext.getSystemService(Context.AUDIO_SERVICE);
             boolean isSpeakerOutput = output == AudioOutput.SPEAKER;
             audioManager.setMode(

Then onPlaybackStateChange, set your pause state (which you can pass as a prop to the RNV Video component) as !data.isPlaying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants