Removed deskshare library files from client
This commit is contained in:
parent
e7884e831b
commit
e7f8237a21
@ -1,155 +0,0 @@
|
||||
// Last time updated at September 04, 2015, 14:54:45
|
||||
// By Daniel Perrone (perroned)
|
||||
|
||||
// Latest file can be found here: https://cdn.webrtc-experiment.com/Screen-Capturing.js
|
||||
|
||||
// Muaz Khan - www.MuazKhan.com
|
||||
// MIT License - www.WebRTC-Experiment.com/licence
|
||||
// Documentation - https://github.com/muaz-khan/Chrome-Extensions/tree/master/Screen-Capturing.js
|
||||
// Demo - https://www.webrtc-experiment.com/Screen-Capturing/
|
||||
|
||||
// ___________________
|
||||
// Screen-Capturing.js
|
||||
|
||||
// Source code: https://github.com/muaz-khan/Chrome-Extensions/tree/master/desktopCapture
|
||||
// Google AppStore installation path: https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk
|
||||
|
||||
// This JavaScript file is aimed to explain steps needed to integrate above chrome extension
|
||||
// in your own webpages
|
||||
|
||||
// Usage:
|
||||
// getScreenConstraints(function(screen_constraints) {
|
||||
// navigator.webkitGetUserMedia({ video: screen_constraints }, onSuccess, onFailure );
|
||||
// });
|
||||
|
||||
// First Step: Download the extension, modify "manifest.json" and publish to Google AppStore
|
||||
// https://github.com/muaz-khan/Chrome-Extensions/tree/master/desktopCapture#how-to-publish-yourself
|
||||
|
||||
// Second Step: Listen for postMessage handler
|
||||
// postMessage is used to exchange "sourceId" between chrome extension and you webpage.
|
||||
// though, there are tons other options as well, e.g. XHR-signaling, websockets, etc.
|
||||
window.addEventListener('message', function(event) {
|
||||
if (event.origin != window.location.origin) {
|
||||
return;
|
||||
}
|
||||
|
||||
onMessageCallback(event.data);
|
||||
});
|
||||
|
||||
// and the function that handles received messages
|
||||
|
||||
function onMessageCallback(data) {
|
||||
// "cancel" button is clicked
|
||||
if (data == 'PermissionDeniedError') {
|
||||
chromeMediaSource = 'PermissionDeniedError';
|
||||
if (screenCallback) return screenCallback('PermissionDeniedError');
|
||||
else throw new Error('PermissionDeniedError');
|
||||
}
|
||||
|
||||
// extension notified his presence
|
||||
if (data == 'rtcmulticonnection-extension-loaded') {
|
||||
chromeMediaSource = 'desktop';
|
||||
}
|
||||
|
||||
// extension shared temp sourceId
|
||||
if (data.sourceId && screenCallback) {
|
||||
screenCallback(sourceId = data.sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
// global variables
|
||||
var chromeMediaSource = 'screen';
|
||||
var sourceId;
|
||||
var screenCallback;
|
||||
|
||||
// this method can be used to check if chrome extension is installed & enabled.
|
||||
function isChromeExtensionAvailable(callback) {
|
||||
if (!callback) return;
|
||||
|
||||
if (chromeMediaSource == 'desktop') return callback(true);
|
||||
|
||||
// ask extension if it is available
|
||||
window.postMessage('are-you-there', '*');
|
||||
|
||||
setTimeout(function() {
|
||||
if (chromeMediaSource == 'screen') {
|
||||
callback(false);
|
||||
} else callback(true);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// this function can be used to get "source-id" from the extension
|
||||
this.getSourceId = function(callback) {
|
||||
if (!callback) throw '"callback" parameter is mandatory.';
|
||||
if(sourceId) return callback(sourceId);
|
||||
|
||||
screenCallback = callback;
|
||||
window.postMessage('get-sourceId', '*');
|
||||
}
|
||||
|
||||
var isFirefox = typeof window.InstallTrigger !== 'undefined';
|
||||
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
||||
var isChrome = !!window.chrome && !isOpera;
|
||||
|
||||
this.getChromeExtensionStatus = function(callback) {
|
||||
if (isFirefox) return callback('not-chrome');
|
||||
|
||||
var extensionid = Meteor.config.deskshareExtensionKey;
|
||||
|
||||
var image = document.createElement('img');
|
||||
image.src = 'chrome-extension://' + extensionid + '/icon.png';
|
||||
image.onload = function() {
|
||||
chromeMediaSource = 'screen';
|
||||
window.postMessage('are-you-there', '*');
|
||||
setTimeout(function() {
|
||||
if (chromeMediaSource == 'screen') {
|
||||
callback('installed-enabled');
|
||||
} else callback('installed-enabled');
|
||||
}, 2000);
|
||||
};
|
||||
image.onerror = function() {
|
||||
callback('not-installed');
|
||||
};
|
||||
}
|
||||
|
||||
// this function explains how to use above methods/objects
|
||||
this.getScreenConstraints = function(callback) {
|
||||
var firefoxScreenConstraints = {
|
||||
mozMediaSource: 'window',
|
||||
mediaSource: 'window'
|
||||
};
|
||||
|
||||
if(isFirefox) return callback(null, firefoxScreenConstraints);
|
||||
|
||||
// this statement defines getUserMedia constraints
|
||||
// that will be used to capture content of screen
|
||||
var screen_constraints = {
|
||||
mandatory: {
|
||||
chromeMediaSource: chromeMediaSource,
|
||||
maxWidth: screen.width > 1920 ? screen.width : 1920,
|
||||
maxHeight: screen.height > 1080 ? screen.height : 1080
|
||||
},
|
||||
optional: []
|
||||
};
|
||||
|
||||
// this statement verifies chrome extension availability
|
||||
// if installed and available then it will invoke extension API
|
||||
// otherwise it will fallback to command-line based screen capturing API
|
||||
// without a previous sourceId, Chrome will prompt the user to choose again
|
||||
sourceId = null;
|
||||
if (chromeMediaSource == 'desktop') {
|
||||
getSourceId(function() {
|
||||
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
|
||||
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// this statement sets gets 'sourceId" and sets "chromeMediaSourceId"
|
||||
if (chromeMediaSource == 'desktop') {
|
||||
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
|
||||
}
|
||||
|
||||
// now invoking native getUserMedia API
|
||||
callback(null, screen_constraints);
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
// Last time updated at Sep 07, 2014, 08:32:23
|
||||
|
||||
// Latest file can be found here: https://cdn.webrtc-experiment.com/getScreenId.js
|
||||
|
||||
// Muaz Khan - www.MuazKhan.com
|
||||
// MIT License - www.WebRTC-Experiment.com/licence
|
||||
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/getScreenId.js
|
||||
|
||||
// ______________
|
||||
// getScreenId.js
|
||||
|
||||
/*
|
||||
getScreenId(function (error, sourceId, screen_constraints) {
|
||||
// error == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome'
|
||||
// sourceId == null || 'string' || 'firefox'
|
||||
|
||||
if(sourceId == 'firefox') {
|
||||
navigator.mozGetUserMedia(screen_constraints, onSuccess, onFailure);
|
||||
}
|
||||
else navigator.webkitGetUserMedia(screen_constraints, onSuccess, onFailure);
|
||||
});
|
||||
*/
|
||||
|
||||
(function() {
|
||||
window.getScreenId = function(callback) {
|
||||
// for Firefox:
|
||||
// sourceId == 'firefox'
|
||||
// screen_constraints = {...}
|
||||
if (!!navigator.mozGetUserMedia) {
|
||||
callback(null, 'firefox', {
|
||||
video: {
|
||||
mozMediaSource: 'window',
|
||||
mediaSource: 'window'
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
postMessage();
|
||||
|
||||
window.addEventListener('message', onIFrameCallback);
|
||||
|
||||
function onIFrameCallback(event) {
|
||||
if (!event.data) return;
|
||||
|
||||
if (event.data.chromeMediaSourceId) {
|
||||
if (event.data.chromeMediaSourceId === 'PermissionDeniedError') {
|
||||
callback('permission-denied');
|
||||
} else callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId));
|
||||
}
|
||||
|
||||
if (event.data.chromeExtensionStatus) {
|
||||
callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus));
|
||||
}
|
||||
|
||||
// this event listener is no more needed
|
||||
window.removeEventListener('message', onIFrameCallback);
|
||||
}
|
||||
};
|
||||
|
||||
function getScreenConstraints(error, sourceId) {
|
||||
var screen_constraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: error ? 'screen' : 'desktop',
|
||||
maxWidth: window.screen.width > 1920 ? window.screen.width : 1920,
|
||||
maxHeight: window.screen.height > 1080 ? window.screen.height : 1080
|
||||
},
|
||||
optional: []
|
||||
}
|
||||
};
|
||||
|
||||
if (sourceId) {
|
||||
screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
|
||||
}
|
||||
|
||||
return screen_constraints;
|
||||
}
|
||||
|
||||
function postMessage() {
|
||||
if (!iframe.isLoaded) {
|
||||
setTimeout(postMessage, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.contentWindow.postMessage({
|
||||
captureSourceId: true
|
||||
}, '*');
|
||||
}
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.onload = function() {
|
||||
iframe.isLoaded = true;
|
||||
};
|
||||
iframe.src = 'https://www.webrtc-experiment.com/getSourceId/';
|
||||
iframe.style.display = 'none';
|
||||
(document.body || document.documentElement).appendChild(iframe);
|
||||
})();
|
File diff suppressed because it is too large
Load Diff
@ -1,716 +0,0 @@
|
||||
/*
|
||||
* Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is jquery.jsonrpclient.js modified for Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Textalk AB http://textalk.se/
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* jquery.jsonrpclient.js - JSON RPC client code
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* This plugin requires jquery.json.js to be available, or at least the methods $.toJSON and
|
||||
* $.parseJSON.
|
||||
*
|
||||
* The plan is to make use of websockets if they are available, but work just as well with only
|
||||
* http if not.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* var foo = new $.JsonRpcClient({ ajaxUrl: '/backend/jsonrpc' });
|
||||
* foo.call(
|
||||
* 'bar', [ 'A parameter', 'B parameter' ],
|
||||
* function(result) { alert('Foo bar answered: ' + result.my_answer); },
|
||||
* function(error) { console.log('There was an error', error); }
|
||||
* );
|
||||
*
|
||||
* More examples are available in README.md
|
||||
*/
|
||||
(function($) {
|
||||
/**
|
||||
* @fn new
|
||||
* @memberof $.JsonRpcClient
|
||||
*
|
||||
* @param options An object stating the backends:
|
||||
* ajaxUrl A url (relative or absolute) to a http(s) backend.
|
||||
* socketUrl A url (relative of absolute) to a ws(s) backend.
|
||||
* onmessage A socket message handler for other messages (non-responses).
|
||||
* getSocket A function returning a WebSocket or null.
|
||||
* It must take an onmessage_cb and bind it to the onmessage event
|
||||
* (or chain it before/after some other onmessage handler).
|
||||
* Or, it could return null if no socket is available.
|
||||
* The returned instance must have readyState <= 1, and if less than 1,
|
||||
* react to onopen binding.
|
||||
*/
|
||||
$.JsonRpcClient = function(options) {
|
||||
var self = this;
|
||||
this.options = $.extend({
|
||||
ajaxUrl : null,
|
||||
socketUrl : null, ///< The ws-url for default getSocket.
|
||||
onmessage : null, ///< Other onmessage-handler.
|
||||
login : null, /// auth login
|
||||
passwd : null, /// auth passwd
|
||||
sessid : null,
|
||||
loginParams : null,
|
||||
userVariables : null,
|
||||
getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); }
|
||||
}, options);
|
||||
|
||||
self.ws_cnt = 0;
|
||||
|
||||
// Declare an instance version of the onmessage callback to wrap 'this'.
|
||||
this.wsOnMessage = function(event) { self._wsOnMessage(event); };
|
||||
};
|
||||
|
||||
/// Holding the WebSocket on default getsocket.
|
||||
$.JsonRpcClient.prototype._ws_socket = null;
|
||||
|
||||
/// Object <id>: { success_cb: cb, error_cb: cb }
|
||||
$.JsonRpcClient.prototype._ws_callbacks = {};
|
||||
|
||||
/// The next JSON-RPC request id.
|
||||
$.JsonRpcClient.prototype._current_id = 1;
|
||||
|
||||
|
||||
$.JsonRpcClient.prototype.speedTest = function (bytes, cb) {
|
||||
var socket = this.options.getSocket(this.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
this.speedCB = cb;
|
||||
this.speedBytes = bytes;
|
||||
socket.send("#SPU " + bytes);
|
||||
|
||||
var loops = bytes / 1024;
|
||||
var rem = bytes % 1024;
|
||||
var i;
|
||||
var data = new Array(1024).join(".");
|
||||
for (i = 0; i < loops; i++) {
|
||||
socket.send("#SPB " + data);
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
socket.send("#SPB " + data);
|
||||
}
|
||||
|
||||
socket.send("#SPE");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @fn call
|
||||
* @memberof $.JsonRpcClient
|
||||
*
|
||||
* @param method The method to run on JSON-RPC server.
|
||||
* @param params The params; an array or object.
|
||||
* @param success_cb A callback for successful request.
|
||||
* @param error_cb A callback for error.
|
||||
*/
|
||||
$.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) {
|
||||
// Construct the JSON-RPC 2.0 request.
|
||||
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
if (this.options.sessid) {
|
||||
params.sessid = this.options.sessid;
|
||||
}
|
||||
|
||||
var request = {
|
||||
jsonrpc : '2.0',
|
||||
method : method,
|
||||
params : params,
|
||||
id : this._current_id++ // Increase the id counter to match request/response
|
||||
};
|
||||
|
||||
if (!success_cb) {
|
||||
success_cb = function(e){console.log("Success: ", e);};
|
||||
}
|
||||
|
||||
if (!error_cb) {
|
||||
error_cb = function(e){console.log("Error: ", e);};
|
||||
}
|
||||
|
||||
// Try making a WebSocket call.
|
||||
var socket = this.options.getSocket(this.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
this._wsCall(socket, request, success_cb, error_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
// No WebSocket, and no HTTP backend? This won't work.
|
||||
if (this.options.ajaxUrl === null) {
|
||||
throw "$.JsonRpcClient.call used with no websocket and no http endpoint.";
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : this.options.ajaxUrl,
|
||||
data : $.toJSON(request),
|
||||
dataType : 'json',
|
||||
cache : false,
|
||||
|
||||
success : function(data) {
|
||||
if ('error' in data) error_cb(data.error, this);
|
||||
success_cb(data.result, this);
|
||||
},
|
||||
|
||||
// JSON-RPC Server could return non-200 on error
|
||||
error : function(jqXHR, textStatus, errorThrown) {
|
||||
try {
|
||||
var response = $.parseJSON(jqXHR.responseText);
|
||||
|
||||
if ('console' in window) console.log(response);
|
||||
|
||||
error_cb(response.error, this);
|
||||
} catch (err) {
|
||||
// Perhaps the responseText wasn't really a jsonrpc-error.
|
||||
error_cb({ error: jqXHR.responseText }, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Notify sends a command to the server that won't need a response. In http, there is probably
|
||||
* an empty response - that will be dropped, but in ws there should be no response at all.
|
||||
*
|
||||
* This is very similar to call, but has no id and no handling of callbacks.
|
||||
*
|
||||
* @fn notify
|
||||
* @memberof $.JsonRpcClient
|
||||
*
|
||||
* @param method The method to run on JSON-RPC server.
|
||||
* @param params The params; an array or object.
|
||||
*/
|
||||
$.JsonRpcClient.prototype.notify = function(method, params) {
|
||||
// Construct the JSON-RPC 2.0 request.
|
||||
|
||||
if (this.options.sessid) {
|
||||
params.sessid = this.options.sessid;
|
||||
}
|
||||
|
||||
var request = {
|
||||
jsonrpc: '2.0',
|
||||
method: method,
|
||||
params: params
|
||||
};
|
||||
|
||||
// Try making a WebSocket call.
|
||||
var socket = this.options.getSocket(this.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
this._wsCall(socket, request);
|
||||
return;
|
||||
}
|
||||
|
||||
// No WebSocket, and no HTTP backend? This won't work.
|
||||
if (this.options.ajaxUrl === null) {
|
||||
throw "$.JsonRpcClient.notify used with no websocket and no http endpoint.";
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : this.options.ajaxUrl,
|
||||
data : $.toJSON(request),
|
||||
dataType : 'json',
|
||||
cache : false
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a batch-call by using a callback.
|
||||
*
|
||||
* The callback will get an object "batch" as only argument. On batch, you can call the methods
|
||||
* "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be
|
||||
* sent as a batch call then the callback is done.
|
||||
*
|
||||
* @fn batch
|
||||
* @memberof $.JsonRpcClient
|
||||
*
|
||||
* @param callback The main function which will get a batch handler to run call and notify on.
|
||||
* @param all_done_cb A callback function to call after all results have been handled.
|
||||
* @param error_cb A callback function to call if there is an error from the server.
|
||||
* Note, that batch calls should always get an overall success, and the
|
||||
* only error
|
||||
*/
|
||||
$.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) {
|
||||
var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb);
|
||||
callback(batch);
|
||||
batch._execute();
|
||||
};
|
||||
|
||||
/**
|
||||
* The default getSocket handler.
|
||||
*
|
||||
* @param onmessage_cb The callback to be bound to onmessage events on the socket.
|
||||
*
|
||||
* @fn _getSocket
|
||||
* @memberof $.JsonRpcClient
|
||||
*/
|
||||
|
||||
$.JsonRpcClient.prototype.socketReady = function() {
|
||||
if (this._ws_socket === null || this._ws_socket.readyState > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$.JsonRpcClient.prototype.closeSocket = function() {
|
||||
var self = this;
|
||||
if (self.socketReady()) {
|
||||
self._ws_socket.onclose = function (w) {console.log("Closing Socket");};
|
||||
self._ws_socket.close();
|
||||
}
|
||||
};
|
||||
|
||||
$.JsonRpcClient.prototype.loginData = function(params) {
|
||||
var self = this;
|
||||
self.options.login = params.login;
|
||||
self.options.passwd = params.passwd;
|
||||
self.options.loginParams = params.loginParams;
|
||||
self.options.userVariables = params.userVariables;
|
||||
};
|
||||
|
||||
$.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) {
|
||||
var self = this;
|
||||
|
||||
if (self.to) {
|
||||
clearTimeout(self.to);
|
||||
}
|
||||
|
||||
if (!self.socketReady()) {
|
||||
self.authing = false;
|
||||
|
||||
if (self._ws_socket) {
|
||||
delete self._ws_socket;
|
||||
}
|
||||
|
||||
// No socket, or dying socket, let's get a new one.
|
||||
self._ws_socket = new WebSocket(self.options.socketUrl);
|
||||
|
||||
if (self._ws_socket) {
|
||||
// Set up onmessage handler.
|
||||
self._ws_socket.onmessage = onmessage_cb;
|
||||
self._ws_socket.onclose = function (w) {
|
||||
if (!self.ws_sleep) {
|
||||
self.ws_sleep = 1000;
|
||||
}
|
||||
|
||||
if (self.options.onWSClose) {
|
||||
self.options.onWSClose(self);
|
||||
}
|
||||
|
||||
console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec");
|
||||
|
||||
self.to = setTimeout(function() {
|
||||
console.log("Attempting Reconnection....");
|
||||
self.connectSocket(onmessage_cb);
|
||||
}, self.ws_sleep);
|
||||
|
||||
self.ws_cnt++;
|
||||
|
||||
if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) {
|
||||
self.ws_sleep += 1000;
|
||||
}
|
||||
};
|
||||
|
||||
// Set up sending of message for when the socket is open.
|
||||
self._ws_socket.onopen = function() {
|
||||
if (self.to) {
|
||||
clearTimeout(self.to);
|
||||
}
|
||||
self.ws_sleep = 1000;
|
||||
self.ws_cnt = 0;
|
||||
if (self.options.onWSConnect) {
|
||||
self.options.onWSConnect(self);
|
||||
}
|
||||
|
||||
var req;
|
||||
// Send the requests.
|
||||
while ((req = $.JsonRpcClient.q.pop())) {
|
||||
self._ws_socket.send(req);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return self._ws_socket ? true : false;
|
||||
};
|
||||
|
||||
$.JsonRpcClient.prototype._getSocket = function(onmessage_cb) {
|
||||
// If there is no ws url set, we don't have a socket.
|
||||
// Likewise, if there is no window.WebSocket.
|
||||
if (this.options.socketUrl === null || !("WebSocket" in window)) return null;
|
||||
|
||||
this.connectSocket(onmessage_cb);
|
||||
|
||||
return this._ws_socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Queue to save messages delivered when websocket is not ready
|
||||
*/
|
||||
$.JsonRpcClient.q = [];
|
||||
|
||||
/**
|
||||
* Internal handler to dispatch a JRON-RPC request through a websocket.
|
||||
*
|
||||
* @fn _wsCall
|
||||
* @memberof $.JsonRpcClient
|
||||
*/
|
||||
$.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) {
|
||||
var request_json = $.toJSON(request);
|
||||
|
||||
if (socket.readyState < 1) {
|
||||
// The websocket is not open yet; we have to set sending of the message in onopen.
|
||||
self = this; // In closure below, this is set to the WebSocket. Use self instead.
|
||||
$.JsonRpcClient.q.push(request_json);
|
||||
} else {
|
||||
// We have a socket and it should be ready to send on.
|
||||
socket.send(request_json);
|
||||
}
|
||||
|
||||
// Setup callbacks. If there is an id, this is a call and not a notify.
|
||||
if ('id' in request && typeof success_cb !== 'undefined') {
|
||||
this._ws_callbacks[request.id] = { request: request_json, request_obj: request, success_cb: success_cb, error_cb: error_cb };
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal handler for the websocket messages. It determines if the message is a JSON-RPC
|
||||
* response, and if so, tries to couple it with a given callback. Otherwise, it falls back to
|
||||
* given external onmessage-handler, if any.
|
||||
*
|
||||
* @param event The websocket onmessage-event.
|
||||
*/
|
||||
$.JsonRpcClient.prototype._wsOnMessage = function(event) {
|
||||
// Check if this could be a JSON RPC message.
|
||||
var response;
|
||||
|
||||
// Special sub proto
|
||||
if (event.data[0] == "#" && event.data[1] == "S" && event.data[2] == "P") {
|
||||
if (event.data[3] == "U") {
|
||||
this.up_dur = parseInt(event.data.substring(4));
|
||||
} else if (this.speedCB && event.data[3] == "D") {
|
||||
this.down_dur = parseInt(event.data.substring(4));
|
||||
|
||||
var up_kps = (((this.speedBytes * 8) / (this.up_dur / 1000)) / 1024).toFixed(0);
|
||||
var down_kps = (((this.speedBytes * 8) / (this.down_dur / 1000)) / 1024).toFixed(0);
|
||||
|
||||
console.info("Speed Test: Up: " + up_kps + " Down: " + down_kps);
|
||||
this.speedCB(event, { upDur: this.up_dur, downDur: this.down_dur, upKPS: up_kps, downKPS: down_kps });
|
||||
this.speedCB = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
response = $.parseJSON(event.data);
|
||||
|
||||
/// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends.
|
||||
|
||||
if (typeof response === 'object' &&
|
||||
'jsonrpc' in response &&
|
||||
response.jsonrpc === '2.0') {
|
||||
|
||||
/// @todo Handle bad response (without id).
|
||||
|
||||
// If this is an object with result, it is a response.
|
||||
if ('result' in response && this._ws_callbacks[response.id]) {
|
||||
// Get the success callback.
|
||||
var success_cb = this._ws_callbacks[response.id].success_cb;
|
||||
|
||||
/*
|
||||
// set the sessid if present
|
||||
if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) {
|
||||
this.options.sessid = response.result.sessid;
|
||||
if (this.options.sessid) {
|
||||
console.log("setting session UUID to: " + this.options.sessid);
|
||||
}
|
||||
}
|
||||
*/
|
||||
// Delete the callback from the storage.
|
||||
delete this._ws_callbacks[response.id];
|
||||
|
||||
// Run callback with result as parameter.
|
||||
success_cb(response.result, this);
|
||||
return;
|
||||
} else if ('error' in response && this._ws_callbacks[response.id]) {
|
||||
// If this is an object with error, it is an error response.
|
||||
|
||||
// Get the error callback.
|
||||
var error_cb = this._ws_callbacks[response.id].error_cb;
|
||||
var orig_req = this._ws_callbacks[response.id].request;
|
||||
|
||||
// if this is an auth request, send the credentials and resend the failed request
|
||||
if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) {
|
||||
self.authing = true;
|
||||
|
||||
this.call("login", { login: self.options.login, passwd: self.options.passwd, loginParams: self.options.loginParams,
|
||||
userVariables: self.options.userVariables},
|
||||
this._ws_callbacks[response.id].request_obj.method == "login" ?
|
||||
function(e) {
|
||||
self.authing = false;
|
||||
console.log("logged in");
|
||||
delete self._ws_callbacks[response.id];
|
||||
|
||||
if (self.options.onWSLogin) {
|
||||
self.options.onWSLogin(true, self);
|
||||
}
|
||||
}
|
||||
|
||||
:
|
||||
|
||||
function(e) {
|
||||
self.authing = false;
|
||||
console.log("logged in, resending request id: " + response.id);
|
||||
var socket = self.options.getSocket(self.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
socket.send(orig_req);
|
||||
}
|
||||
if (self.options.onWSLogin) {
|
||||
self.options.onWSLogin(true, self);
|
||||
}
|
||||
},
|
||||
|
||||
function(e) {
|
||||
console.log("error logging in, request id:", response.id);
|
||||
delete self._ws_callbacks[response.id];
|
||||
error_cb(response.error, this);
|
||||
if (self.options.onWSLogin) {
|
||||
self.options.onWSLogin(false, self);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the callback from the storage.
|
||||
delete this._ws_callbacks[response.id];
|
||||
|
||||
// Run callback with the error object as parameter.
|
||||
error_cb(response.error, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Probably an error while parsing a non json-string as json. All real JSON-RPC cases are
|
||||
// handled above, and the fallback method is called below.
|
||||
console.log("ERROR: "+ err);
|
||||
return;
|
||||
}
|
||||
|
||||
// This is not a JSON-RPC response. Call the fallback message handler, if given.
|
||||
if (typeof this.options.onmessage === 'function') {
|
||||
event.eventData = response;
|
||||
if (!event.eventData) {
|
||||
event.eventData = {};
|
||||
}
|
||||
|
||||
var reply = this.options.onmessage(event);
|
||||
|
||||
if (reply && typeof reply === "object" && event.eventData.id) {
|
||||
var msg = {
|
||||
jsonrpc: "2.0",
|
||||
id: event.eventData.id,
|
||||
result: reply
|
||||
};
|
||||
|
||||
var socket = self.options.getSocket(self.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
socket.send($.toJSON(msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* Batch object with methods
|
||||
************************************************************************************************/
|
||||
|
||||
/**
|
||||
* Handling object for batch calls.
|
||||
*/
|
||||
$.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) {
|
||||
// Array of objects to hold the call and notify requests. Each objects will have the request
|
||||
// object, and unless it is a notify, success_cb and error_cb.
|
||||
this._requests = [];
|
||||
|
||||
this.jsonrpcclient = jsonrpcclient;
|
||||
this.all_done_cb = all_done_cb;
|
||||
this.error_cb = typeof error_cb === 'function' ? error_cb : function() {};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @sa $.JsonRpcClient.prototype.call
|
||||
*/
|
||||
$.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) {
|
||||
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
if (this.options.sessid) {
|
||||
params.sessid = this.options.sessid;
|
||||
}
|
||||
|
||||
if (!success_cb) {
|
||||
success_cb = function(e){console.log("Success: ", e);};
|
||||
}
|
||||
|
||||
if (!error_cb) {
|
||||
error_cb = function(e){console.log("Error: ", e);};
|
||||
}
|
||||
|
||||
this._requests.push({
|
||||
request : {
|
||||
jsonrpc : '2.0',
|
||||
method : method,
|
||||
params : params,
|
||||
id : this.jsonrpcclient._current_id++ // Use the client's id series.
|
||||
},
|
||||
success_cb : success_cb,
|
||||
error_cb : error_cb
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @sa $.JsonRpcClient.prototype.notify
|
||||
*/
|
||||
$.JsonRpcClient._batchObject.prototype.notify = function(method, params) {
|
||||
if (this.options.sessid) {
|
||||
params.sessid = this.options.sessid;
|
||||
}
|
||||
|
||||
this._requests.push({
|
||||
request : {
|
||||
jsonrpc : '2.0',
|
||||
method : method,
|
||||
params : params
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the batched up calls.
|
||||
*/
|
||||
$.JsonRpcClient._batchObject.prototype._execute = function() {
|
||||
var self = this;
|
||||
|
||||
if (this._requests.length === 0) return; // All done :P
|
||||
|
||||
// Collect all request data and sort handlers by request id.
|
||||
var batch_request = [];
|
||||
var handlers = {};
|
||||
var i = 0;
|
||||
var call;
|
||||
var success_cb;
|
||||
var error_cb;
|
||||
|
||||
// If we have a WebSocket, just send the requests individually like normal calls.
|
||||
var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);
|
||||
if (socket !== null) {
|
||||
for (i = 0; i < this._requests.length; i++) {
|
||||
call = this._requests[i];
|
||||
success_cb = ('success_cb' in call) ? call.success_cb : undefined;
|
||||
error_cb = ('error_cb' in call) ? call.error_cb : undefined;
|
||||
self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb);
|
||||
}
|
||||
|
||||
if (typeof all_done_cb === 'function') all_done_cb(result);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < this._requests.length; i++) {
|
||||
call = this._requests[i];
|
||||
batch_request.push(call.request);
|
||||
|
||||
// If the request has an id, it should handle returns (otherwise it's a notify).
|
||||
if ('id' in call.request) {
|
||||
handlers[call.request.id] = {
|
||||
success_cb : call.success_cb,
|
||||
error_cb : call.error_cb
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); };
|
||||
|
||||
// No WebSocket, and no HTTP backend? This won't work.
|
||||
if (self.jsonrpcclient.options.ajaxUrl === null) {
|
||||
throw "$.JsonRpcClient.batch used with no websocket and no http endpoint.";
|
||||
}
|
||||
|
||||
// Send request
|
||||
$.ajax({
|
||||
url : self.jsonrpcclient.options.ajaxUrl,
|
||||
data : $.toJSON(batch_request),
|
||||
dataType : 'json',
|
||||
cache : false,
|
||||
type : 'POST',
|
||||
|
||||
// Batch-requests should always return 200
|
||||
error : function(jqXHR, textStatus, errorThrown) {
|
||||
self.error_cb(jqXHR, textStatus, errorThrown);
|
||||
},
|
||||
success : success_cb
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal helper to match the result array from a batch call to their respective callbacks.
|
||||
*
|
||||
* @fn _batchCb
|
||||
* @memberof $.JsonRpcClient
|
||||
*/
|
||||
$.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) {
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var response = result[i];
|
||||
|
||||
// Handle error
|
||||
if ('error' in response) {
|
||||
if (response.id === null || !(response.id in handlers)) {
|
||||
// An error on a notify? Just log it to the console.
|
||||
if ('console' in window) console.log(response);
|
||||
} else {
|
||||
handlers[response.id].error_cb(response.error, this);
|
||||
}
|
||||
} else {
|
||||
// Here we should always have a correct id and no error.
|
||||
if (!(response.id in handlers) && 'console' in window) {
|
||||
console.log(response);
|
||||
} else {
|
||||
handlers[response.id].success_cb(response.result, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof all_done_cb === 'function') all_done_cb(result);
|
||||
};
|
||||
|
||||
})(jQuery);
|
File diff suppressed because it is too large
Load Diff
@ -1,455 +0,0 @@
|
||||
this.callback = function(message){console.log(message);}; // holds the user's callback for a global scope
|
||||
this.callbacks = {};
|
||||
this.callICEConnected = false;
|
||||
this.callPurposefullyEnded = false; // used to determine whether the user ended the call or the call was ended from somewhere else outside
|
||||
this.callTimeout = null; // function that will run if there is no call established
|
||||
this.conferenceIdNumber = "1008";
|
||||
this.conferenceUsername = "FreeSWITCH User";
|
||||
this.toDisplayDisconnectCallback = true; // if a call is dropped only display the error the first time
|
||||
this.wasCallSuccessful = false; // when the websocket connection is closed this determines whether a call was ever successfully established
|
||||
this.webcamStream = "webcamStream";
|
||||
window[webcamStream] = null;
|
||||
this.verto = null;
|
||||
this.videoTag = null;
|
||||
|
||||
// save a copy of the hangup function registered for the verto object
|
||||
var oldHangup = $.verto.prototype.hangup;
|
||||
// overwrite the verto hangup handler with my own handler
|
||||
$.verto.prototype.hangup = function(callID, userCallback) {
|
||||
if (userCallback) {
|
||||
callback = userCallback;
|
||||
}
|
||||
callActive = false;
|
||||
|
||||
if (cur_call) {
|
||||
console.log('call ended ' + cur_call.audioStream.currentTime); // the duration of the call
|
||||
if (callPurposefullyEnded === true) { // the user ended the call themself
|
||||
callback({'status':'ended'});
|
||||
} else {
|
||||
callback({'status':'failed', 'errorcode': 1005}); // Call ended unexpectedly
|
||||
}
|
||||
clearTimeout(callTimeout);
|
||||
cur_call = null;
|
||||
} else {
|
||||
console.log('bye event already received');
|
||||
}
|
||||
// call the original hangup procedure
|
||||
return oldHangup.apply(this, arguments);
|
||||
}
|
||||
|
||||
// main entry point to making a verto call
|
||||
this.callIntoConference_verto = function(voiceBridge, conferenceUsername, conferenceIdNumber, userCallback, videoTag, options) {
|
||||
window.videoTag = videoTag;
|
||||
// stores the user's callback in the global scope
|
||||
if (userCallback) {
|
||||
callback = userCallback;
|
||||
}
|
||||
if(!isLoggedIntoVerto()) { // start the verto log in procedure
|
||||
// runs when a web socket is disconnected
|
||||
callbacks.onWSClose = function(v, success) {
|
||||
if(wasCallSuccessful) { // a call was established through the websocket
|
||||
if(toDisplayDisconnectCallback) { // will only display the error the first time
|
||||
// the connection was dropped in an already established call
|
||||
console.log("websocket disconnected");
|
||||
callback({'status':'failed', 'errorcode': 1001}); // WebSocket disconnected
|
||||
toDisplayDisconnectCallback = false;
|
||||
}
|
||||
} else {
|
||||
// this callback was triggered and a call was never successfully established
|
||||
console.log("websocket connection could not be established");
|
||||
callback({'status':'failed', 'errorcode': 1002}); // Could not make a WebSocket connection
|
||||
}
|
||||
}
|
||||
// runs when the websocket is successfully created
|
||||
callbacks.onWSLogin = function(v, success) {
|
||||
cur_call = null;
|
||||
ringing = false;
|
||||
console.log("Inside onWSLogin");
|
||||
|
||||
if (success) {
|
||||
console.log("starting call");
|
||||
toDisplayDisconnectCallback = true; // yes, display an error if the socket closes
|
||||
wasCallSuccessful = true; // yes, a call was successfully established through the websocket
|
||||
webrtc_call_verto(voiceBridge, conferenceUsername, conferenceIdNumber, callback, options);
|
||||
} else {
|
||||
callback({'status':'failed', 'errorcode': '10XX'}); // eror logging verto into freeswitch
|
||||
}
|
||||
}
|
||||
// set up verto
|
||||
// $.verto.init({}, init(videoTag));
|
||||
init(videoTag);
|
||||
} else {
|
||||
console.log("already logged into verto, going straight to making a call");
|
||||
webrtc_call_verto(voiceBridge, conferenceUsername, conferenceIdNumber, callback, options);
|
||||
}
|
||||
}
|
||||
|
||||
this.checkSupport = function(callback) {
|
||||
if(!isWebRTCAvailable_verto()) {
|
||||
callback({'status': 'failed', 'errorcode': 1003}); // Browser version not supported
|
||||
}
|
||||
|
||||
if (!navigator.getUserMedia) {
|
||||
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||
}
|
||||
|
||||
if (!navigator.getUserMedia){
|
||||
callback({'status': 'failed', 'errorcode': '10XX'}); // getUserMedia not supported in this browser
|
||||
}
|
||||
}
|
||||
|
||||
this.configStuns = function(callbacks, callback, videoTag) {
|
||||
console.log("Fetching STUN/TURN server info for Verto initialization");
|
||||
var stunsConfig = {};
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
url: '/bigbluebutton/api/stuns/'
|
||||
}).done(function(data) {
|
||||
console.log("ajax request done");
|
||||
console.log(data);
|
||||
if(data['response'] && data.response.returncode == "FAILED") {
|
||||
console.error(data.response.message);
|
||||
callback({'status':'failed', 'errorcode': data.response.message});
|
||||
return;
|
||||
}
|
||||
stunsConfig['stunServers'] = ( data['stunServers'] ? data['stunServers'].map(function(data) {
|
||||
return {'url': data['url']};
|
||||
}) : [] );
|
||||
stunsConfig['turnServers'] = ( data['turnServers'] ? data['turnServers'].map(function(data) {
|
||||
return {
|
||||
'urls': data['url'],
|
||||
'username': data['username'],
|
||||
'credential': data['password']
|
||||
};
|
||||
}) : [] );
|
||||
stunsConfig = stunsConfig['stunServers'].concat(stunsConfig['turnServers']);
|
||||
console.log("success got stun data, making verto");
|
||||
makeVerto(callbacks, stunsConfig, videoTag);
|
||||
}).fail(function(data, textStatus, errorThrown) {
|
||||
// BBBLog.error("Could not fetch stun/turn servers", {error: textStatus, user: callerIdName, voiceBridge: conferenceVoiceBridge});
|
||||
callback({'status':'failed', 'errorcode': 1009});
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
this.docall_verto = function(extension, conferenceUsername, conferenceIdNumber, callbacks, options) {
|
||||
console.log(extension + ", " + conferenceUsername + ", " + conferenceIdNumber);
|
||||
|
||||
if (cur_call) { // only allow for one call
|
||||
console.log("Quitting: Call already in progress");
|
||||
return;
|
||||
}
|
||||
// determine the resolution the user chose for webcam video
|
||||
my_check_vid_res();
|
||||
outgoingBandwidth = "default";
|
||||
incomingBandwidth = "default";
|
||||
var useVideo = useCamera = useMic = false;
|
||||
|
||||
if(options.watchOnly) {
|
||||
window.watchOnly = true;
|
||||
window.listenOnly = false;
|
||||
window.joinAudio = false;
|
||||
useVideo = true;
|
||||
useCamera = false;
|
||||
useMic = false;
|
||||
} else if(options.listenOnly) {
|
||||
window.listenOnly = true;
|
||||
window.watchOnly = false;
|
||||
window.joinAudio = false;
|
||||
useVideo = false;
|
||||
useCamera = false;
|
||||
useMic = false;
|
||||
} else if(options.joinAudio) {
|
||||
window.joinAudio = true;
|
||||
window.watchOnly = false;
|
||||
window.listenOnly = false;
|
||||
useVideo = false;
|
||||
useCamera = false;
|
||||
useMic = true;
|
||||
}
|
||||
|
||||
cur_call = verto.newCall({
|
||||
destination_number: extension,
|
||||
caller_id_name: conferenceUsername,
|
||||
caller_id_number: conferenceIdNumber,
|
||||
outgoingBandwidth: outgoingBandwidth,
|
||||
incomingBandwidth: incomingBandwidth,
|
||||
useStereo: true,
|
||||
useVideo: useVideo,
|
||||
useCamera: useCamera,
|
||||
useMic: useMic,
|
||||
dedEnc: false,
|
||||
mirrorInput: false
|
||||
});
|
||||
|
||||
if (callbacks != null) { // add user supplied callbacks to the current call
|
||||
cur_call.rtc.options.callbacks = $.extend(cur_call.rtc.options.callbacks, callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
// retrieves the camera resolution the user selected
|
||||
// displays a local feed of the user's webcam
|
||||
this.doWebcamPreview = function(onSuccess, onFailure, videoTag) {
|
||||
var selectedVideoConstraints = getChosenWebcamResolution(); // this is the video profile the user chose
|
||||
selectedVideoConstraints = getWebcamConstraintsFromResolution(selectedVideoConstraints); // convert to a valid constraints object
|
||||
console.log("screen constraints", selectedVideoConstraints)
|
||||
previewLocalMedia(webcamStream, selectedVideoConstraints, videoTag, onSuccess, onFailure);
|
||||
window.videoTag = videoTag;
|
||||
my_real_size()
|
||||
}
|
||||
|
||||
// return the webcam resolution that the user has selected
|
||||
this.getChosenWebcamResolution = function() {
|
||||
var videoConstraints = getAllPresetVideoResolutions(); // retrieve all resolutions
|
||||
var selectedVideo = null;
|
||||
for(var i in videoConstraints) {
|
||||
selectedVideo = videoConstraints[i];
|
||||
if($("#webcamQuality_"+i).is(':checked')) { // compare against all resolutions
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectedVideo;
|
||||
}
|
||||
|
||||
// receives a video resolution profile, and converts it into a constraints format for getUserMedia
|
||||
this.getWebcamConstraintsFromResolution = function(resolution) {
|
||||
return {
|
||||
"audio": false,
|
||||
"video": {
|
||||
"mandatory": {
|
||||
"minWidth": resolution.constraints.minWidth,
|
||||
"maxWidth": resolution.constraints.maxWidth,
|
||||
"minHeight": resolution.constraints.minHeight,
|
||||
"maxHeight": resolution.constraints.maxHeight,
|
||||
"minFrameRate": resolution.constraints.minFrameRate
|
||||
},
|
||||
"optional": []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// check if logged into verto by seeing if there is a ready websocket connection
|
||||
this.isLoggedIntoVerto = function () {
|
||||
return (verto != null ? (ref = verto.rpcClient) != null ? ref.socketReady() : void 0 : void 0);
|
||||
}
|
||||
|
||||
// overwrite and substitute my own init function
|
||||
this.init = function(videoTag) {
|
||||
videoTag = window.videoTag;
|
||||
cur_call = null;
|
||||
share_call = null;
|
||||
incomingBandwidth = "default";
|
||||
configStuns(callbacks, callback, videoTag);
|
||||
}
|
||||
|
||||
// checks whether Google Chrome or Firefox have the WebRTCPeerConnection object
|
||||
this.isWebRTCAvailable_verto = function () {
|
||||
return (typeof window.webkitRTCPeerConnection !== 'undefined' || typeof window.mozRTCPeerConnection !== 'undefined');
|
||||
}
|
||||
|
||||
// exit point for conference
|
||||
this.leaveWebRTCVoiceConference_verto = function() {
|
||||
console.log("Leaving the voice conference");
|
||||
webrtc_hangup_verto();
|
||||
}
|
||||
|
||||
this.make_call_verto = function(voiceBridge, conferenceUsername, conferenceIdNumber, userCallback, server, recall, options) {
|
||||
if (userCallback) {
|
||||
callback = userCallback;
|
||||
}
|
||||
callPurposefullyEnded = false;
|
||||
|
||||
// after 15 seconds if a call hasn't been established display error, hangup and logout of verto
|
||||
callTimeout = setTimeout(function() {
|
||||
console.log('Ten seconds without updates sending timeout code');
|
||||
callback({'status':'failed', 'errorcode': 1006}); // Failure on call
|
||||
if (verto != null) {
|
||||
verto.hangup();
|
||||
verto.logout();
|
||||
verto = null;
|
||||
}
|
||||
cur_call = null;
|
||||
}, 10000*1.5);
|
||||
|
||||
var myRTCCallbacks = {
|
||||
onError: function(vertoErrorObject, errorMessage) {
|
||||
console.error("custom callback: onError");
|
||||
console.error(vertoErrorObject);
|
||||
console.error("ERROR:");
|
||||
console.error(errorMessage);
|
||||
if(errorMessage.name === "PermissionDeniedError") { // user denied access to media peripherals
|
||||
console.error("User denied permission/access to hardware");
|
||||
console.error("getUserMedia: failure - ", errorMessage);
|
||||
callback({'status': 'mediafail', 'cause': errorMessage});
|
||||
}
|
||||
cur_call.hangup({cause: "Device or Permission Error"});
|
||||
clearTimeout(callTimeout);
|
||||
},
|
||||
onICEComplete: function(self, candidate) { // ICE candidate negotiation is complete
|
||||
console.log("custom callback: onICEComplete");
|
||||
console.log('Received ICE status changed to completed');
|
||||
if (callICEConnected === false) {
|
||||
callICEConnected = true;
|
||||
if (callActive === true) {
|
||||
callback({'status':'started'});
|
||||
}
|
||||
clearTimeout(callTimeout);
|
||||
}
|
||||
},
|
||||
onStream: function(rtc, stream) { // call has been established
|
||||
console.log("getUserMicMedia: success");
|
||||
callback({'status':'mediasuccess'});
|
||||
console.log("custom callback: stream started");
|
||||
callActive = true;
|
||||
console.log('BigBlueButton call accepted');
|
||||
|
||||
if (callICEConnected === true) {
|
||||
callback({'status':'started'});
|
||||
} else {
|
||||
callback({'status':'waitingforice'});
|
||||
}
|
||||
clearTimeout(callTimeout);
|
||||
}
|
||||
};
|
||||
|
||||
if(isLoggedIntoVerto()) {
|
||||
console.log("Verto is logged into FreeSWITCH, socket is available, making call");
|
||||
callICEConnected = false;
|
||||
|
||||
docall_verto(voiceBridge, conferenceUsername, conferenceIdNumber, myRTCCallbacks, options);
|
||||
|
||||
if(recall === false) {
|
||||
console.log('call connecting');
|
||||
callback({'status': 'connecting'});
|
||||
} else {
|
||||
console.log('call connecting again');
|
||||
}
|
||||
|
||||
callback({'status':'mediarequest'});
|
||||
} else {
|
||||
console.error("Verto is NOT logged into FreeSWITCH, socket is NOT available, abandoning call request");
|
||||
}
|
||||
}
|
||||
|
||||
this.makeVerto = function(callbacks, stunsConfig, videoTag) {
|
||||
var vertoPort = "8082";
|
||||
var hostName = Meteor.config.vertoServerAddress;
|
||||
var socketUrl = "wss://" + hostName + ":" + vertoPort;
|
||||
var login = "1008";
|
||||
var password = Meteor.config.freeswitchProfilePassword;
|
||||
var minWidth = "320";
|
||||
var minHeight = "180";
|
||||
var maxWidth = "320";
|
||||
var maxHeight = "180";
|
||||
|
||||
console.log("stuns info is");
|
||||
console.log(stunsConfig);
|
||||
|
||||
// create verto object and log in
|
||||
verto = new $.verto({
|
||||
login: login,
|
||||
passwd: password,
|
||||
socketUrl: socketUrl,
|
||||
tag: videoTag,
|
||||
ringFile: "sounds/bell_ring2.wav",
|
||||
loginParams: {foo: true, bar: "yes"},
|
||||
useVideo: false,
|
||||
useCamera: false,
|
||||
iceServers: stunsConfig, // use user supplied stun configuration
|
||||
// iceServers: true, // use stun, use default verto configuration
|
||||
}, callbacks);
|
||||
}
|
||||
|
||||
// sets verto to begin using the resolution that the user selected
|
||||
this.my_check_vid_res = function() {
|
||||
var selectedVideoConstraints = getChosenWebcamResolution();
|
||||
my_real_size(selectedVideoConstraints);
|
||||
|
||||
if (verto) {
|
||||
verto.videoParams({
|
||||
"minWidth": selectedVideoConstraints.constraints.minWidth,
|
||||
"minHeight": selectedVideoConstraints.constraints.minHeight,
|
||||
"maxWidth": selectedVideoConstraints.constraints.maxWidth,
|
||||
"maxHeight": selectedVideoConstraints.constraints.maxHeight,
|
||||
"minFrameRate": selectedVideoConstraints.constraints.minFrameRate,
|
||||
"vertoBestFrameRate": selectedVideoConstraints.constraints.vertoBestFrameRate
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.my_real_size = function(selectedVideoConstraints) {
|
||||
$("#" + window.videoTag).height("100%");
|
||||
$("#" + window.videoTag).width("100%");
|
||||
}
|
||||
|
||||
/*
|
||||
receives the handle to the global resource representing the video feed
|
||||
receives media constraints to request access to
|
||||
receives videoTag representing where the media (if any) should be rendered
|
||||
receives callbacks for success and failure
|
||||
*/
|
||||
this.previewLocalMedia = function(streamHandle, videoConstraints, videoTag, onSuccess, onFailure) {
|
||||
if(!!window[streamHandle]) {
|
||||
$("#" + videoTag).src = null;
|
||||
window[streamHandle].stop();
|
||||
}
|
||||
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||
navigator.getUserMedia(videoConstraints, function(stream) {
|
||||
window[streamHandle] = stream;
|
||||
$("#" + videoTag).get(0).src = URL.createObjectURL(stream);
|
||||
$("#" + videoTag).get(0).play();
|
||||
$("#" + videoTag).show();
|
||||
return onSuccess(stream);
|
||||
}, function(error) {
|
||||
return onFailure(error);
|
||||
});
|
||||
}
|
||||
|
||||
var RTCPeerConnectionCallbacks = {
|
||||
iceFailed: function(e) {
|
||||
console.log('Received ICE negotiation failed');
|
||||
callback({'status':'failed', 'errorcode': 1007}); // Failure on call
|
||||
cur_call = null;
|
||||
verto.hangup();
|
||||
verto = null;
|
||||
clearTimeout(callTimeout);
|
||||
}
|
||||
};
|
||||
this.RTCPeerConnectionCallbacks = RTCPeerConnectionCallbacks;
|
||||
|
||||
this.verto_onStreamCallback = function(self, stream) {
|
||||
clearTimeout(callTimeout);
|
||||
}
|
||||
|
||||
this.verto_afterStreamPublish = function() {
|
||||
console.log("Video stream published - notifying clients to subscribe");
|
||||
notification_ScreenShared();
|
||||
//return simulatePresenterDeskshareHasStarted();
|
||||
}
|
||||
|
||||
this.webrtc_call_verto = function(voiceBridge, conferenceUsername, conferenceIdNumber, userCallback, options) {
|
||||
if (userCallback) {
|
||||
callback = userCallback;
|
||||
}
|
||||
console.log("webrtc_call\n"+voiceBridge + ", " + conferenceUsername + ", " + conferenceIdNumber + ", " + callback);
|
||||
|
||||
if(!isWebRTCAvailable()) {
|
||||
callback({'status': 'failed', 'errorcode': 1003}); // Browser version not supported
|
||||
return;
|
||||
}
|
||||
|
||||
var server = window.document.location.hostname;
|
||||
console.log("user " + conferenceUsername + " calling to " + voiceBridge);
|
||||
if (isLoggedIntoVerto()) {
|
||||
make_call_verto(voiceBridge, conferenceUsername, conferenceIdNumber, callback, "", false, options);
|
||||
}
|
||||
}
|
||||
|
||||
this.webrtc_hangup_verto = function(userCallback) {
|
||||
if (userCallback) {
|
||||
callback = userCallback;
|
||||
}
|
||||
callPurposefullyEnded = true;
|
||||
console.log("Hanging up current session");
|
||||
verto.hangup(false, callback);
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
var deskshareStream = "deskshareStream";
|
||||
window[deskshareStream] = null;
|
||||
this.share_call = null;
|
||||
|
||||
this.doshare = function(on, callback, videoTag) {
|
||||
if (!on) {
|
||||
if (share_call) {
|
||||
share_call.hangup();
|
||||
share_call = null;
|
||||
setInSession("sharingMyScreen", false)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (share_call) {
|
||||
return;
|
||||
}
|
||||
|
||||
outgoingBandwidth = incomingBandwidth = "default";
|
||||
var sharedev = "screen";
|
||||
|
||||
if (sharedev !== "screen") {
|
||||
console.log("Attempting Screen Capture with non-screen device....");
|
||||
BBB.getMyUserInfo(function (retData){
|
||||
share_call = verto.newCall({
|
||||
destination_number: retData.voiceBridge + "-screen",
|
||||
caller_id_name: retData.myUsername + " (Screen)",
|
||||
caller_id_number: retData.myUserID + " (screen)",
|
||||
outgoingBandwidth: outgoingBandwidth,
|
||||
incomingBandwidth: incomingBandwidth,
|
||||
useCamera: sharedev,
|
||||
useVideo: true,
|
||||
screenShare: true,
|
||||
dedEnc: false,
|
||||
mirrorInput: false
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var callbacks = {
|
||||
onError: function(vertoErrorObject, errorMessage) {
|
||||
console.error("custom callback: onError");
|
||||
setInSession("sharingMyScreen", false)
|
||||
},
|
||||
onICEComplete: function(self, candidate) { // ICE candidate negotiation is complete
|
||||
console.log("custom callback: onICEComplete");
|
||||
setInSession("sharingMyScreen", true)
|
||||
}
|
||||
};
|
||||
|
||||
if (!!navigator.mozGetUserMedia) {
|
||||
var selectedDeskshareResolution = getChosenDeskshareResolution(); // this is the video profile the user chose
|
||||
my_real_size(selectedDeskshareResolution);
|
||||
var screen_constraints = {
|
||||
"mozMediaSource": 'window',
|
||||
"mediaSource": 'window',
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
frameRate : {min: 15, max: 30}
|
||||
};
|
||||
|
||||
window.listenOnly = false;
|
||||
window.watchOnly = false;
|
||||
window.joinAudio = true;
|
||||
|
||||
BBB.getMyUserInfo(function (retData){
|
||||
share_call = verto.newCall({
|
||||
destination_number: retData.voiceBridge + "-screen",
|
||||
caller_id_name: retData.myUsername + " (Screen)",
|
||||
caller_id_number: retData.myUserID + " (screen)",
|
||||
outgoingBandwidth: outgoingBandwidth,
|
||||
incomingBandwidth: incomingBandwidth,
|
||||
videoParams: screen_constraints,
|
||||
useVideo: true,
|
||||
screenShare: true,
|
||||
dedEnc: false,
|
||||
mirrorInput: false,
|
||||
tag: "webcam"
|
||||
});
|
||||
});
|
||||
|
||||
share_call.rtc.options.callbacks = $.extend(share_call.rtc.options.callbacks, callbacks);
|
||||
} else {
|
||||
getChromeExtensionStatus( function(status) {
|
||||
getScreenConstraints(function(error, screen_constraints) {
|
||||
if(error) {
|
||||
return console.error(error);
|
||||
}
|
||||
|
||||
console.log('screen_constraints', screen_constraints);
|
||||
var selectedDeskshareResolution = getChosenDeskshareResolution(); // this is the video profile the user chose
|
||||
my_real_size(selectedDeskshareResolution);
|
||||
var selectedDeskshareConstraints = getDeskshareConstraintsFromResolution(selectedDeskshareResolution, screen_constraints); // convert to a valid constraints object
|
||||
console.log(selectedDeskshareConstraints);
|
||||
|
||||
window.listenOnly = false;
|
||||
window.watchOnly = false;
|
||||
window.joinAudio = true;
|
||||
|
||||
share_call = verto.newCall({
|
||||
destination_number: extension + "-screen",
|
||||
caller_id_name: conferenceUsername + " (Screen)",
|
||||
caller_id_number: conferenceIdNumber + " (screen)",
|
||||
outgoingBandwidth: outgoingBandwidth,
|
||||
incomingBandwidth: incomingBandwidth,
|
||||
videoParams: selectedDeskshareConstraints.video.mandatory,
|
||||
useVideo: true,
|
||||
screenShare: true,
|
||||
dedEnc: false,
|
||||
mirrorInput: false,
|
||||
tag: videoTag
|
||||
});
|
||||
|
||||
share_call.rtc.options.callbacks = $.extend(share_call.rtc.options.callbacks, callbacks);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.doDesksharePreview = function(onSuccess, onFailure, videoTag) {
|
||||
// Firefox
|
||||
if (!!navigator.mozGetUserMedia) {
|
||||
var selectedDeskshareResolution = getChosenDeskshareResolution(); // this is the video profile the user chose
|
||||
my_real_size(selectedDeskshareResolution);
|
||||
var selectedDeskshareConstraints = {
|
||||
video: {
|
||||
mediaSource: "window", // window, screen
|
||||
mozMediaSource: "window",
|
||||
mandatory: {
|
||||
maxWidth: 0,
|
||||
maxHeight: 0,
|
||||
frameRate : {min: 10, max: 10}
|
||||
}
|
||||
},
|
||||
audio: false
|
||||
};
|
||||
previewLocalMedia(deskshareStream, selectedDeskshareConstraints, videoTag, onSuccess, onFailure);
|
||||
} else if(!!window.chrome) {
|
||||
getChromeExtensionStatus(function(status) {
|
||||
sourceId = null;
|
||||
getScreenConstraints(function(error, screen_constraints) {
|
||||
if(error) {
|
||||
return console.error(error);
|
||||
}
|
||||
|
||||
console.log('screen_constraints', screen_constraints);
|
||||
var selectedDeskshareResolution = getChosenDeskshareResolution(); // this is the video profile the user chose
|
||||
my_real_size(selectedDeskshareResolution);
|
||||
var selectedDeskshareConstraints = getDeskshareConstraintsFromResolution(selectedDeskshareResolution, screen_constraints); // convert to a valid constraints object
|
||||
console.log(selectedDeskshareConstraints);
|
||||
previewLocalMedia(deskshareStream, selectedDeskshareConstraints, videoTag, onSuccess, onFailure);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// return the webcam resolution that the user has selected
|
||||
this.getChosenDeskshareResolution = function() {
|
||||
var videoConstraints = getAllPresetVideoResolutions(); // retrieve all resolutions
|
||||
var selectedVideo = videoConstraints[$("#deskshareResolutions").find(":selected").val()];
|
||||
return selectedVideo;
|
||||
}
|
||||
|
||||
// receives a video resolution profile, and converts it into a constraints format for getUserMedia
|
||||
this.getDeskshareConstraintsFromResolution = function(resolution, constraints) {
|
||||
return {
|
||||
"audio": false,
|
||||
"video": {
|
||||
"mandatory": {
|
||||
"maxWidth": resolution.constraints.maxWidth,
|
||||
"maxHeight": resolution.constraints.maxHeight,
|
||||
"chromeMediaSource": constraints.mandatory.chromeMediaSource,
|
||||
"chromeMediaSourceId": constraints.mandatory.chromeMediaSourceId,
|
||||
"minFrameRate": resolution.constraints.minFrameRate
|
||||
},
|
||||
"optional": []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.screenStart = function(state, callback, videoTag) {
|
||||
window.videoTag = videoTag;
|
||||
if (state) {
|
||||
if(!isLoggedIntoVerto()) { // start the verto log in procedure
|
||||
// runs when the websocket is successfully created
|
||||
callbacks.onWSLogin = function(v, success) {
|
||||
doshare(state, callback, videoTag);
|
||||
callback({'status':'success', 'message': 'screenshare started'});
|
||||
console.log("Logged in with verto. Starting screenshare");
|
||||
}
|
||||
// set up verto
|
||||
// $.verto.init({}, init);
|
||||
init(window.videoTag);
|
||||
} else {
|
||||
console.log("Already logged into verto, going straight to making a call");
|
||||
doshare(state, callback, videoTag);
|
||||
callback({'status':'success', 'message': 'screenshare started'});
|
||||
}
|
||||
} else {
|
||||
doshare(state, callback, videoTag);
|
||||
callback({'status':'success', 'message': 'screenshare ended'});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user