Hello, in my application, a room is created, in this room two users can enter, but when one enters and then the other, only the first one of the two devices shows the two videos, in the logs show that the SDPs and Candidates are being set correctly.
I realized that only what shows the two videos, onaddstream is triggered.
On two devices signaling state returns: stable
On two devices Ice state returns: connected and after one return completed
Expected behavior
Show the two videos
let pc
let socket
let _localStream
export default function Chat({ route }) {
const [localStream, setLocalStream] = useState('')
const [remoteStream, setRemoteStream] = useState(null)
useEffect(() => {
connectToServer()
}, [])
function getRoom() {
return route.params.room
}
function connectToServer() {
socket = io.connect('http://192.168.15.6:8080/signal', {
reconnection: false
})
socket.on('connect', () => {
socket.emit('join', {
room: getRoom()
});
socket.on('joined', () => {
createPeerConnection()
getMedia()
})
socket.on('video-offer', (data) => {
handleOfferMsg(data)
// //console.log('OFERTA RECEBIDA NO ' + route.params.name + ' DO ' + data.who)
})
socket.on('video-answer', function (data) {
handleVideoAnswerMsg(data);
// //console.log('RESPOSTA RECEBIDA NO ' + route.params.name + ' DO ' + data.who)
});
socket.on('new-ice-candidate', function (data) {
handleNewICECandidateMsg(data)
////console.log('ICE SERVER RECEBIDO NO ' + route.params.name + ' DO ' + data.who)
});
})
}
function getMedia() {
let isFront = true;
mediaDevices.enumerateDevices().then(sourceInfos => {
let videoSourceId;
for (let i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i];
if (sourceInfo.kind == "videoinput" && sourceInfo.facing == (isFront ? "front" : "environment")) {
videoSourceId = sourceInfo.deviceId;
}
}
mediaDevices.getUserMedia({
audio: true,
video: {
mandatory: {
minWidth: 500, // Provide your own width, height and frame rate here
minHeight: 300,
minFrameRate: 30
},
facingMode: (isFront ? "user" : "environment"),
optional: (videoSourceId ? [{ sourceId: videoSourceId }] : [])
}
})
.then(stream => {
setLocalStream(stream.toURL())
_localStream = stream
pc.addStream(stream)
// Got stream!
})
.catch((e) => console.log('ERRRO AQUI @@@@@@@', e));
})
.catch((e) => console.log('ERRRO AQUI 222222', e))
}
function createPeerConnection(callback) {
const configuration = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] };
pc = new RTCPeerConnection(configuration);
pc.onicecandidate = function (event) {
if (event.candidate) {
//console.log('ICE CRIADO NO ' + route.params.name + ': ' + JSON.stringify(event.candidate))
socket.emit('new-ice-candidate', {
room: getRoom(),
candidate: event.candidate,
who: route.params.nameklj
});
}
};
pc.onaddstream = (e) => {
//console.log('STREAM RECEBIDO NO ' + route.params.name)
debugger
setRemoteStream(e.stream)
}
pc.onnegotiationneeded = () => {
pc.createOffer({
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
})
.then(sdp => {
//console.log('SDP CRIADO PARA OFERTA NO ' + route.params.name + ': ' + JSON.stringify(sdp))
pc.setLocalDescription(sdp)
socket.emit('video-offer', {
room: getRoom(),
sdp: sdp,
who: route.params.name
})
})
.catch(e => reportError(e, 'offer'));
}
if (callback) callback(pc)
}
function reportError(errMessage, from) {
console.log(`Error ${errMessage}, from: ${from}`);
}
function handleOfferMsg(msg) {
createPeerConnection((pc) => {
pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
.then(() => pc.createAnswer({
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
}))
.then(sdp => {
pc.setLocalDescription(sdp)
socket.emit('video-answer', {
room: getRoom(),
sdp,
who: route.params.name
})
})
.catch((e) => console.log('ERRRROOO AQUIIIIIIII', e));
})
}
function handleNewICECandidateMsg(msg) {
if (pc) pc.addIceCandidate(new RTCIceCandidate(msg.candidate))
}
function handleVideoAnswerMsg(msg) {
if (pc) pc.setRemoteDescription(new RTCSessionDescription(msg.sdp)).catch(e => reportError(e, 'VideoAnswerMSG'))
}
return (
<View style={styles.container}>
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>Usuário: {route.params.name}</Text>
<View style={{ flexDirection: "row" }}>
<RTCView streamURL={localStream} style={{ width: 200, height: 200 }} />
{remoteStream && <RTCView streamURL={remoteStream.toURL()} style={{ width: 200, height: 200 }} mirror={true} />}
</View>
</View>
)
}