I see all the server/mobile etc. stuff working including audio and video, but the second it has to use the TURN servers, it doesn’t show audio/video. I can see candidates going in between, and connection established the same as local, but no audio or video transferred. I’m thinking there is a syntax issue, since the TURN servers aren’t mine/not custom.
Turn servers are from xirsys.net/
Static configuration (just copy pasting the creds/servers etc)
import { io } from 'lib'
import {
RTCPeerConnection,
RTCIceCandidate,
RTCSessionDescription,
RTCView,
MediaStream,
MediaStreamTrack,
mediaDevices,
registerGlobals
} from 'react-native-webrtc'
const config = {
iceServers: [
{ url: 'stun:eu-turn1.xirsys.com' },
{
username: '*****',
credential: '*****',
urls: [
'turn:eu-turn1.xirsys.com:80?transport=udp',
'turn:eu-turn1.xirsys.com:3478?transport=udp',
'turn:eu-turn1.xirsys.com:80?transport=tcp',
'turn:eu-turn1.xirsys.com:3478?transport=tcp',
'turns:eu-turn1.xirsys.com:443?transport=tcp',
'turns:eu-turn1.xirsys.com:5349?transport=tcp'
]
},
]
}
let myConn = new RTCPeerConnection(config),
clients = {},
local,
guestPeer,
remoteStream
function getRemoteStream() {
return remoteStream
}
// starts the camera
function localStream() {
if(local) return local
mediaDevices.enumerateDevices()
.then(sourceInfos => {
let videoSourceId
for (let i = 0; i < sourceInfos.length; i++) {
const sourceInfo = sourceInfos[i]
if(sourceInfo.kind == 'videoinput' && sourceInfo.facing == 'front') {
videoSourceId = sourceInfo.deviceId
}
}
mediaDevices
.getUserMedia({
audio: true,
video: {
mandatory: {
minFrameRate: 30,
minHeight: 768,
minWidth: 1280
},
facingMode: 'user',
// optional: videoSourceId ? [{ sourceId: videoSourceId }] : [],
},
})
.then(stream => {
local = stream
myConn.addStream(stream)
return stream
})
.catch(error => {
// Log error
})
})
}
// TODO: handle later. for now, handle the people that come in later
// tell the existing guests the host started streaming
function startStreaming() {
io.startStreaming()
}
// HOST should send an offer
function onNewGuest({ guestId, hostId }) {
let newPeer = new RTCPeerConnection(config)
clients[guestId] = newPeer
newPeer.addStream(local)
newPeer.createOffer()
.then(sdp => newPeer.setLocalDescription(sdp))
.then(() => {
io.sendOffer({ guestId, offer: newPeer.localDescription })
})
.catch(e => console.log('err create offer', e))
newPeer.onicecandidate = (e) => {
if(!e.candidate) return
io.candidate({ guestId, candidate: e.candidate })
}
}
// GUEST received an offer
function onOffer({ hostId, offer, guestId }) {
console.log('offer?', offer);
guestPeer = new RTCPeerConnection(config)
guestPeer
.setRemoteDescription(new RTCSessionDescription(offer))
.then(() => guestPeer.createAnswer())
.then(sdp => guestPeer.setLocalDescription(sdp))
.then(() => io.sendAnswer({ hostId, offer: guestPeer.localDescription }))
.catch(e => console.log('err onOffer', e))
guestPeer.onicecandidate = e => {
if(!e.candidate) return
io.candidate({ hostId, candidate: e.candidate })
}
guestPeer.onaddstream = e => {
if(!e.stream || remoteStream === e.stream) return console.log('same stream')
remoteStream = e.stream
}
}
// HOST received an answer to offer
function onAnswer({ guestId, offer }) {
clients[guestId]
.setRemoteDescription(new RTCSessionDescription(offer))
}
function addIceCandidate({ guestId, hostId, candidate }) {
console.log('got ice', candidate);
if(guestId) guestPeer.addIceCandidate(new RTCIceCandidate(candidate))
if(hostId) clients[guestId]?.addIceCandidate(new RTCIceCandidate(candidate))
}
function close(isHost) {
isHost
? clients.forEach(x => x.close())
: guestPeer?.close()
}
const streaming = {
localStream,
getRemoteStream,
onAnswer,
onOffer,
onNewGuest,
guestPeer,
startStreaming,
addIceCandidate,
close,
switchCamera: () => {
local
.getVideoTracks()
.forEach((track) => {
track._switchCamera()
})
},
// Mutes the local's outgoing audio
toggleMute: () => {
local
.getAudioTracks()
.forEach(track => {
track.enabled = !track.enabled
})
}
}
export default streaming
Is this some kind of syntax issue, or am I missing something?