I have a video call app where I a trying to create one to one peer connection.
But somehow track event is not getting dispatched despite doing peer.addTrack from senders end.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Video App</title>
</head>
<body>
<div>
<h3>Your Id: <span id="myId"></span></h3>
<h3>Online Users (click to connect)</h3>
<div id="users">
</div>
<video id="local-video"></video>
<video id="remote-video"></video>
</div>
</div>
<p id="status"></p>
</div>
<!-- Import socket.io script -->
<script src="/socket.io/socket.io.js"></script>
<script src="./client.js"<</script>
</body>
</html>
client.js
const socket = io();
const peer = new RTCPeerConnection({
iceServers: [
{
urls: ["stun:stun.l.google.com:19302", "stun:global.stun.twilio.com:3478"],
},
],
});
const createCall = async (to) => {
const status = document.getElementById("status");
status.innerText = `Calling ${to}`;
const localOffer = await peer.createOffer();
await peer.setLocalDescription(localOffer);
socket.emit("outgoing:call", { fromOffer: localOffer, to });
};
peer.ontrack = async ({ streams: [stream] }) => {
console.log("Incoming stream", stream);
const status = document.getElementById("status");
status.innerText = "Incomming Stream";
const video = document.getElementById("remote-video");
video.srcObject = stream;
video.play();
const mySteam = await navigator.mediaDevices.getUserMedia({
video: true,
});
for (const track of mySteam.getTracks()) {
peer.addTrack(track, mySteam);
}
};
socket.on("users:joined", (id) => {
const usersDiv = document.getElementById("users");
const btn = document.createElement("button");
const textNode = document.createTextNode(id);
btn.id = id;
btn.setAttribute("onclick", `createCall('${id}')`);
btn.appendChild(textNode);
usersDiv.appendChild(btn);
});
socket.on("incomming:answere", async (data) => {
const status = document.getElementById("status");
status.innerText = "incomming:answere";
const { offer } = data;
await peer.setRemoteDescription(offer);
});
socket.on("user:disconnect", (id) => {
document.getElementById(id).remove();
});
socket.on("incomming:call", async (data) => {
const status = document.getElementById("status");
status.innerText = "incomming:call";
const { from, offer } = data;
await peer.setRemoteDescription(offer);
const answereOffer = await peer.createAnswer();
await peer.setLocalDescription(answereOffer);
socket.emit("call:accepted", { answere: answereOffer, to: from });
const mySteam = await navigator.mediaDevices.getUserMedia({
video: true,
});
for (const track of mySteam.getTracks()) {
peer.addTrack(track, mySteam);
}
});
const getAndUpdateUsers = async () => {
const usersDiv = document.getElementById("users");
usersDiv.innerHTML = "";
const response = await fetch("/users", { method: "GET" });
const jsonResponse = await response.json();
console.log(jsonResponse);
jsonResponse.forEach((user) => {
const btn = document.createElement("button");
const textNode = document.createTextNode(user[0]);
btn.id = user[0];
btn.setAttribute("onclick", `createCall('${user[0]}')`);
btn.appendChild(textNode);
usersDiv.appendChild(btn);
});
};
socket.on("hello", ({ id }) => (document.getElementById("myId").innerText = id));
const getUserMedia = async () => {
const userMedia = await navigator.mediaDevices.getUserMedia({
video: true,
});
const videoEle = document.getElementById("local-video");
videoEle.srcObject = userMedia;
videoEle.play();
};
window.addEventListener("load", getAndUpdateUsers);
window.addEventListener("load", getUserMedia);
sever.js (Used to create the inital connection)
//import and initialization
const io = new SocketIO(server);
const PORT = process.env.PORT || 8000;
// Create a users map to keep track of users
const users = new Map();
io.on('connection', socket => {
console.log(`user connected: ${socket.id}`);
users.set(socket.id, socket.id);
// emit that a new user has joined as soon as someone joins
socket.broadcast.emit('users:joined', socket.id);
socket.emit('hello', { id: socket.id });
socket.on('outgoing:call', data => {
const { fromOffer, to } = data;
socket.to(to).emit('incomming:call', { from: socket.id, offer: fromOffer });
});
socket.on('call:accepted', data => {
const { answere, to } = data;
socket.to(to).emit('incomming:answere', { from: socket.id, offer: answere })
});
socket.on('disconnect', () => {
console.log(`user disconnected: ${socket.id}`);
users.delete(socket.id);
socket.broadcast.emit('user:disconnect', socket.id);
});
});
app.use(express.static( path.resolve('./public') ));
app.get('/users', (req, res) => {
return res.json(Array.from(users));
});
server.listen(PORT, () => console.log(`Server started at PORT:${PORT}`));
There are no errors in console
peer.getReceivers() and peer.getSenders() both an empty array.