Lakshya Jain
Lakshya Jain

Reputation: 115

Why is video.srcObject not working with WebRTC?

Here's my simple code

import React, { useState, useEffect, useRef } from "react";
import io from "socket.io-client";

import Navbar from "../../components/Navbar";

export default function ViewerRoom() {
  const [socket, setSocket] = useState(null);
  const localVid = useRef();
  const remoteVid = useRef();

  useEffect(() => {
    const init = async () => {
      //Get URL Params
      const searchParams = new URL(window.location).searchParams;
      const proxy = searchParams.get("v");

      //Define Streams
      const localStream = await navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true,
      });
      let remoteStream = new MediaStream();

      //Create RTCPeerConnection
      const servers = {
        iceServers: [
          {
            urls: [
              "stun:stun1.l.google.com:19302",
              "stun:stun1.2.google.com:19302",
            ],
          },
        ],
        iceCandidatePoolSize: 10,
      };
      let pc = new RTCPeerConnection(servers);

      //Add the tracks
      localStream.getTracks().forEach((track) => {
        pc.addTrack(track, localStream);
      });

      //Pull the tracks from the remote stream
      pc.ontrack = (event) => {
        event.streams[0].getTracks().forEach((track) => {
          remoteStream.addTrack(track);
        });
      };

      //Initialize Socket
      const newSocket = io("http://localhost:1829");
      setSocket(newSocket);

      //Create Data object
      const data = {
        id: proxy,
      };

      //Join Call
      newSocket.emit("join", JSON.stringify(data));

      //Joined Call Auth Callback
      newSocket.on("join-call", (buffer) => {
        //Deserialize
        const data = JSON.parse(buffer);

        //Get that SDP
        const answer = data.offer;
        const remoteDescription = new RTCSessionDescription(answer);
        pc.setRemoteDescription(remoteDescription);

        //Get the Ice Candidates and loop over and add them
        data.iceCandidates.map((ice) => {
          const candidate = new RTCIceCandidate(ice);
          pc.addIceCandidate(candidate);
        });
      });

      localVid.current.srcObject = localStream;
      remoteVid.current.srcObject = remoteStream;
    };
    init();
  }, []);
  return (
    <>
      <Navbar />
      <div>
        <>
          <video
            ref={localVid}
            muted
            id="local"
            autoPlay
            width={600}
            height={480}
          />
          <video
            ref={remoteVid}
            id="remote"
            autoPlay
            width={600}
            height={480}
            style={{ marginLeft: "150px" }}
          />
        </>
      </div>
    </>
  );
}

Everything works. The socket connects, peer.ontrack gets fired, the stream gets updated, everything. But the video doesn't display in the UI. The local video gets displayed, but not the remote one. What's wrong? Is it a bug in the browser API? Is it something in my code? I've been scratching my head for hours but I can't get a solution for this problem
If it helps, I'm using React and Es6. Please give a solution

Upvotes: 1

Views: 1549

Answers (1)

chrisguttandin
chrisguttandin

Reputation: 9116

I think the remote video element doesn't play because autoplay doesn't work unless the element is also muted. But calling play() programmatically should work.

// ...
localVid.current.srcObject = localStream;
remoteVid.current.srcObject = remoteStream;
remoteVid.current.play();

Upvotes: 1

Related Questions