Hi there, today we are creating video call app using webRtc, firebase and react.js.
You can also test code available here -> Github
1. Create Room ->
First, create realtime database in firebase and create a roomId using urlparams, which is a random created key in 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 roomId 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 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 most important part of webrtc is create peer to peer connection so we can communication in realtime, for that we need to follow below image.
For signaling we are using firebase.
First user will create a offer for others to join and when someone joins then one answer will be created and they will communicate using signaling.
i. 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));
}
});
};
ii. 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 realtime chat with audio, video and screen share.
Top comments (0)