I have an application in which I have implemented audio/video calling between web ( Reactjs ) and mobile ( React Native ). I am using react-native-webrtc
for mobile side peer. When an audio call is connected and peer connections are created, the audio stream works perfectly. When I switch to video call during the audio call and the camera on my device turns on, the existing stream is not updated to accommodate both audio and video streams. I am looking for a solution where I can switch between audio and video calls on the fly and update the webRTC stream accordingly.
Reactjs code: Getting audio stream and setting it to localStream
getStream = (options) => {
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
navigator.getUserMedia(
{ audio: true, video: false },
(stream) => {
console.log("getusermedia event obj", stream);
console.log(stream.getTracks());
this.localGetTracks();
if (this.localVideo.current !== null) {
this.localVideo.current.srcObject = stream;
this.localStream = stream;
}
},
(error) => {
console.log("User Media Error", error);
}
)};
Reactjs code: New peer connection is created and stream is added with the localStream
in it, which includes audio as true and video as false
newPeerConnection = () => {
window.RTCPeerConnection =
window.mozRTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.RTCPeerConnection;
let peerConn = new RTCPeerConnection({
iceServers: turnServer,
});
peerConn.onicecandidate = (evt) => {
if (evt.candidate) {
this.props.connection.invoke(
"addIceCandidate",
parseInt(this.props.ticket.id),
JSON.stringify({
type: "candidate",
sdpMLineIndex: evt.candidate.sdpMLineIndex,
sdpMid: evt.candidate.sdpMid,
candidate: evt.candidate.candidate,
})
);
} else {
console.log("End of candidates.");
this.setState(
{
videoState: true,
end_call: true,
call_status: "Connected",
},
() => this.props._handleCallConnected(true)
);
}
this.forceUpdate();
};
peerConn.addStream(this.localStream);
peerConn.addEventListener(
"addstream",
(stream) => {
console.log("remoteStream on addstream", stream);
this.remoteVideo.current.srcObject = stream.stream;
},
false
);
this.setState({
peerConn: peerConn,
})};
React-native code: An event listener is subscribed for when a new stream is added, it listens to this eventListener
and adds the upcoming stream to remoteStream
peerConn.addEventListener(
'addstream',
(stream) => {
console.log(`AddStreamListen`);
console.log('remoteStream added', stream);
InCallManager.setForceSpeakerphoneOn(false);
this.setState({
isSpeakerEnabled: false,
});
this.setState({
remoteStream: stream,
showAudioCallTimer: true,
});
},
false,
);
Reactjs code: Adding a new stream with audio and video both as true
getVideoStream = () => {
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
navigator.getUserMedia(
{ audio: true, video: true, mirror: true },
(stream) => {
this.localStream = stream;
this.localVideo.current.srcObject = this.localStream;
this.state.peerConn.addStream(this.localStream);
},
(error) => {
console.log("error", error);
}
)};
But the eventListener
on mobile code does not listen to the second stream I am adding with audio as true and video as true, the previous stream continues and video is not showing up