Fixes firefox issues. The firefox video is displayed in chrome.

This commit is contained in:
hristoterezov 2014-11-14 12:13:26 +02:00
parent 41fd416338
commit f5189d5cdc
9 changed files with 180 additions and 68 deletions

57
app.js
View File

@ -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();

View File

@ -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' +

View File

@ -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) { }

View File

@ -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) {

View File

@ -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]);

View File

@ -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 = {};

View File

@ -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

View File

@ -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;

View File

@ -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) {