Fixes firefox issues. The firefox video is displayed in chrome.
This commit is contained in:
parent
41fd416338
commit
f5189d5cdc
57
app.js
57
app.js
|
@ -69,7 +69,7 @@ function init() {
|
|||
|
||||
obtainAudioAndVideoPermissions(function (stream) {
|
||||
var audioStream, videoStream;
|
||||
if(document.webkitMediaStream)
|
||||
if(window.webkitMediaStream)
|
||||
{
|
||||
var audioStream = new webkitMediaStream();
|
||||
var videoStream = new webkitMediaStream();
|
||||
|
@ -90,7 +90,7 @@ function init() {
|
|||
}
|
||||
else
|
||||
{
|
||||
// VideoLayout.changeLocalAudio(stream);
|
||||
VideoLayout.changeLocalAudio(stream);
|
||||
startLocalRtpStatsCollector(stream);
|
||||
|
||||
|
||||
|
@ -289,16 +289,19 @@ function waitForPresence(data, sid) {
|
|||
var sess = connection.jingle.sessions[sid];
|
||||
|
||||
var thessrc;
|
||||
|
||||
// look up an associated JID for a stream id
|
||||
if (!data.stream.id || data.stream.id.indexOf('mixedmslabel') === -1) {
|
||||
if (data.stream.id && data.stream.id.indexOf('mixedmslabel') === -1) {
|
||||
// look only at a=ssrc: and _not_ at a=ssrc-group: lines
|
||||
|
||||
var ssrclines
|
||||
= SDPUtil.find_lines(sess.peerconnection.remoteDescription.sdp, 'a=ssrc:');
|
||||
ssrclines = ssrclines.filter(function (line) {
|
||||
// NOTE(gp) previously we filtered on the mslabel, but that property
|
||||
// is not always present.
|
||||
// return line.indexOf('mslabel:' + data.stream.label) !== -1;
|
||||
return (!data.stream.id? false : (line.indexOf('msid:' + data.stream.id) !== -1));
|
||||
|
||||
return ((line.indexOf('msid:' + data.stream.id) !== -1));
|
||||
});
|
||||
if (ssrclines.length) {
|
||||
thessrc = ssrclines[0].substring(7).split(' ')[0];
|
||||
|
@ -606,15 +609,27 @@ $(document).bind('setLocalDescription.jingle', function (event, sid) {
|
|||
var media = simulcast.parseMedia(sess.peerconnection.localDescription);
|
||||
media.forEach(function (media) {
|
||||
|
||||
// TODO(gp) maybe exclude FID streams?
|
||||
Object.keys(media.sources).forEach(function(ssrc) {
|
||||
if(Object.keys(media.sources) > 0) {
|
||||
// TODO(gp) maybe exclude FID streams?
|
||||
Object.keys(media.sources).forEach(function (ssrc) {
|
||||
newssrcs.push({
|
||||
'ssrc': ssrc,
|
||||
'type': media.type,
|
||||
'direction': media.direction
|
||||
});
|
||||
});
|
||||
}
|
||||
else if(sess.localStreamsSSRC && sess.localStreamsSSRC[media.type])
|
||||
{
|
||||
newssrcs.push({
|
||||
'ssrc': ssrc,
|
||||
'ssrc': sess.localStreamsSSRC[media.type],
|
||||
'type': media.type,
|
||||
'direction': media.direction
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
console.log('new ssrcs', newssrcs);
|
||||
|
||||
// Have to clear presence map to get rid of removed streams
|
||||
|
@ -647,20 +662,22 @@ $(document).bind('iceconnectionstatechange.jingle', function (event, sid, sessio
|
|||
var metadata = {};
|
||||
metadata.setupTime = (new Date()).getTime() - session.timeChecking;
|
||||
session.peerconnection.getStats(function (res) {
|
||||
res.result().forEach(function (report) {
|
||||
if (report.type == 'googCandidatePair' && report.stat('googActiveConnection') == 'true') {
|
||||
metadata.localCandidateType = report.stat('googLocalCandidateType');
|
||||
metadata.remoteCandidateType = report.stat('googRemoteCandidateType');
|
||||
if(res && res.result) {
|
||||
res.result().forEach(function (report) {
|
||||
if (report.type == 'googCandidatePair' && report.stat('googActiveConnection') == 'true') {
|
||||
metadata.localCandidateType = report.stat('googLocalCandidateType');
|
||||
metadata.remoteCandidateType = report.stat('googRemoteCandidateType');
|
||||
|
||||
// log pair as well so we can get nice pie charts
|
||||
metadata.candidatePair = report.stat('googLocalCandidateType') + ';' + report.stat('googRemoteCandidateType');
|
||||
// log pair as well so we can get nice pie charts
|
||||
metadata.candidatePair = report.stat('googLocalCandidateType') + ';' + report.stat('googRemoteCandidateType');
|
||||
|
||||
if (report.stat('googRemoteAddress').indexOf('[') === 0) {
|
||||
metadata.ipv6 = true;
|
||||
if (report.stat('googRemoteAddress').indexOf('[') === 0) {
|
||||
metadata.ipv6 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
trackUsage('iceConnected', metadata);
|
||||
});
|
||||
trackUsage('iceConnected', metadata);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
@ -1328,6 +1345,8 @@ $(document).ready(function () {
|
|||
VideoLayout.positionLarge(currentVideoWidth, currentVideoHeight);
|
||||
});
|
||||
|
||||
document.getElementById('largeVideo').volume = 0;
|
||||
|
||||
if (!$('#settings').is(':visible')) {
|
||||
console.log('init');
|
||||
init();
|
||||
|
|
|
@ -453,6 +453,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
|||
'a=rtpmap:100 VP8/90000\r\n' +
|
||||
'a=rtcp-fb:100 ccm fir\r\n' +
|
||||
'a=rtcp-fb:100 nack\r\n' +
|
||||
'a=rtcp-fb:100 nack pli\r\n' +
|
||||
'a=rtcp-fb:100 goog-remb\r\n' +
|
||||
'a=rtpmap:116 red/90000\r\n' +
|
||||
'a=rtpmap:117 ulpfec/90000\r\n' +
|
||||
|
|
|
@ -5,6 +5,7 @@ function TraceablePeerConnection(ice_config, constraints) {
|
|||
this.updateLog = [];
|
||||
this.stats = {};
|
||||
this.statsinterval = null;
|
||||
this.originalRemoteDescription = null;
|
||||
this.maxstats = 0; // limit to 300 values, i.e. 5 minutes; set to 0 to disable
|
||||
|
||||
/**
|
||||
|
@ -187,6 +188,7 @@ TraceablePeerConnection.prototype.setRemoteDescription = function (description,
|
|||
var self = this;
|
||||
description = simulcast.transformRemoteDescription(description);
|
||||
this.trace('setRemoteDescription', dumpSDP(description));
|
||||
this.originalRemoteDescription = description;
|
||||
this.peerconnection.setRemoteDescription(description,
|
||||
function () {
|
||||
self.trace('setRemoteDescriptionOnSuccess');
|
||||
|
@ -483,6 +485,11 @@ TraceablePeerConnection.prototype.addIceCandidate = function (candidate, success
|
|||
TraceablePeerConnection.prototype.getStats = function(callback, errback) {
|
||||
if (navigator.mozGetUserMedia) {
|
||||
// ignore for now...
|
||||
if(!errback)
|
||||
errback = function () {
|
||||
|
||||
}
|
||||
this.peerconnection.getStats(null,callback,errback);
|
||||
} else {
|
||||
this.peerconnection.getStats(callback);
|
||||
}
|
||||
|
@ -511,6 +518,18 @@ function setupRTC() {
|
|||
MediaStream.prototype.getAudioTracks = function () { return []; };
|
||||
RTCSessionDescription = mozRTCSessionDescription;
|
||||
RTCIceCandidate = mozRTCIceCandidate;
|
||||
RTC.getLocalSSRC = function (session, callback) {
|
||||
session.peerconnection.getStats(function (s) {
|
||||
session.localStreamsSSRC = {
|
||||
"audio": s['outbound_rtp_audio_0'].ssrc,
|
||||
"video": s['outbound_rtp_video_1'].ssrc
|
||||
};
|
||||
callback(session.localStreamsSSRC);
|
||||
},
|
||||
function () {
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
}
|
||||
} else if (navigator.webkitGetUserMedia) {
|
||||
console.log('This appears to be Chrome');
|
||||
|
@ -537,6 +556,9 @@ function setupRTC() {
|
|||
return this.audioTracks;
|
||||
};
|
||||
}
|
||||
RTC.getLocalSSRC = function (session, callback) {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
if (RTC === null) {
|
||||
try { console.log('Browser does not appear to be WebRTC-capable'); } catch (e) { }
|
||||
|
|
|
@ -84,7 +84,7 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
case 'session-initiate':
|
||||
sess = new JingleSession($(iq).attr('to'), $(iq).find('jingle').attr('sid'), this.connection);
|
||||
// configure session
|
||||
if (this.localAudio) {
|
||||
if (this.localAudio && RTC.browser == "chrome") {
|
||||
sess.localStreams.push(this.localAudio);
|
||||
}
|
||||
if (this.localVideo) {
|
||||
|
@ -169,7 +169,7 @@ Strophe.addConnectionPlugin('jingle', {
|
|||
Math.random().toString(36).substr(2, 12), // random string
|
||||
this.connection);
|
||||
// configure session
|
||||
if (this.localAudio) {
|
||||
if (this.localAudio && RTC.browser == "chrome") {
|
||||
sess.localStreams.push(this.localAudio);
|
||||
}
|
||||
if (this.localVideo) {
|
||||
|
|
|
@ -192,7 +192,8 @@ SDP.prototype.removeMediaLines = function(mediaindex, prefix) {
|
|||
}
|
||||
|
||||
// add content's to a jingle element
|
||||
SDP.prototype.toJingle = function (elem, thecreator) {
|
||||
SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
|
||||
// console.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
|
||||
var i, j, k, mline, ssrc, rtpmap, tmp, line, lines;
|
||||
var self = this;
|
||||
// new bundle plan
|
||||
|
@ -225,7 +226,12 @@ SDP.prototype.toJingle = function (elem, thecreator) {
|
|||
if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
|
||||
ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
|
||||
} else {
|
||||
ssrc = false;
|
||||
if(ssrcs && ssrcs[mline.media])
|
||||
{
|
||||
ssrc = ssrcs[mline.media];
|
||||
}
|
||||
else
|
||||
ssrc = false;
|
||||
}
|
||||
|
||||
elem.c('content', {creator: thecreator, name: mline.media});
|
||||
|
@ -277,25 +283,60 @@ SDP.prototype.toJingle = function (elem, thecreator) {
|
|||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
// FIXME: group by ssrc and support multiple different ssrcs
|
||||
var ssrclines = SDPUtil.find_lines(this.media[i], 'a=ssrc:');
|
||||
ssrclines.forEach(function(line) {
|
||||
idx = line.indexOf(' ');
|
||||
var linessrc = line.substr(0, idx).substr(7);
|
||||
if (linessrc != ssrc) {
|
||||
if(ssrclines.length > 0) {
|
||||
ssrclines.forEach(function (line) {
|
||||
idx = line.indexOf(' ');
|
||||
var linessrc = line.substr(0, idx).substr(7);
|
||||
if (linessrc != ssrc) {
|
||||
elem.up();
|
||||
ssrc = linessrc;
|
||||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
}
|
||||
var kv = line.substr(idx + 1);
|
||||
elem.c('parameter');
|
||||
if (kv.indexOf(':') == -1) {
|
||||
elem.attrs({ name: kv });
|
||||
} else {
|
||||
elem.attrs({ name: kv.split(':', 2)[0] });
|
||||
elem.attrs({ value: kv.split(':', 2)[1] });
|
||||
}
|
||||
elem.up();
|
||||
ssrc = linessrc;
|
||||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
}
|
||||
var kv = line.substr(idx + 1);
|
||||
elem.c('parameter');
|
||||
if (kv.indexOf(':') == -1) {
|
||||
elem.attrs({ name: kv });
|
||||
} else {
|
||||
elem.attrs({ name: kv.split(':', 2)[0] });
|
||||
elem.attrs({ value: kv.split(':', 2)[1] });
|
||||
}
|
||||
});
|
||||
elem.up();
|
||||
});
|
||||
elem.up();
|
||||
}
|
||||
else
|
||||
{
|
||||
elem.up();
|
||||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
elem.c('parameter');
|
||||
elem.attrs({name: "cname", value:Math.random().toString(36).substring(7)});
|
||||
elem.up();
|
||||
var msid = null;
|
||||
if(mline.media == "audio")
|
||||
{
|
||||
msid = connection.jingle.localAudio.getAudioTracks()[0].id;
|
||||
}
|
||||
else
|
||||
{
|
||||
msid = connection.jingle.localVideo.getVideoTracks()[0].id;
|
||||
}
|
||||
if(msid != null)
|
||||
{
|
||||
msid = msid.replace(/[\{,\}]/g,"");
|
||||
elem.c('parameter');
|
||||
elem.attrs({name: "msid", value:msid});
|
||||
elem.up();
|
||||
elem.c('parameter');
|
||||
elem.attrs({name: "mslabel", value:msid});
|
||||
elem.up();
|
||||
elem.c('parameter');
|
||||
elem.attrs({name: "label", value:msid});
|
||||
elem.up();
|
||||
elem.up();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// old proprietary mapping, to be removed at some point
|
||||
tmp = SDPUtil.parse_ssrc(this.media[i]);
|
||||
|
|
|
@ -23,7 +23,7 @@ function JingleSession(me, sid, connection) {
|
|||
this.ice_config = {};
|
||||
this.drip_container = [];
|
||||
|
||||
this.usetrickle = true;
|
||||
this.usetrickle = false;
|
||||
this.usepranswer = false; // early transport warmup -- mind you, this might fail. depends on webrtc issue 1718
|
||||
this.usedrip = false; // dripping is sending trickle candidates not one-by-one
|
||||
|
||||
|
@ -36,6 +36,7 @@ function JingleSession(me, sid, connection) {
|
|||
this.reason = null;
|
||||
|
||||
this.wait = true;
|
||||
this.localStreamsSSRC = null;
|
||||
}
|
||||
|
||||
JingleSession.prototype.initiate = function (peerjid, isInitiator) {
|
||||
|
@ -64,6 +65,7 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) {
|
|||
};
|
||||
this.peerconnection.onaddstream = function (event) {
|
||||
self.remoteStreams.push(event.stream);
|
||||
console.log("REMOTE STREAM ADDED: " + event.stream + " - " + event.stream.id);
|
||||
$(document).trigger('remotestreamadded.jingle', [event, self.sid]);
|
||||
};
|
||||
this.peerconnection.onremovestream = function (event) {
|
||||
|
@ -105,6 +107,7 @@ JingleSession.prototype.accept = function () {
|
|||
|
||||
var pranswer = this.peerconnection.localDescription;
|
||||
if (!pranswer || pranswer.type != 'pranswer') {
|
||||
console.error("No local sdp set!");
|
||||
return;
|
||||
}
|
||||
console.log('going from pranswer to answer');
|
||||
|
@ -128,7 +131,7 @@ JingleSession.prototype.accept = function () {
|
|||
initiator: this.initiator,
|
||||
responder: this.responder,
|
||||
sid: this.sid });
|
||||
prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC);
|
||||
this.connection.sendIQ(accept,
|
||||
function () {
|
||||
var ack = {};
|
||||
|
@ -219,10 +222,10 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
|
|||
}, 20);
|
||||
|
||||
}
|
||||
this.drip_container.push(event.candidate);
|
||||
this.drip_container.push(candidate);
|
||||
return;
|
||||
} else {
|
||||
self.sendIceCandidate([event.candidate]);
|
||||
self.sendIceCandidate([candidate]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -236,25 +239,43 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
|
|||
initiator: this.initiator,
|
||||
sid: this.sid});
|
||||
this.localSDP = new SDP(this.peerconnection.localDescription.sdp);
|
||||
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.connection.sendIQ(init,
|
||||
function () {
|
||||
//console.log('session initiate ack');
|
||||
var ack = {};
|
||||
ack.source = 'offer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
self.state = 'error';
|
||||
self.peerconnection.close();
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'offer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
var self = this;
|
||||
var sendJingle = function (ssrc) {
|
||||
if(!ssrc)
|
||||
ssrc = {};
|
||||
self.localSDP.toJingle(init, self.initiator == self.me ? 'initiator' : 'responder', ssrc);
|
||||
self.connection.sendIQ(init,
|
||||
function () {
|
||||
//console.log('session initiate ack');
|
||||
var ack = {};
|
||||
ack.source = 'offer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
self.state = 'error';
|
||||
self.peerconnection.close();
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'offer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
}
|
||||
|
||||
RTC.getLocalSSRC(this, function (ssrcs) {
|
||||
if(ssrcs)
|
||||
{
|
||||
sendJingle(ssrcs);
|
||||
$(document).trigger("setLocalDescription.jingle", [self.sid]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendJingle();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
this.lasticecandidate = true;
|
||||
console.log('Have we encountered any srflx candidates? ' + this.hadstuncandidate);
|
||||
|
@ -345,7 +366,7 @@ JingleSession.prototype.createdOffer = function (sdp) {
|
|||
action: 'session-initiate',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid});
|
||||
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC);
|
||||
this.connection.sendIQ(init,
|
||||
function () {
|
||||
var ack = {};
|
||||
|
|
|
@ -89,7 +89,8 @@ SessionBase.prototype.switchStreams = function (new_stream, oldStream, success_c
|
|||
self.connection.jingle.localVideo = new_stream;
|
||||
|
||||
self.connection.jingle.localStreams = [];
|
||||
self.connection.jingle.localStreams.push(self.connection.jingle.localAudio);
|
||||
if(RTC.browser == "chrome")
|
||||
self.connection.jingle.localStreams.push(self.connection.jingle.localAudio);
|
||||
self.connection.jingle.localStreams.push(self.connection.jingle.localVideo);
|
||||
|
||||
// Conference is not active
|
||||
|
|
|
@ -174,6 +174,8 @@ StatsCollector.prototype.start = function ()
|
|||
self.peerconnection.getStats(
|
||||
function (report)
|
||||
{
|
||||
if(!report || !report.result || typeof report.result != 'function')
|
||||
return;
|
||||
var results = report.result();
|
||||
//console.error("Got interval report", results);
|
||||
self.currentAudioLevelsReport = results;
|
||||
|
@ -193,6 +195,8 @@ StatsCollector.prototype.start = function ()
|
|||
self.peerconnection.getStats(
|
||||
function (report)
|
||||
{
|
||||
if(!report || !report.result || typeof report.result != 'function')
|
||||
return;
|
||||
var results = report.result();
|
||||
//console.error("Got interval report", results);
|
||||
self.currentStatsReport = results;
|
||||
|
|
|
@ -10,10 +10,13 @@ var VideoLayout = (function (my) {
|
|||
|
||||
my.changeLocalAudio = function(stream) {
|
||||
connection.jingle.localAudio = stream;
|
||||
if(RTC.browser == "chrome")
|
||||
{
|
||||
RTC.attachMediaStream($('#localAudio'), stream);
|
||||
document.getElementById('localAudio').autoplay = true;
|
||||
document.getElementById('localAudio').volume = 0;
|
||||
}
|
||||
|
||||
RTC.attachMediaStream($('#localAudio'), stream);
|
||||
document.getElementById('localAudio').autoplay = true;
|
||||
document.getElementById('localAudio').volume = 0;
|
||||
};
|
||||
|
||||
my.changeLocalVideo = function(stream, flipX) {
|
||||
|
|
Loading…
Reference in New Issue