Browse Source

Implemented extension bridge support.

Implemented screen sharing for chrome using extension.
pull/77/head
Simon Eisenmann 11 years ago
parent
commit
93a1c7b668
  1. 19
      static/js/directives/screenshare.js
  2. 9
      static/js/mediastream/peerscreenshare.js
  3. 2
      static/js/mediastream/webrtc.js
  4. 100
      static/js/services/chromeextension.js
  5. 55
      static/js/services/screensharing.js
  6. 9
      static/js/services/services.js

19
static/js/directives/screenshare.js

@ -20,7 +20,7 @@
*/ */
define(['jquery', 'underscore', 'text!partials/screenshare.html', 'text!partials/screensharepeer.html', 'bigscreen'], function($, _, template, templatePeer, BigScreen) { define(['jquery', 'underscore', 'text!partials/screenshare.html', 'text!partials/screensharepeer.html', 'bigscreen'], function($, _, template, templatePeer, BigScreen) {
return ["$window", "mediaStream", "$compile", "safeApply", "videoWaiter", "$timeout", "alertify", "translation", function($window, mediaStream, $compile, safeApply, videoWaiter, $timeout, alertify, translation) { return ["$window", "mediaStream", "$compile", "safeApply", "videoWaiter", "$timeout", "alertify", "translation", "screensharing", function($window, mediaStream, $compile, safeApply, videoWaiter, $timeout, alertify, translation, screensharing) {
var peerTemplate = $compile(templatePeer); var peerTemplate = $compile(templatePeer);
@ -168,9 +168,24 @@ define(['jquery', 'underscore', 'text!partials/screenshare.html', 'text!partials
} }
$scope.layout.screenshare = true; $scope.layout.screenshare = true;
screensharing.getScreen().then(function(options) {
if (options) {
$scope.startScreenshare(options);
} else {
// No options received - assume cancel.
$scope.stopScreenshare();
}
}, function(err) {
console.log("Screen sharing request returned error", err);
$scope.stopScreenshare();
});
};
$scope.startScreenshare = function(options) {
// Create userMedia with screen share type. // Create userMedia with screen share type.
var usermedia = mediaStream.webrtc.doScreenshare(); var usermedia = mediaStream.webrtc.doScreenshare(options);
var handler; var handler;
var peers = {}; var peers = {};
var screenshares = []; var screenshares = [];

9
static/js/mediastream/peerscreenshare.js

@ -71,19 +71,16 @@ define(['jquery', 'underscore', 'mediastream/peercall', 'mediastream/tokens'], f
var screenWidth = window.screen.width; var screenWidth = window.screen.width;
var screenHeight = window.screen.height; var screenHeight = window.screen.height;
// NOTE(longsleep): This generates constrains for the experiental Screen sharing // Constains which define what actually gets shared need to
// support in Chrome 31+. This needs to be enabled in flags: // be provided in options.
// chrome://flags/#enable-usermedia-screen-capture
var mandatoryVideoConstraints = $.extend({ var mandatoryVideoConstraints = $.extend({
chromeMediaSource: 'screen',
maxWidth: screenWidth, maxWidth: screenWidth,
maxHeight: screenHeight maxHeight: screenHeight
}, options); }, options);
var mediaConstraints = { var mediaConstraints = {
audio: false, audio: false,
video: { video: {
mandatory: mandatoryVideoConstraints, mandatory: mandatoryVideoConstraints
optional: []
} }
} }
console.log("Setting screen sharing media constraints", mandatoryVideoConstraints); console.log("Setting screen sharing media constraints", mandatoryVideoConstraints);

2
static/js/mediastream/webrtc.js

@ -481,7 +481,7 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u
var usermedia = new UserMedia({ var usermedia = new UserMedia({
noaudio: true noaudio: true
}); });
var ok = usermedia.doGetUserMedia(null, PeerScreenshare.getMediaContraints()); var ok = usermedia.doGetUserMedia(null, PeerScreenshare.getMediaContraints(options));
if (ok) { if (ok) {
this.e.one("done", function() { this.e.one("done", function() {
usermedia.stop(); usermedia.stop();

100
static/js/services/chromeextension.js

@ -0,0 +1,100 @@
/*
* Spreed WebRTC.
* Copyright (C) 2013-2014 struktur AG
*
* This file is part of Spreed WebRTC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
define(["underscore"], function(_) {
// chromeExtension
return ["$window", "$q", function($window, $q) {
var available = false;
var marker = $window.document.getElementById("chromeextension-available");
if (marker) {
available = true;
console.log("Chrome extension is available.");
}
var ChromeExtension = function() {
this.registry = {};
this.count = 0;
};
ChromeExtension.prototype.call = function(data) {
var deferred = $q.defer();
var n = this.count++;
this.registry[n] = deferred;
var msg = {
Type: "Call",
Call: data,
n: n
}
$window.postMessage(msg, $window.document.URL);
return deferred.promise;
};
ChromeExtension.prototype.onMessage = function(event) {
var data = event.data;
switch (data.Type) {
case "Call":
var deferred = this.registry[data.n];
if (deferred) {
delete this.registry[data.n];
var call = data.Call;
if (call.Type === "Result") {
//console.log("Call complete with result", call);
deferred.resolve(call.Result);
} else {
//console.log("Call failed with error", call);
deferred.reject(call.Error);
}
} else {
console.warn("Unknown call reference received", data, this.registry, this);
}
break;
default:
console.log("Unknown message type", data.Type, data);
break;
}
};
var extension;
if (available) {
extension = new ChromeExtension();
$window.addEventListener("message", function(event) {
//console.log("message", event.origin, event.source === window, event);
if (event.source === window && event.data.answer) {
// Only let through our own messages marked as answer.
extension.onMessage(event);
}
});
}
// public API.
return {
available: available,
call: function(data) {
return extension.call(data);
}
}
}];
});

55
static/js/services/screensharing.js

@ -18,13 +18,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
define(['webrtc.adapter'], function() { define(['underscore', 'webrtc.adapter'], function(_) {
// screensharing // screensharing
return ["$window", function($window) { return ["$window", "$q", "chromeExtension", function($window, $q, chromeExtension) {
// Check if we can do screensharing. // Check if we can do screensharing.
var supported = false; var supported = false;
var prepare = null;
if ($window.webrtcDetectedBrowser === "chrome") { if ($window.webrtcDetectedBrowser === "chrome") {
if ($window.webrtcDetectedVersion >= 32 && if ($window.webrtcDetectedVersion >= 32 &&
$window.webrtcDetectedVersion < 37) { $window.webrtcDetectedVersion < 37) {
@ -32,18 +33,66 @@ define(['webrtc.adapter'], function() {
// It was removed in Chrome 37 in favour of chrome.chooseDesktopMedia // It was removed in Chrome 37 in favour of chrome.chooseDesktopMedia
// https://code.google.com/p/chromium/issues/detail?id=347641 // https://code.google.com/p/chromium/issues/detail?id=347641
supported = true; supported = true;
prepare = function(options) {
// This generates constrains for the flag based screen screensharing
// support in Chrome 31+ to 36. Flag to be enabled is found at:
// chrome://flags/#enable-usermedia-screen-capture
var d = $q.defer()
var opts = _.extend({
chromeMediaSource: "screen"
}, options);
d.resolve(opts);
return d.promise;
};
} else if ($window.webrtcDetectedVersion >= 37) { } else if ($window.webrtcDetectedVersion >= 37) {
// We need a extension to support screen sharing. See // We need a extension to support screen sharing. See
// https://developer.chrome.com/extensions/desktopCapture#method-chooseDesktopMedia // https://developer.chrome.com/extensions/desktopCapture#method-chooseDesktopMedia
// for details. // for details.
} }
if (chromeExtension.available) {
supported = true;
prepare = function(options) {
var select = chromeExtension.call({
Type: "Action",
Action: "chooseDesktopMedia"
});
var d = $q.defer();
select.then(function(id) {
//console.log("Prepare screensharing success", id);
if (id) {
var opts = _.extend({
chromeMediaSource: "desktop",
chromeMediaSourceId: id
}, options);
d.resolve(opts);
} else {
d.resolve(null);
}
}, function(err) {
console.log("Failed to prepare screensharing", err);
d.reject(err);
});
return d.promise;
};
}
} else { } else {
// Currently Chrome only. // Currently Chrome only.
} }
// public API. // public API.
return { return {
supported: supported supported: supported,
getScreen: function(options) {
if (prepare) {
return prepare(options);
} else {
var d = $q.defer()
d.reject("No implementation to get screen.");
return d.promise;
}
}
} }
}]; }];

9
static/js/services/services.js

@ -53,7 +53,8 @@ define([
'services/dialogs', 'services/dialogs',
'services/geolocation', 'services/geolocation',
'services/screensharing', 'services/screensharing',
'services/continueconnector'], function(_, 'services/continueconnector',
'services/chromeextension'], function(_,
desktopNotify, desktopNotify,
playSound, playSound,
safeApply, safeApply,
@ -86,7 +87,8 @@ animationFrame,
dialogs, dialogs,
geolocation, geolocation,
screensharing, screensharing,
continueConnector) { continueConnector,
chromeExtension) {
var services = { var services = {
desktopNotify: desktopNotify, desktopNotify: desktopNotify,
@ -121,7 +123,8 @@ continueConnector) {
dialogs: dialogs, dialogs: dialogs,
geolocation: geolocation, geolocation: geolocation,
screensharing: screensharing, screensharing: screensharing,
continueConnector: continueConnector continueConnector: continueConnector,
chromeExtension: chromeExtension
}; };
var initialize = function(angModule) { var initialize = function(angModule) {

Loading…
Cancel
Save