blackuy/react-native-twilio-video-webrtc

After enabling Screen Share in IOS, LocalPartipant view is replaced with Screen View tracks instead of Camera View.

Opened this issue · 9 comments

After enabling Screen Share in IOS, LocalPartipant view is replaced with Screen View tracks instead of Camera View.

After I turned off Screen Share, localparticipant view is blank and no View is present, If anyone has any idea about this it would be really helpful. Thank you

Thanks @dynamisch-manish I will check this

@dynamisch-manish In apps like Zoom when screen sharing is ON, the video view gets minimized (picture in picture) and then you can browse the rest of the app. How can we achieve the same with this package?

I don't know about the Pip mode for whole device, but if you want user can minimise & go another screens in your application you can achieve this by creating Higher order component.

Create Ref for Twilio on Root

import * as React from 'react';

export const videoCallRef = React.createRef();

Now use this ref to control Twilio function like toggle mic or video on/off, flip camera, etc.

Then create Higher order component.

import React, {memo, useCallback} from 'react';
import {TwilioVideo} from 'react-native-twilio-video-webrtc';
import {videoCallRef} from '../VideoCallRef';

const VideoCallProvider = memo(({children}) => {

  const _onRoomDidConnect = useCallback(
    payload => {
      console.log('#$@ - _onRoomDidConnect ==> ', payload);
    },
    [],
  );

  const _onRoomDidDisconnect = useCallback(
    payload => {
      console.log('#$@ - _onRoomDidDisconnect ==> ', payload);
    },
    [],
  );

  const _onRoomDidFailToConnect = useCallback(
    payload => {
      console.log('#$@ - _onRoomDidFailToConnect ==> ', payload);
    },
    [],
  );

  const _onRoomParticipantDidConnect = useCallback(
    payload => {
      console.log('#$@ - _onRoomParticipantDidConnect ==> ', payload);
    },
    [],
  );

  const _onRoomParticipantDidDisconnect = useCallback(
    payload => {
      console.log('#$@ - _onRoomParticipantDidDisconnect ==> ', payload);
    },
    [],
  );

  const _onParticipantAddedVideoTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantAddedVideoTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantRemovedVideoTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantRemovedVideoTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantEnabledVideoTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantEnabledVideoTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantDisabledVideoTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantDisabledVideoTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantAddedAudioTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantAddedAudioTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantRemovedAudioTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantRemovedAudioTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantEnabledAudioTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantEnabledAudioTrack ==> ', payload);
    },
    [],
  );

  const _onParticipantDisabledAudioTrack = useCallback(
    payload => {
      console.log('#$@ - _onParticipantDisabledAudioTrack ==> ', payload);
    },
    [],
  );

  const _onDominantSpeakerDidChange = useCallback(
    payload => {
      console.log('#$@ - _onDominantSpeakerDidChange ==> ', payload);
    },
    [],
  );

  const onParticipantAddedDataTrack = useCallback(
    payload => {
      console.log('#$@ - onParticipantAddedDataTrack ==> ', payload);
    },
    [],
  );

  const onParticipantRemovedDataTrack = useCallback(
    payload => {
      console.log('#$@ - onParticipantRemovedDataTrack ==> ', payload);
    },
    [],
  );

  const onDataTrackMessageReceived = useCallback(
    ({message, trackSid}) => {
      console.log('#$@ - onDataTrackMessageReceived ==> ', JSON.parse(message));
    },
    [],
  );

  const _onCameraWasInterrupted = useCallback(
    payload => {
      console.log('#$@ - _onCameraWasInterrupted ==> ', payload);
      videoCallRef.current
        .setLocalVideoEnabled(false)
        .then(isEnabled => dispatch(setCameraEnable(isEnabled)));
    },
    [dispatch],
  );

  const _onCameraInterruptionEnded = useCallback(
    payload => {
      console.log('#$@ - _onCameraInterruptionEnded ==> ', payload);
      videoCallRef.current
        .setLocalVideoEnabled(true)
        .then(isEnabled => dispatch(setCameraEnable(isEnabled)));
    },
    [dispatch],
  );

  const _onScreenShareChanged = useCallback(
    payload => {
      console.log('#$@ - _onScreenShareChanged ==> ', payload);
    },
    [],
  );

  const onCameraDidStart = useCallback(param => {
    console.log('#$@ - onCameraDidStart ==> ', param);
  }, []);

  const onCameraDidStopRunning = useCallback(param => {
    console.log('#$@ - onCameraDidStopRunning ==> ', param);
  }, []);

  const onNetworkQualityLevelsChanged = useCallback(param => {
    console.log('#$@ - onNetworkQualityLevelsChanged ==> ', param);
  }, []);

  const onStatsReceived = useCallback(param => {
    console.log('#$@ - onStatsReceived ==> ', param);
  }, []);

  return (
    <>
    <TwilioVideo
      ref={videoCallRef}
      onRoomDidConnect={_onRoomDidConnect}
      onRoomDidDisconnect={_onRoomDidDisconnect}
      onRoomDidFailToConnect={_onRoomDidFailToConnect}
      onRoomParticipantDidConnect={_onRoomParticipantDidConnect}
      onRoomParticipantDidDisconnect={_onRoomParticipantDidDisconnect}
      onParticipantAddedVideoTrack={_onParticipantAddedVideoTrack}
      onParticipantRemovedVideoTrack={_onParticipantRemovedVideoTrack}
      onParticipantEnabledVideoTrack={_onParticipantEnabledVideoTrack}
      onParticipantDisabledVideoTrack={_onParticipantDisabledVideoTrack}
      onParticipantAddedAudioTrack={_onParticipantAddedAudioTrack}
      onParticipantRemovedAudioTrack={_onParticipantRemovedAudioTrack}
      onParticipantEnabledAudioTrack={_onParticipantEnabledAudioTrack}
      onParticipantDisabledAudioTrack={_onParticipantDisabledAudioTrack}
      onDominantSpeakerDidChange={_onDominantSpeakerDidChange}
      onParticipantAddedDataTrack={onParticipantAddedDataTrack}
      onParticipantRemovedDataTrack={onParticipantRemovedDataTrack}
      onDataTrackMessageReceived={onDataTrackMessageReceived}
      onCameraWasInterrupted={_onCameraWasInterrupted}
      onCameraInterruptionEnded={_onCameraInterruptionEnded}
      onScreenShareChanged={_onScreenShareChanged}
      //
      onCameraDidStart={onCameraDidStart}
      onCameraDidStopRunning={onCameraDidStopRunning}
      onNetworkQualityLevelsChanged={onNetworkQualityLevelsChanged}
      onStatsReceived={onStatsReceived}
      // IOS Only
      autoInitializeCamera={true}
    />
    {children}
    </>
  );
});

