I'm trying to start desktop screen streaming from native client to web browser. When i start connection sdp exchange is ok and media streaming starts as it should. But data channel is immidiately fires "close" event. As i understand data channel should be created befoe sdp exchange and i set negotiate to false. So it should automaticly inform other peer about this channel and start data channel. but it's not in my case.
I tried many different ways like setting datachannel with options or peer connection with or without options.
Am i missing something ?
Following is code for initiator from web browser.
var pcConstraints = {};
var servers = {
//iceTransportPolicy: 'relay', // force turn
iceServers:
[
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:stun.stunprotocol.org:3478' },
{ url: 'stun:stun.anyfirewall.com:3478' }
]
};
var offerOptions = {
offerToReceiveAudio: 0,
offerToReceiveVideo: 1,
trickle: false
};
function startStream() {
console.log("startStream...");
remotestream = new RTCPeerConnection(servers, pcConstraints);
if (localstream) {
remotestream.addStream(localstream);
}
// optional data channel
dataChannel = remotestream.createDataChannel('testchannel', {});
setDataChannel(dataChannel);
remotestream.onaddstream = function (e) {
try {
console.log("remote media connection success!");
var vid2 = document.getElementById('vid2');
vid2.srcObject = e.stream;
vid2.onloadedmetadata = function (e) {
vid2.play();
};
var t = setInterval(function () {
if (!remotestream) {
clearInterval(t);
}
else {
Promise.all([
remotestream.getStats(null).then(function (o) {
var rcv = null;
var snd = null;
o.forEach(function (s) {
if ((s.type == "inbound-rtp" && s.mediaType == "video" && !s.isRemote) ||
(s.type == "ssrc" && s.mediaType == "video" && s.id.indexOf("recv") >= 0))
{
rcv = s;
}
else if((s.type == "outbound-rtp" && s.mediaType == "video" && !s.isRemote) ||
(s.type == "ssrc" && s.mediaType == "video" && s.id.indexOf("send") >= 0))
{
snd = s;
}
});
return dumpStat(rcv, snd);
})
]).then(function (s) {
statsdiv.innerHTML = "<small>" + s + "</small>";
});
}
}, 100);
} catch (ex) {
console.log("Failed to connect to remote media!", ex);
socket.close();
}
};
remotestream.onicecandidate = function (event) {
if (event.candidate) {
var ice = parseIce(event.candidate.candidate);
if (ice && ice.component_id == 1 // skip RTCP
//&& ice.type == 'relay' // force turn
&& ice.localIP.indexOf(":") < 0) { // skip IP6
console.log('onicecandidate[local]: ' + event.candidate.candidate);
var obj = JSON.stringify({
"command": "onicecandidate",
"candidate": event.candidate
});
send(obj);
localIce.push(ice);
}
else {
console.log('onicecandidate[local skip]: ' + event.candidate.candidate);
}
}
else {
console.log('onicecandidate: complete.')
if (remoteAnswer) {
// fill empty pairs using last remote ice
//for (var i = 0, lenl = localIce.length; i < lenl; i++) {
// if (i >= remoteIce.length) {
// var c = remoteIce[remoteIce.length - 1];
// var ice = parseIce(c.candidate);
// ice.foundation += i;
// c.candidate = stringifyIce(ice);
// remotestream.addIceCandidate(c);
// }
//}
}
}
};
remotestream.createOffer(function (desc) {
console.log('createOffer: ' + desc.sdp);
remotestream.setLocalDescription(desc, function () {
var obj = JSON.stringify({
"command": "offer",
"desc": desc
});
send(obj);
},
function (errorInformation) {
console.log('setLocalDescription error: ' + errorInformation);
});
},
function (error) {
alert(error);
},
offerOptions);
}
function setDataChannel(dc) {
dc.onerror = function (error) {
alert("DataChannel Error:", error);
};
dc.onmessage = function (event) {
alert("DataChannel Message:", event.data);
};
dc.onopen = function () {
dataChannel.send("Hello World!");
};
dc.onclose = function (error) {
alert("DataChannel is Closed");
alert(error.data)
};
}