aws / amazon-chime-sdk-component-library-react

Amazon Chime React Component Library with integrations with the Amazon Chime SDK.
Apache License 2.0
268 stars 160 forks source link

Screenshare overrides video stream from user on RemoteVideo component #840

Closed kirill-dev-pro closed 1 year ago

kirill-dev-pro commented 2 years ago

What happened and what did you expect to happen?

When user enables screenshare it overrides video from users camera on every RemoteVideo even though it has correct tileId for users camera and screenshare has another tileId.

Have you reviewed our existing documentation?

Reproduction steps

Create <RemoteVideo /> and <ContentShareComponent />, turn on

const { toggleContentShare } = useContentShareControls()

now remote video and content share both show screenshare stream

Amazon Chime SDK React Components Library version

3.3.0

What browsers are you seeing the problem on?

firefox and chrome

Browser version

latest

Device Information

macOS, desctop

Meeting and Attendee ID Information.

No response

Browser console logs

-

Add any other context about the problem here.

No response

michhyun1 commented 1 year ago

Is there a reason you don't prefer to use the VideoTileGrid component?

If you are having issues with the Content share hook and the Remote Video component, I still imagine the issue might be related to tile Ids.

Can you please post what your code looks like?

And is it possible for you to try to turn on the remoteVideo first before you toggleContentShare. And then see what happens.

devalevenkatesh commented 1 year ago

@kirill-dev-pro thanks for reporting the issue. I tried to test and I could not come across the same issue. Here is my code to test this:

import { 
  ChangeEvent,
  useEffect,
  useState
} from 'react';

import {LogLevel} from 'amazon-chime-sdk-js';

import {
  LocalVideo,
  useMeetingManager,
  useLocalVideo,
  useMeetingStatus,
  MeetingStatus,
  useRemoteVideoTileState,
  RemoteVideo,
  ContentShare,
  useContentShareControls
} from 'amazon-chime-sdk-component-library-react';

function Home() {
  const [meetingName, setMeetingName] = useState('');
  const [attendeeName, setAttendeeName] = useState('');
  const meetingManager = useMeetingManager();
  const meetingStatus = useMeetingStatus();
  const { toggleVideo } = useLocalVideo();
  const { toggleContentShare } = useContentShareControls();
  // Get remote video tiles if available and enabled by remote attendees.
  // You can use `RemoteVideos` component if you do not want to manage remote tiles and handle the remote tileId.
  // Simply, remove these two lines and the second useEffect which sets the remote tileId.
  // Change the {remoteTileId && <RemoteVideo tileId={remoteTileId} />} in return method to just <RemoteVideos />
  // `RemoteVideos` internally will handle the same for you but wont be limited to just one tileId.
  const { tiles } = useRemoteVideoTileState();
  const [remoteTileId, setRemoteTileId] = useState<number>();

  useEffect(() => {
    async function tog() {
      if (meetingStatus === MeetingStatus.Succeeded) {
        await toggleVideo();
      }
    }
    tog();
  }, [meetingStatus]);

  // UseEffect to set the remote video tile once remote attendee join with video already started.
  useEffect(() => {
    if (tiles && tiles.length) {
      setRemoteTileId(tiles[0]);
    } else {
      setRemoteTileId(undefined);
    }
  }, [tiles]);

  const joinMeeting = async () => {
    // Fetch the meeting and attendee data from your server application
    const joinInfo = await fetch(`http://127.0.0.1:8080/join?meetingName=${meetingName}&attendeeName=${attendeeName}`, {method: 'POST'});
    const data = await joinInfo.json();
    const joinData = {
      meetingInfo: data.meeting.Meeting,
      attendeeInfo: data.attendee.Attendee,
      meetingManagerConfig: {
        logLevel: LogLevel.INFO
      }
    };
    await meetingManager.join(joinData);
    await meetingManager.start();
  };

  const leaveMeeting = async () => {
    await meetingManager.leave();
  }

  const startContentShare = async () => {
    await toggleContentShare();
  }

  const handleMeetingNameChange = (e: ChangeEvent<HTMLInputElement>) => {
    setMeetingName(e.target.value);
  }

  const handleAttendeeNameChange = (e: ChangeEvent<HTMLInputElement>) => {
    setAttendeeName(e.target.value);
  }

  return (
    <div className="Home">
      <div>
        Meeting name:
        <input type='text' value={meetingName} onChange={handleMeetingNameChange}></input>
      </div>
      <div>
        Attendee name:
        <input type='text' value={attendeeName} onChange={handleAttendeeNameChange}></input>
      </div>
      <button onClick={joinMeeting}>Join</button>
      <button onClick={leaveMeeting}>leave</button>
      <button onClick={startContentShare}>start content share</button>
      <h3>Content Video</h3>
      <div style={{height:'300px', width: '400px'}}>
        <ContentShare />
      </div>
      <h3>Local Video</h3>
      <div style={{height:'300px', width: '400px'}}>
        <LocalVideo />
      </div>
      <h3>Remote Video</h3>
      <div style={{height:'300px', width: '400px'}}>
        {remoteTileId && <RemoteVideo tileId={remoteTileId} />}
      </div>
    </div>
  );
}

export default Home;

Here is the basic screenshot:

Screen Shot 2022-11-02 at 5 07 46 PM

I could see that the LocalVideo, RemoteVideo and the ContentShare components showed each of their respective videos. Please let me know if you are still facing the issue.

The above code is based of below testing demo: https://github.com/devalevenkatesh/test-amazon-chime-sdk-react-components/tree/main/meeting-videos-on-join

kirill-dev-pro commented 1 year ago

Hey @devalevenkatesh! It appears to be issue in my code, I used videoTileDidUpdate observer to rebind video elements to solve another issue with having multiple videogrid that being mounted and unmounted by their own. I was ocasioanlly rebinding new video frames with tileState.isContent property in videoTileDidUpdate observer to the same video elements same attendees were using. So there is no issue with library itslef