Trying to keep the problem as simple as possible, I am creating a media stream in a chrome extension like so:
var pc = new RTCPeerConnection(null);
chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], null, function(streamId) {
var constraints = {
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: streamId
}
}
},
success = function(stream) {
pc.addStream(stream);
pc.createOffer(function(offer) {
pc.setLocalDescription(offer, function() {
send('make_offer', name, offer);
}, printError);
}, printError);
};
getUserMedia(constraints, success, printError);
});
For now, my offer is received by a peer visiting a page in a browser. That looks more or less like this (m is a message object with the offer):
var pc = new RTCPeerConnection(null);
pc.onaddstream = function(e) {
var video = document.getElementById('video');
video.src = URL.createObjectURL(e.stream);
};
pc.setRemoteDescription(new RTCSessionDescription(m.value), function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer, function() {
send('make_answer', m.from, answer);
}, printError);
}, printError);
}, printError);
I have done this, both with and without ice servers, which look like this when I use them:
var iceServers = {
iceServers: [
{url: 'stun:stun.l.google.com:19302'}
]
};
Right now, the peer receives and displays the stream perfectly in Firefox. No problem at all. But it's not working in Chrome. Here is some selected data from chrome://webrtc-internals: connection to firefox:
"ssrc_3309930214_send-transportId": {
"startTime": "2014-09-30T01:41:11.525Z",
"endTime": "2014-09-30T01:41:21.606Z",
"values": "[\"Channel-video-1\",\"Channel-video-1\",\"Channel-video-1\"]"
},
"ssrc_3309930214_send-packetsLost": {
"startTime": "2014-09-30T01:41:11.525Z",
"endTime": "2014-09-30T01:41:21.606Z",
"values": "[0,0,0,0,0,0,0]"
},
connection to chrome:
"ssrc_1684026093_send-transportId": {
"startTime": "2014-09-30T01:41:57.310Z",
"endTime": "2014-09-30T01:42:00.313Z",
"values": "[\"Channel-audio-1\",\"Channel-audio-1\",\"Channel-audio-1\",\"Channel-audio-1\"]"
},
"ssrc_1684026093_send-packetsLost": {
"startTime": "2014-09-30T01:41:57.310Z",
"endTime": "2014-09-30T01:42:00.313Z",
"values": "[-1,-1,-1,-1]" // what is causing this??
},
Those seem important, but I'm not sure exactly of the implications. I have more data, but I'm not sure exactly what is important. The main idea, is that data goes out to firefox, but not to chrome, though no exceptions occur that I can see. The one further suspicious piece of data happens if I load the peer page in Chrome Canary (latest):
Failed to load resource: net::ERR_CACHE_MISS
This is a console error, and I don't know where it comes from. It occurs after the answer is sent from the peer back to the host (chrome extension).
Signaling done over wss://, test peer is hosted at https:// I'm not sure where to go from here.
Update: Based on answer and comment, I added a handler for onicecandidate:
pc.onicecandidate = function(e) {
console.log('This is the ice candidate.');
console.log(e);
if(!e.candidate) return console.warn('no candidate!');
send('got_ice_candidate', name, e.candidate);
};
I also set up an equivalent peer connection from browser to browser using video:
var constraints = {
audio: false,
video: true
};
getUserMedia(constraints, success, printError);
This works fine, both from Firefox to Chrome and vise-versa, so the issue may be chrome-extension-specific... There is a difference in how ice gathering occurs between the successful case and the extension case:
- Between browsers, there is no ice at all. There is one event, and e.candidate is
null
. - From extension to browser, there are lots of
onicecandidate
events. They are not all in agreement. So perhaps the chrome extension is confusing the STUN server? I don't know.
Thanks for your answers, would love any more insight that you have.
can you please add handling ice candidates on both sides ?
pc.onicecandidate = function(e){ send('ice_candidate', e.target) }
And on the other side on receiving this 'message' do
pc.addIceCandidate(new RTCIceCandidate(message));
Chrome sends ice candidates even after offer/answer have been exchanged which firefox does not seem to do.