Create Video calls and screen sharing using WebRTC

Hi there, today we are creating a video call app using webRtc, firebase, and react.js.

You can also test code available here -> Github

1. Create Room ->

First, create a real-time database in firebase and create a room Id using URL params, a randomly created key in the firebase database.

// reference of RD

let RD = firebase.database().ref();

// url params

const URLPARAMS = new URLSearchParams(window.location.search);

// get id from url

const roomId = URLPARAMS.get("id");




if (roomId) {

  // set room id as child

  RD = RD.child(roomId);

} else {

  // create id and set to roomid

  RD = RD.push();

  window.history.replaceState(null, "meet", "?id=" + RD.key);

}


2. create participant object –

now we will create an object participant in our room Id which contains audio, video, and screen share information. It will look like this –

To get this output, we will do as follow, you can get userName as a string or get it dynamically too.

const participantDb = RD.child("participant");

  useEffect(() => {

    //check for value if true

    connectedRef.on("value", (snap) => {

      if (snap.val()) {

        // create values to push

        const defaultPref = {

          audio: true,

          video: false,

          screen: false,

        };

 

    // push data to participant

        const pushedDataOfParticipant = participantDb.push({

          userName: 'tejendra',

          preference: defaultPref,

        });

        // remove user when he quit or close browser

        pushedDataOfParticipant.onDisconnect().remove();

      }

    });

  }, []);


3. Peer Connection –

Now the most important part of webrtc is creating peer-to-peer connections so we can improve communication in realtime, for that we need to follow the below image.

For signaling, we are using firebase.

The first user will create an offer for others to join and when someone joins then one answer will be created and they will communicate using signaling.

  1. create offer –
export const createOffer = async (peerConnection, receiverId, createdID) => {

  const currentParticipantRef = participantRef.child(receiverId);

  peerConnection.onicecandidate = (event) => {

    event.candidate &&

      currentParticipantRef

        .child("offerCandidates")

        .push({ ...event.candidate.toJSON(), userId: createdID });

  };

 

  const offerDescription = await peerConnection.createOffer();

  await peerConnection.setLocalDescription(offerDescription);




  const offer = {

    sdp: offerDescription.sdp,

    type: offerDescription.type,

    userId: createdID,

  };




  await currentParticipantRef.child("offers").push().set({ offer });

};




export const initializeListensers = async (userId) => {

  const currentUserRef = participantRef.child(userId);




  currentUserRef.child("offers").on("child_added", async (snapshot) => {

    const data = snapshot.val();

    if (data?.offer) {

      const pc =

        store.getState().participants[data.offer.userId].peerConnection;

      await pc.setRemoteDescription(new RTCSessionDescription(data.offer));

      await createAnswer(data.offer.userId, userId);

    }

  });

 

  currentUserRef.child("offerCandidates").on("child_added", (snapshot) => {

    const data = snapshot.val();

    if (data.userId) {

      const pc = store.getState().participants[data.userId].peerConnection;

      pc.addIceCandidate(new RTCIceCandidate(data));

    }

  });

 

  currentUserRef.child("answers").on("child_added", (snapshot) => {

    const data = snapshot.val();

    if (data?.answer) {

      const pc =

        store.getState().participants[data.answer.userId].peerConnection;

      const answerDescription = new RTCSessionDescription(data.answer);

      pc.setRemoteDescription(answerDescription);

    }

  });

 

  currentUserRef.child("answerCandidates").on("child_added", (snapshot) => {

    const data = snapshot.val();

    if (data.userId) {

      const pc = store.getState().participants[data.userId].peerConnection;

      pc.addIceCandidate(new RTCIceCandidate(data));

    }

  });

};


  1. create answer –
const createAnswer = async (otherUserId, userId) => {

  const pc = store.getState().participants[otherUserId].peerConnection;

  const participantRef1 = participantRef.child(otherUserId);

  pc.onicecandidate = (event) => {

    event.candidate &&

      participantRef1

        .child("answerCandidates")

        .push({ ...event.candidate.toJSON(), userId: userId });

  };


  const answerDescription = await pc.createAnswer();

  await pc.setLocalDescription(answerDescription);




  const answer = {

    type: answerDescription.type,

    sdp: answerDescription.sdp,

    userId: userId,

  };

 

  await participantRef1.child("answers").push().set({ answer });

};

 

That’s it, now you can create a simple UI component and start a real-time chat with audio, video, and screen share.

Leave a Reply