Browse Source

Implemented negotiation workaround for Firefox.

pull/112/head
Simon Eisenmann 11 years ago
parent
commit
4b6e9d27a6
  1. 25
      static/js/directives/audiovideo.js
  2. 2
      static/js/mediastream/peercall.js
  3. 29
      static/js/mediastream/peerconnection.js

25
static/js/directives/audiovideo.js

@ -27,6 +27,11 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
var streams = {}; var streams = {};
var getStreamId = function(stream, currentcall) {
var id = currentcall.id + "-" + stream.id;
console.log("Created stream ID", id);
return id;
};
$scope.container = $element.get(0); $scope.container = $element.get(0);
$scope.layoutparent = $element.parent(); $scope.layoutparent = $element.parent();
@ -48,8 +53,10 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
$scope.addRemoteStream = function(stream, currentcall) { $scope.addRemoteStream = function(stream, currentcall) {
if (streams.hasOwnProperty(stream.id)) { var id = getStreamId(stream, currentcall);
console.warn("Cowardly refusing to add stream id twice", stream.id, currentcall);
if (streams.hasOwnProperty(id)) {
console.warn("Cowardly refusing to add stream id twice", id, currentcall);
return; return;
} }
@ -62,16 +69,16 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
subscope.onlyaudio = false; subscope.onlyaudio = false;
subscope.destroyed = false; subscope.destroyed = false;
subscope.$on("active", function() { subscope.$on("active", function() {
console.log("Stream scope is now active", stream.id, peerid); console.log("Stream scope is now active", id, peerid);
}); });
subscope.$on("$destroy", function() { subscope.$on("$destroy", function() {
console.log("Destroyed scope for stream", stream.id, peerid); console.log("Destroyed scope for stream", id, peerid);
subscope.destroyed = true; subscope.destroyed = true;
}); });
console.log("Created stream scope", stream.id, peerid); console.log("Created stream scope", id, peerid);
// Add created scope. // Add created scope.
streams[stream.id] = subscope; streams[id] = subscope;
// Render template. // Render template.
peerTemplate(subscope, function(clonedElement, scope) { peerTemplate(subscope, function(clonedElement, scope) {
@ -120,10 +127,12 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
$scope.removeRemoteStream = function(stream, currentcall) { $scope.removeRemoteStream = function(stream, currentcall) {
//console.log("remove stream", stream, stream.id, currentcall); //console.log("remove stream", stream, stream.id, currentcall);
var subscope = streams[stream.id]; var id = getStreamId(stream, currentcall);
var subscope = streams[id];
if (subscope) { if (subscope) {
buddyData.pop(currentcall.id); buddyData.pop(currentcall.id);
delete streams[stream.id]; delete streams[id];
//console.log("remove scope", subscope); //console.log("remove scope", subscope);
if (subscope.element) { if (subscope.element) {
subscope.element.remove(); subscope.element.remove();

2
static/js/mediastream/peercall.js

@ -138,7 +138,7 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection
// after the remote SDP was set successfully. // after the remote SDP was set successfully.
_.defer(_.bind(function() { _.defer(_.bind(function() {
_.each(peerconnection.getRemoteStreams(), _.bind(function(stream) { _.each(peerconnection.getRemoteStreams(), _.bind(function(stream) {
if (!this.streams.hasOwnProperty(stream) && (stream.getAudioTracks().length > 0 || stream.getVideoTracks().length > 0)) { if (!this.streams.hasOwnProperty(stream.id) && (stream.getAudioTracks().length > 0 || stream.getVideoTracks().length > 0)) {
// NOTE(longsleep): Add stream here when it has at least one audio or video track, to avoid FF >= 33 to add it multiple times. // NOTE(longsleep): Add stream here when it has at least one audio or video track, to avoid FF >= 33 to add it multiple times.
console.log("Adding stream after remote SDP success.", stream); console.log("Adding stream after remote SDP success.", stream);
this.onRemoteStreamAdded(stream); this.onRemoteStreamAdded(stream);

29
static/js/mediastream/peerconnection.js

@ -70,13 +70,22 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
// for example https://bugzilla.mozilla.org/show_bug.cgi?id=998546. // for example https://bugzilla.mozilla.org/show_bug.cgi?id=998546.
pc.onaddstream = _.bind(this.onRemoteStreamAdded, this); pc.onaddstream = _.bind(this.onRemoteStreamAdded, this);
pc.onremovestream = _.bind(this.onRemoteStreamRemoved, this); pc.onremovestream = _.bind(this.onRemoteStreamRemoved, this);
// NOTE(longsleep): onnegotiationneeded is not supported by Firefox if (webrtcDetectedBrowser === "firefox") {
// https://bugzilla.mozilla.org/show_bug.cgi?id=840728 // NOTE(longsleep): onnegotiationneeded is not supported by Firefox. We trigger it
pc.onnegotiationneeded = _.bind(this.onNegotiationNeeded, this); // manually when a stream is added or removed.
// https://bugzilla.mozilla.org/show_bug.cgi?id=840728
this.negotiationNeeded = _.bind(function() {
if (this.currentcall.initiate) {
// Trigger onNegotiationNeeded once for Firefox.
console.log("Negotiation needed.");
this.onNegotiationNeeded({target: this.pc});
}
}, this);
} else {
pc.onnegotiationneeded = _.bind(this.onNegotiationNeeded, this);
}
pc.ondatachannel = _.bind(this.onDatachannel, this); pc.ondatachannel = _.bind(this.onDatachannel, this);
pc.onsignalingstatechange = function(event) { pc.onsignalingstatechange = function(event) {
// XXX(longsleep): Remove this or handle it in a real function.
// XXX(longsleep): Firefox 25 does send event as a string (like stable).
console.debug("Signaling state changed", pc.signalingState); console.debug("Signaling state changed", pc.signalingState);
}; };
// NOTE(longsleep): // NOTE(longsleep):
@ -113,6 +122,10 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
}; };
PeerConnection.prototype.negotiationNeeded = function() {
// Per default this does nothing as the browser is expected to handle this.
};
PeerConnection.prototype.createDatachannel = function(label, init) { PeerConnection.prototype.createDatachannel = function(label, init) {
if (!label) { if (!label) {
@ -226,12 +239,8 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
PeerConnection.prototype.onNegotiationNeeded = function(event) { PeerConnection.prototype.onNegotiationNeeded = function(event) {
// XXX(longsleep): Renegotiation seems to break video streams on Chrome 31.
// XXX(longsleep): Renegotiation can happen from both sides, meaning this
// could switch offer/answer side - oh crap.
var peerconnection = event.target; var peerconnection = event.target;
if (peerconnection === this.pc) { if (peerconnection === this.pc) {
//console.log("Negotiation needed.", peerconnection.remoteDescription, peerconnection.iceConnectionState, peerconnection.signalingState, this);
this.currentcall.onNegotiationNeeded(); this.currentcall.onNegotiationNeeded();
} }
@ -271,12 +280,14 @@ define(['jquery', 'underscore', 'webrtc.adapter'], function($, _) {
PeerConnection.prototype.addStream = function() { PeerConnection.prototype.addStream = function() {
_.defer(this.negotiationNeeded);
return this.pc.addStream.apply(this.pc, arguments); return this.pc.addStream.apply(this.pc, arguments);
}; };
PeerConnection.prototype.removeStream = function() { PeerConnection.prototype.removeStream = function() {
_.defer(this.negotiationNeeded);
return this.pc.removeStream.apply(this.pc, arguments); return this.pc.removeStream.apply(this.pc, arguments);
}; };

Loading…
Cancel
Save