export default VideoCallProvider;

And then warp your component tree in that in App.js

const App = () => (
  <Provider store={store}>
    <VideoCallProvider>
      <NavigationContainer>
         <Stack  ...... />
      </NavigationContainer>
    </VideoCallProvider >
  </Provider>

Now you can manage tracks using redux or context API & access them anywhere in the components.

@dynamisch-manish Hi manish, do you have any idea after sharing screen share why my localview which we are rendering using TwilioVideoLocalView is replaced by screen share tracks. Actually when I am publishing my screen tracks from my react native application to my react application I am filtering screen screen tracks at other side and showing screen share tracks seperatly in different component but I dont know how to filter screen share tracks in TwilioVideoLocalView. If you have any idea regarding this please let me know. It would be really helpful. Thank you

@vipulSoni458 Hi Vipul, actually there is only two stream one for video & second for audio. On video stream either we can put a camera view or screen view, that's why your TwilioVideoLocalView is replaced with ongoing view on video stream.

There is no way you can share both Screen View & Camera View. You can also verify with MS Teams app. On Teams whenever you share your screen your LocalView replaced with your profile picture or with your initials. I am also using this approach.

@dynamisch-manish Hi Manish thank for the response, actually its fine to publish one video at a time but what is happening is when I publish screen tracks my whole localView is replaced by multiple mirroring video of screen share. So my query is, is there any way I can stop this mirroring view of screen share and when I screen share I can replace my camera view with any static text or initials. Like its fine if I can not publish both camera and screen share in TwilioVideoLocalView at the same time but the problem is when I share screen share my whole TwilioVideoLocalView is replaced with multiple screen share mirroring view.

@dynamisch-manish Okay I got your point. When I am publishing my screen share I need to replace TwilioVideoLocalView with normal view with some text then it will not mirror. Thank you so much for helping and giving me the right direction. I really appreciate it. Thank you.