Source: lib/echoTest.js

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;