iceConnectionState as completed but camera is blank

30 Views Asked by At

Im a new react native learner trying to implement video call with web rtc. I am now facing an issue which i have a blank remote video call. I checked my logging and i can see that my web rtc has logged onIceGatheringChangeCOMPLETE but for some reason the frames received on my remote stream is always this EglRenderer: Duration: 4007 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.

Attached is my code


function ConnectScreen2({ route }) {
  const ctx = useContext(AuthContext)
  const MyRandomId = "554433";
  const [localStream, setLocalStream] = useState();
  const [remoteStream, setRemoteStream] = useState();
  // for ending call
  const [CachedLocalPC, setCachedLocalPC] = useState();
  const ref = collection(firebase, "Room");
  const targetCollectionRef = collection(firebase, "expenses");
  let timer = null;

  function SnapShotAndSetICE(Collection, MyPC) {
    console.log("SnapShotAndSetICE cached local " + MyPC);
    onSnapshot(Collection, (snapshot) => {
      snapshot.docChanges().forEach((change) => {
        if (change.type === "added") {
          let data = change.doc.data();
          console.log("Addcaller " + data.candidate);
          MyPC.addIceCandidate(new RTCIceCandidate(data));
        }
      });
    });
  }


  async function StartCall2() {
    const localPC = new RTCPeerConnection(peerConstraints);
    console.log("StartCall2");

    const UserRef = doc(ref, MyRandomId);


    localStream.getTracks().forEach((track) => {
      localPC.addTrack(track, localStream);
    });

    const roomRef = doc(ref, MyRandomId);
    const callerCandidatesCollection = collection(roomRef, "callerCandidates");
    const calleeCandidatesCollection = collection(roomRef, "calleeCandidates");
    //setup when ice candidate is added add to doc
    localPC.addEventListener("icecandidate", (e) => {

      if (!e.candidate) {
        return;
      }
      try { addDoc(callerCandidatesCollection, e.candidate.toJSON()) }
      catch (error) {
        console.log("OnAdd ice candidate error");
      }

    });
    // setup to listen for when remote stream is added
    localPC.ontrack = (e) => {
      console.log("on track " + e.streams.length);
      const newStream = new MediaStream();
      if (e.streams.length > 0) {
        e.streams[0].getTracks().forEach((track) => {
          newStream.addTrack(track);
        });

        console.log("start call Remote stream " + newStream.toURL())
        setRemoteStream(newStream);
      }

    };
    // make offer
    let offer = null
    try {

      console.log("Start call create offer");
      offer = await localPC.createOffer();

    }
    catch (error) {
      console.log("Start call create offer fail");
    }

    try {
      await localPC.setLocalDescription(offer);

    }
    catch (error) {
      console.log("Start call setLocalDescription fail");
    }

    await setDoc(roomRef, { offer, connected: false, RoomDetails: { HostName: ctx.UserName } }, { merge: true });


    // Listen for remote answer
    onSnapshot(roomRef, (doc) => {
      console.log(" Start call SetupRemoteDescription2 " + localPC);
      const data = doc.data();
      if (!localPC.currentRemoteDescription && data.answer) {
        const rtcSessionDescription = new RTCSessionDescription(data.answer);
        localPC.setRemoteDescription(rtcSessionDescription);
        //timer=setTimeout(SnapShotAndSetICE.bind(this,calleeCandidatesCollection,CachedLocalPC),10000);
        SnapShotAndSetICE(calleeCandidatesCollection, localPC);

        console.log("local pc " + localPC.iceConnectionState)
      }
      else {
        setRemoteStream();
      }

    });
    const TargetRef = doc(targetCollectionRef, route.params.targetuid);

    await setDoc(TargetRef, { InvitationId: MyRandomId }, { merge: true });

    console.log("ice connection 3 " + localPC.iceConnectionState + " signal str " + localPC.signalingState);
    setCachedLocalPC(localPC)
    setInterval(checkIce, 5000, localPC);
  }
  ///// join call
  async function JoinCall() {
    const localPC = new RTCPeerConnection(peerConstraints);
    const roomRef = doc(ref, route.params.id);
    const roomSnapshot = await getDoc(roomRef);
    console.log("join call");
    if (!roomSnapshot.exists) {
      console.log("Join call no room exist");
      return;
    }
    localStream.getTracks().forEach((track) => {
      localPC.addTrack(track, localStream);
    });
    const callerCandidatesCollection = collection(roomRef, "callerCandidates");
    const calleeCandidatesCollection = collection(roomRef, "calleeCandidates");
    localPC.addEventListener("icecandidate", (e) => {

      if (!e.candidate) {
        return;
      }
      addDoc(calleeCandidatesCollection, e.candidate.toJSON());
    });
    localPC.ontrack = (e) => {
      const newStream = new MediaStream();
      e.streams[0].getTracks().forEach((track) => {
        newStream.addTrack(track);
      });
      console.log("Join call Remote stream " + newStream.toURL())
      setRemoteStream(newStream);
    };
    let answer = null;
    const offer = roomSnapshot.data().offer;

    if (!localPC.currentLocalDescription) {
      try { await localPC.setRemoteDescription(new RTCSessionDescription(offer)); }
      catch (error) {
        console.log("create new remote description fail");
      }
      try { answer = await localPC.createAnswer(); }
      catch (error) {
        console.log("create createAnswer fail");
      }
      try { await localPC.setLocalDescription(answer); }
      catch (error) {
        console.log("localdescription fail");
      }
      //timer=setTimeout(SnapShotAndSetICE.bind(this,callerCandidatesCollection,CachedLocalPC),10000);
      SnapShotAndSetICE(callerCandidatesCollection, localPC);
    }
   
    await updateDoc(roomRef, { answer, connected: true }, { merge: true });
    setCachedLocalPC(localPC);
    setInterval(checkIce, 5000, localPC);
  }



  function checkIce(MyPC) {//console.log("ice connection 4");
    if (MyPC) {
      console.log("ice connection 4" + MyPC.iceConnectionState + " signal str " + MyPC.signalingState);
    }
    else {
      console.log("CachedLocalPC " + MyPC);
    }
    //
  }


  useEffect(() => {
    async function SetupStream() {
      const Stream = await GetStreams();

      setLocalStream(Stream);
      console.log("Stream " + Stream);
    }
    async function Setups() {
      await SetupStream();
    }
    Setups();

  }, []);

  useEffect(() => {
    if (localStream) {
      if (route.params.StartCall === true) {
        StartCall2();
      }
      else {
        JoinCall();
      }

    }

  }, [localStream])


  const peerConstraints = {
    iceServers: [
      { urls: 'stun:stun.l.google.com:19302' },
      { urls: 'stun:stun1.l.google.com:19302' },
      { urls: 'stun:stun2.l.google.com:19302' },
      { urls: 'stun:stun3.l.google.com:19302' },
      { urls: 'turn:numb.viagenie.ca', credential: 'muazkh', username: '[email protected]' },
      { urls: 'turn:relay.backups.cz', credential: 'webrtc', username: 'webrtc' },
      { urls: 'turn:relay.backups.cz?transport=tcp', credential: 'webrtc', username: 'webrtc' },
      { urls: 'turn:192.158.29.39:3478?transport=udp', credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=', username: '28224511:1379330808' },
    ]
  };
  return (
    <View className="flex-1 bg-red-600" style={styles.MainContainer}>

      {!remoteStream && (
        <View style={styles.LocalCamContainer} >
          <Text style={styles.Text}> MyCam</Text>
          <RTCView
            className="flex-1"
            streamURL={localStream && localStream.toURL()}
            objectFit={"cover"}
            style={styles.LocalCamContainer}

          />

        </View>


      )}

      {remoteStream && (
        <View style={styles.LocalCamContainer} >
          <RTCView
            className="flex-1"
            streamURL={localStream && localStream.toURL()}
            objectFit={"cover"}
            style={styles.LocalCamContainer}
          />
          {(
            <RTCView

              className="flex-1"
              streamURL={remoteStream && remoteStream.toURL()}
              objectFit={"cover"}
              style={styles.LocalCamContainer}
            />
          )}
        </View>
      )}
    </View>
  );
}


const styles = StyleSheet.create({
  MainContainer:
  {
    flex: 1
  },
  LocalCamContainer:
  {
    flex: 1,
    backgroundColor: "red",
    borderRadius: 8
  },
  Text:
  {
    alignItems: "center",
    justifyContent: "center"
  }
})
export default ConnectScreen2;
0

There are 0 best solutions below