Reputation: 87
I am trying to make a Zoom-like video call app with ReactJS and Socket.io using WebRTC.I am using NodeJS(socket.io) as the signaling server. I have gone through the process of creating an offer and making the answer.The connection is in stable state. I get the media stream from the remote peer and add it to the video element but for some reason the video doesn't show up in the element. Only the grey screen. Following is my code
ReactJS code
import React, { useState, useEffect, useRef } from 'react'
import { socket } from '../socket';
const PC = new RTCPeerConnection({ iceServers: [{urls: 'stun:stun.l.google.com:19302'}] });
export function VideoPlayer () {
const localVideoRef = useRef(null)
const videoRef = useRef(null)
const [users, setUsers] = useState([])
async function setStream(peerConnection) {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
localVideoRef.current.srcObject = stream
PC.addStream(stream);
}
const onAddStream = obj => {
let vid = document.createElement('video');
vid.setAttribute('class', 'video-small');
vid.setAttribute('autoplay', 'autoplay');
vid.setAttribute('muted', 'muted');
vid.setAttribute('crossorigin', 'anonymous')
vid.setAttribute('id', 'video-small');
document.getElementById('users-container').appendChild(vid)
vid.src = obj.stream
}
const handleAddUsers = data => {
setUsers(data.users)
}
const createOffer = async id => {
const offer = await PC.createOffer()
await PC.setLocalDescription(offer)
socket.emit('make-offer', {
offer: offer,
to: id
})
}
const handleOffer = data => {
const offer = data.offer
PC.setRemoteDescription(new RTCSessionDescription(offer), async () => {
const answer = await PC.createAnswer()
await PC.setLocalDescription(answer)
socket.emit('make-answer', {
answer: answer,
to: data.socket
})
})
}
const handleAnswer = data => {
const answer = data.answer
PC.setRemoteDescription(new RTCSessionDescription(answer), async () => {
document.getElementById(data.socket).setAttribute('class', 'active');
})
}
useEffect(() => {
PC.onaddstream = onAddStream
setStream(PC)
socket.on('add-users', handleAddUsers)
socket.on('offer-made', handleOffer)
socket.on('answer-made', handleAnswer)
window.addEventListener("iceconnectionstatechange", (event) => {
console.log(event)
});
return () => {
PC.onaddstream = null
socket.off('add-users', handleAddUsers)
socket.off('offer-made', handleOffer)
socket.off('answer-made', handleAnswer)
}
}, [])
return(
<div className='container'>
<video style={{ width: '100%', height: 'auto' }} id='localVideo' ref={localVideoRef} autoPlay muted />
<div className='users-container' id='users-container'>
<h4>Users</h4>
<div id='users'>
{users.map(id => (
<div id={id} onClick={() => createOffer(id)}>{id}</div>
))}
</div>
</div>
</div>
)
}
The styles applied to the above code are as follows
html, body {
padding: 0px;
margin: 0px;
}
video {
background: #CCC;
}
.container {
width: 100%;
}
.video-large {
width: 75%;
float: left;
}
.users-container {
width: 21%;
float: left;
padding: 2%;
position: relative;
}
.video-small {
margin-top: 20px;
width: 100%;
}
#users div {
color: red;
text-decoration: underline;
cursor: pointer;
}
#users .active {
color: #000;
cursor: default;
}
And finally the relevant NodeJS code (signaling server)
const app = express()
const server = require('http').createServer(app);
const io = require('socket.io')(server, {
cors: {
origin: "http://localhost:3000"
}
})
const clients = [];
io.on('connection', socket => {
socket.emit('add-users', {
users: clients
})
socket.broadcast.emit('add-users', {
users: [socket.id]
})
socket.on('make-offer', function (data) {
socket.to(data.to).emit('offer-made', {
offer: data.offer,
socket: socket.id
});
});
socket.on('make-answer', function (data) {
socket.to(data.to).emit('answer-made', {
socket: socket.id,
answer: data.answer
});
});
socket.on('disconnect', function () {
clients.splice(clients.indexOf(socket.id), 1);
io.emit('remove-user', socket.id);
});
clients.push(socket.id)
})
What i am thinking is the issue might be with iceconnectionstate, as i have added an event listener on iceconnectionstatechange and it never moves on from new state. But i am not sure how to resolve that or even if that is an issue
Upvotes: 0
Views: 381