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;