var Janus = require('../externals/janus.nojquery');
var Promise = require('bluebird/js/release/bluebird');
/**
* EchoTest usecase
* @class
* @classdesc EchoTest usecase
* @param {object} onEvents Event handlers: onConnected, onSlowLink
* @param {object} domElements DOM elements: local, remote
* @param {object} options Available options: muteRemoteAudio
* @return {Promise} EchoTest methods: getCurrentBitrate, launchConnection, closeUsecase
* @example
* var onEvents = {
* onConnected: function() {
* // Connected
* },
* onSlowLink: function(uplink, nacks) {
* // Slow link detected
* }
* };
*
* var domElements = {
* local: document.getElementById('localVideo'),
* remote: document.getElementById('remoteVideo')
* };
*
* var options = {
* stream: {
* muteRemoteAudio: true
* }
* };
*
* usecases.echoTest(onEvents, domElements, options)
* .then(function(action) {
* // Use Case has been atacched succesfully
* ...
* })
* .catch(function(cause) {
* // Error attaching the Use Case
* console.log("Error Attach " + cause );
* })
*/
var echoTest = function(onEvents, domElements, options) {
if(!domElements || !domElements.local || !domElements.remote || domElements.local.nodeType !== 1 || domElements.remote.nodeType !== 1) return null;
var muteRemoteAudio = (options && options.stream && options.stream.muteRemoteAudio) ? options.stream.muteRemoteAudio : false;
var echoTestHandle = null;
/**
* Close the current UseCase. It's recommended combine with disconnect method
* @return {nothing}
* @example
* action.closeUsecase();
* myVideoApp.disconnect(); // Recommended
*/
var closeUsecase = function() {
if(domElements) {
for (var element in domElements) {
if (!domElements.hasOwnProperty(element)) continue;
var obj = domElements[element];
if(obj && obj.innerHTML) obj.innerHTML = '';
}
}
};
/**
* Gets the current Bitrate between the Peer and the VideoGateway. You need to call the launchConnection first.
* @return {integer} Number of kbits/sec
* @example
* action.getCurrentBitrate();
*/
var getCurrentBitrate = function() {
return parseInt(echoTestHandle.getBitrate().split(' ')[0]);
};
/**
* Establish a connection between the peer and the VideoGateway.
* @return {nothing}
* @example
* action.launchConnection();
*/
var launchConnection = function() {
// Negotiate WebRTC
var body = { "audio": true, "video": true};
console.log(body);
echoTestHandle.send({"message": body});
Janus.debug("Trying a createOffer too (audio/video sendrecv)");
echoTestHandle.createOffer(
{
media: { data: true },
success: function(jsep) {
echoTestHandle.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
}
});
};
return new Promise(function (resolve, reject) {
window.VideoRTC.connection.handle.attach({
plugin: "janus.plugin.echotest",
success: function(pluginHandle) {
echoTestHandle = pluginHandle;
resolve({
getCurrentBitrate: getCurrentBitrate,
launchConnection: launchConnection,
closeUsecase: closeUsecase
});
},
error: function(cause) {
Janus.error(" -- Error attaching plugin...", cause);
reject(cause);
},
consentDialog: function(on) {
// Nothing
},
iceState: function(state) {
Janus.debug("ICE state changed to " + state);
},
mediaState: function(medium, on) {
Janus.debug("VideoGateway " + (on ? "started" : "stopped") + " receiving our " + medium);
},
webrtcState: function(on) {
Janus.debug("VideoGateway says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
},
slowLink: function(uplink, nacks) {
Janus.debug("VideoGateway reports problems " + (uplink ? "sending" : "receiving") + " packets on this PeerConnection (" + nacks + " NACKs/s " + (uplink ? "received" : "sent") + ")");
if(onEvents && onEvents.onSlowLink) onEvents.onSlowLink(uplink, nacks);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message :::");
Janus.debug(JSON.stringify(msg));
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
echoTestHandle.handleRemoteJsep({jsep: jsep});
}
var result = msg["result"];
if(result !== null && result !== undefined) {
if(result === "done") {
// The plugin closed the echo test
Janus.debug("The Echo Test is over");
}
}
},
onlocalstream: function(stream) {
// Local Video
if(!domElements.local) return false;
var container = domElements.local;
var newNode = document.createElement('div');
newNode.id = 'video-local-container';
newNode.className = 'videortc-video-container';
newNode.innerHTML = '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="video-local"></video>';
container.insertBefore(newNode, container.firstChild);
var videoElem = document.getElementById('video-local');
Janus.attachMediaStream(videoElem, stream);
videoElem.muted = true;
var videoTracks = stream.getVideoTracks();
if (videoTracks === null || videoTracks === undefined || videoTracks.length === 0) {
// No remote video
var nodeNoCamera = document.createElement('div');
nodeNoCamera.innerHTML = 'No camera available';
nodeNoCamera.style.position = "relative";
nodeNoCamera.style.height = "100%";
nodeNoCamera.style.width = "100%";
nodeNoCamera.style.top = "100%";
nodeNoCamera.style.left = "50%";
nodeNoCamera.style.transform = "translate(-50%,-50%)";
nodeNoCamera.className = "no-camera-available";
newNode.insertBefore(nodeNoCamera, newNode.firstChild);
}
},
onremotestream: function(stream) {
// Remote Video
if(!domElements.remote) return false;
var container = domElements.remote;
var newNode = document.createElement('div');
newNode.id = 'video-remote-container';
newNode.className = 'videortc-video-container';
newNode.innerHTML = '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="video-remote"></video>';
container.insertBefore(newNode, container.firstChild);
var videoElem = document.getElementById('video-remote');
Janus.attachMediaStream(videoElem, stream);
if(muteRemoteAudio) videoElem.muted = true;
var videoTracks = stream.getVideoTracks();
if (videoTracks === null || videoTracks === undefined || videoTracks.length === 0) {
// No remote video
var nodeNoCamera = document.createElement('div');
nodeNoCamera.innerHTML = 'No camera available';
nodeNoCamera.style.position = "relative";
nodeNoCamera.style.height = "100%";
nodeNoCamera.style.width = "100%";
nodeNoCamera.style.top = "100%";
nodeNoCamera.style.left = "50%";
nodeNoCamera.style.transform = "translate(-50%,-50%)";
nodeNoCamera.className = "no-camera-available";
newNode.insertBefore(nodeNoCamera, newNode.firstChild);
}
if(onEvents && onEvents.onConnected) onEvents.onConnected();
},
ondataopen: function () {
// Nothing
},
ondata: function (data) {
// Nothing
},
oncleanup: function() {
console.log("Cleanup notification");
}
});
});
};
exports.echoTest = echoTest;