I have an React Native application that includes group video call. I am using 'RTCPeerConnection
' from 'react-native-webrtc
' package.
On page load, I have initiated local stream and sockets for offers, answers and icecandidate. When a user click start call function RTCPeerConnection will be created, added the local stream to peerconnection, created offer, set local description and send the offer to other users in socket.
Here is the code when a user start the call
createOffer = async() => {
const pc = new RTCPeerConnection({
host: PEER_SERVER_HOST,
path: PEER_SERVER_PATH,
secure: PEER_SECURE,
port: PEER_SERVER_PORT,
iceServers: [
{ urls: ['stun:stun.l.google.com:19302', 'stun:stun2.l.google.com:19302'] },
{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' },
],
});
const stream = await mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach((track) => {
pc.addTrack(track, stream);
});
this.setState({ localStream: stream });
pc.onicecandidate = (event) => {
if (event.candidate) {
// alert(`Sending ICE candidate to ${userId}: ${event.candidate}`);
this.socket.emit('icecandidate_multiple', { candidate: event.candidate, userId: this.state.userId, roomId: this.state.roomId });
}
};
pc.ontrack = (event) => {
const remoteStream = new MediaStream();
event.streams[0].getTracks().forEach((track) => {
remoteStream.addTrack(track);
});
this.setState({
remoteStreams: event.streams[0]
});
alert(JSON.stringify( event.streams[0]));
};
pc.onaddstream = (event) => {
alert("On Add Remote Stream");
}
pc.onconnectionstatechange = (event) => {
alert(`Connection state changed to ${peerConnectionRef.current.connectionState}`);
};
// Set up the iceConnectionState change handler
pc.oniceconnectionstatechange = this.handleIceConnectionStateChange;
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
this.setState({
peerConnections: pc
});
this.socket.emit('offer_multiple', { offer, userId: this.state.userId, roomId: this.state.roomId });
};
When the remote user receives the offer through socket, a seperate RTCPeerConnection will be created, added local stream, setted remote description with the offer received, created answer, set local description with the answer and send back the answer to the called user.
Here is the code for the user received the call
handleOffer = async(offer, userId) => {
const pc = new RTCPeerConnection({
host: PEER_SERVER_HOST,
path: PEER_SERVER_PATH,
secure: PEER_SECURE,
port: PEER_SERVER_PORT,
iceServers: [
{ urls: ['stun:stun.l.google.com:19302', 'stun:stun2.l.google.com:19302'] },
{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' },
],
});
// await pc.addStream(this.state.localStream);
// const { localStream } = this.state;
// localStream.getTracks().forEach((track) => {
// pc.addTrack(track, localStream);
// });
alert("11111");
const stream = await mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach((track) => {
pc.addTrack(track, stream);
});
this.setState({ localStream: stream });
alert("2222222222");
pc.onicecandidate = (event) => {
if (event.candidate) {
// alert(`Sending ICE candidate to ${userId}: ${event.candidate}`);
this.socket.emit('icecandidate_multiple', { candidate: event.candidate, userId: this.state.userId, roomId: this.state.roomId });
}
};
pc.ontrack = (event) => {
const remoteStream = new MediaStream();
event.streams[0].getTracks().forEach((track) => {
remoteStream.addTrack(track);
});
this.setState({
remoteStreams: event.streams[0]
});
alert(JSON.stringify( event.streams[0]));
};
pc.onaddstream = (event) => {
alert("On Add Remote Stream");
}
pc.onconnectionstatechange = (event) => {
alert(`Connection state changed to ${peerConnectionRef.current.connectionState}`);
};
// Set up the iceConnectionState change handler
pc.oniceconnectionstatechange = this.handleIceConnectionStateChange;
await pc.setRemoteDescription(new RTCSessionDescription(offer));
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
this.setState({
peerConnections: pc
});
this.socket.emit('answer_multiple', { answer: answer, userId, roomId: this.state.roomId });
};
Now, all the offer and answer are created and received. The issue is now related to Remote video stream. Inside onTrack
function, have get the streams and added to remote stream state variable. On consoling, the value does come in remotestream.
But, in device, the remote video is displaying as black screen. Local stream is correctly displaying. Could you tell me where I am going worng or what has to be modified to make the remote stream to display.
I have used RTCView
tag to display local and remote stream.
Thanks in Advance.