Browse Source

Allow receiver to receive connections without a stream, by injecting a dummy stream.

pull/206/head
Simon Eisenmann 10 years ago committed by Simon Eisenmann
parent
commit
a44cedc52d
  1. 54
      static/js/directives/audiovideo.js
  2. 5
      static/js/mediastream/peercall.js

54
static/js/directives/audiovideo.js

@ -38,8 +38,11 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
}; };
// Dummy stream. // Dummy stream.
var dummy = { var DummyStream = function() {};
id: "defaultDummyStream" DummyStream.prototype.id = "defaultDummyStream";
DummyStream.prototype.stop = function() {};
DummyStream.is = function(stream) {
return stream && stream.stop === DummyStream.prototype.stop;
}; };
$scope.container = $element[0]; $scope.container = $element[0];
@ -72,19 +75,28 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
} }
var callscope; var callscope;
var subscope;
if (calls.hasOwnProperty(currentcall.id)) { if (calls.hasOwnProperty(currentcall.id)) {
//console.log("xxx has call", id, currentcall.id); //console.log("xxx has call", id, currentcall.id);
callscope = calls[currentcall.id]; if (DummyStream.is(stream)) {
if (stream === dummy) {
return; return;
} }
callscope = calls[currentcall.id];
if (callscope.dummy) { if (callscope.dummy) {
// Current call has a dummy target. Use it directly. // Current call is marked as dummy. Use it directly.
callscope.dummy.$apply(function() { var dummyId = getStreamId(callscope.dummy, currentcall);
subscope = streams[dummyId];
if (subscope) {
subscope.dummy = null;
delete streams[dummyId];
streams[id] = subscope;
safeApply(subscope, function(scope) {
console.log("Replacing dummy with stream", id); console.log("Replacing dummy with stream", id);
callscope.dummy.attachStream(stream); scope.attachStream(stream);
}); });
callscope.dummy = null; } else {
console.warn("Scope marked as dummy but target stream not found", dummyId);
}
return; return;
} }
} else { } else {
@ -97,7 +109,6 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
} }
// Create scope for this stream. // Create scope for this stream.
var subscope;
subscope = callscope.$new(); subscope = callscope.$new();
callscope.streams++; callscope.streams++;
var peerid = subscope.peerid = currentcall.id; var peerid = subscope.peerid = currentcall.id;
@ -125,8 +136,8 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
console.log("Created stream scope", id); console.log("Created stream scope", id);
// If stream is a dummy, mark us in callscope. // If stream is a dummy, mark us in callscope.
if (stream === dummy) { if (DummyStream.is(stream)) {
callscope.dummy = subscope; callscope.dummy = stream;
} }
// Add created scope. // Add created scope.
@ -138,9 +149,15 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
clonedElement.data("peerid", scope.peerid); clonedElement.data("peerid", scope.peerid);
scope.element = clonedElement; scope.element = clonedElement;
scope.attachStream = function(stream) { scope.attachStream = function(stream) {
if (stream === dummy) { if (DummyStream.is(stream)) {
scope.withvideo = false;
scope.onlyaudio = true;
_.defer(function() {
scope.$emit("active", currentcall);
$scope.redraw();
});
return; return;
} } else {
var video = clonedElement.find("video")[0]; var video = clonedElement.find("video")[0];
$window.attachMediaStream(video, stream); $window.attachMediaStream(video, stream);
// Waiter callbacks also count as connected, as browser support (FireFox 25) is not setting state changes properly. // Waiter callbacks also count as connected, as browser support (FireFox 25) is not setting state changes properly.
@ -152,10 +169,12 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
if (withvideo) { if (withvideo) {
scope.$apply(function($scope) { scope.$apply(function($scope) {
$scope.withvideo = true; $scope.withvideo = true;
$scope.onlyaudio = false;
}); });
} else { } else {
console.info("Incoming stream has no video tracks."); console.info("Incoming stream has no video tracks.");
scope.$apply(function($scope) { scope.$apply(function($scope) {
$scope.withvideo = false;
$scope.onlyaudio = true; $scope.onlyaudio = true;
}); });
} }
@ -170,8 +189,9 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
scope.$emit("active", currentcall); scope.$emit("active", currentcall);
$scope.redraw(); $scope.redraw();
}); });
scope.dummy = null;
}
scope.unattached = false; scope.unattached = false;
scope.dummy = false;
}; };
scope.doChat = function() { scope.doChat = function() {
$scope.$emit("startchat", currentcall.id, { $scope.$emit("startchat", currentcall.id, {
@ -323,6 +343,10 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
$window.reattachMediaStream($scope.miniVideo, $scope.localVideo); $window.reattachMediaStream($scope.miniVideo, $scope.localVideo);
$scope.haveStreams = true; $scope.haveStreams = true;
} }
if (stream === null) {
// Inject dummy stream.
stream = new DummyStream();
}
$scope.addRemoteStream(stream, currentcall); $scope.addRemoteStream(stream, currentcall);
}); });
@ -346,7 +370,7 @@ define(['jquery', 'underscore', 'text!partials/audiovideo.html', 'text!partials/
case "connected": case "connected":
case "completed": case "completed":
case "failed": case "failed":
$scope.addRemoteStream(dummy, currentcall); $scope.addRemoteStream(new DummyStream(), currentcall);
break; break;
} }

5
static/js/mediastream/peercall.js

@ -142,13 +142,18 @@ define(['jquery', 'underscore', 'mediastream/utils', 'mediastream/peerconnection
// reason we always trigger onRemoteStream added for all streams which are available // reason we always trigger onRemoteStream added for all streams which are available
// after the remote SDP was set successfully. // after the remote SDP was set successfully.
_.defer(_.bind(function() { _.defer(_.bind(function() {
var streams = 0;
_.each(peerconnection.getRemoteStreams(), _.bind(function(stream) { _.each(peerconnection.getRemoteStreams(), _.bind(function(stream) {
if (!this.streams.hasOwnProperty(stream.id) && (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);
streams++;
} }
}, this)); }, this));
if (streams === 0 && this.sdpConstraints.mandatory && (this.sdpConstraints.mandatory.OfferToReceiveAudio || this.sdpConstraints.mandatory.OfferToReceiveVideo)) {
this.e.triggerHandler("remoteStreamAdded", [null, this]);
}
}, this)); }, this));
}, this), _.bind(function(err) { }, this), _.bind(function(err) {
console.error("Set remote session description failed", err); console.error("Set remote session description failed", err);

Loading…
Cancel
Save