Source: lib/videoPlayer.js

var Janus = require('../externals/janus.nojquery');
var Promise = require('bluebird/js/release/bluebird');

/**
 * VideoPlayer usecase
 * @class
 * @classdesc VideoPlayer usecase
 * @param  {object} onEvents       Event handlers: onStopped
 * @param  {object} domElements    DOM elements: videoplayer
 * @return {Promise}               VideoPlayer methods: getRecords, playRecord
 * @example
 * var onEvents = {
 *     onStopped: function(cause) {
 *          // Stopped
 *     }
 * };
 *
 * var domElements = {
 *     videoplayer: document.getElementById('videoplayer')
 * };
 *
 * usecases.videoPlayer(onEvents, domElements)
 *     .then(function(action) {
 *          // Use Case has been atacched succesfully
 *          ...
 *     })
 *     .catch(function(cause) {
 *         // Error attaching the Use Case
 *         console.log("Error Attach " + cause );
 *     })
 */
var videoPlayer = function(onEvents, domElements) {

    var videoplayerHandle = null;
    var recordList = null;
    var recordFullList = null;
    var isPlaying = 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 = '';
            }
        }
    };

    /**
     * Play Video Remote
     * @param  {integer} idRecord Id record
     * @return {nothing}
     * @private
     */
    var playVideoRemote = function(idRecord) {
        var handlePlayout = null;

        window.VideoRTC.connection.handle.attach(
            {
                plugin: "janus.plugin.recordplay",
                success: function(pluginHandle) {
                    handlePlayout = pluginHandle;
                    var play = { "request": "play", "id": idRecord };
                    handlePlayout.send({"message": play});
                },
                error: function(error) {
                    Janus.error("  -- Error attaching plugin...", error);
                },
                consentDialog: function(on) {
                    // Nothing
                },
                onmessage: function(msg, jsep) {
                    Janus.debug(" ::: Got a message :::");
                    var result = msg["result"];
                    if(result !== null && result !== undefined) {
                        if(result["status"] !== undefined && result["status"] !== null) {
                            var event = result["status"];
                            if(event === 'preparing') {
                                Janus.log("Preparing the recording playout");
                                handlePlayout.createAnswer(
                                    {
                                        jsep: jsep,
                                        media: { audioSend: false, videoSend: false },	// We want recvonly audio/video
                                        success: function(jsep) {
                                            Janus.debug("Got SDP!");
                                            Janus.debug(jsep);
                                            var body = { "request": "start" };
                                            handlePlayout.send({"message": body, "jsep": jsep});
                                        },
                                        error: function(error) {
                                            Janus.error("WebRTC error:", error);
                                        }
                                    });
                            } else if(event === 'slow_link') {
                                var uplink = result["uplink"];
                                if(uplink !== 0) {
                                    // Janus detected issues when receiving our media, let's slow down
                                    bandwidth = parseInt(bandwidth / 1.5);
                                    handlePlayout.send({
                                        'message': {
                                            'request': 'configure',
                                            'video-bitrate-max': bandwidth, // Reduce the bitrate
                                            'video-keyframe-interval': 15000 // Keep the 15 seconds key frame interval
                                        }
                                    });
                                }
                            } else if(event === 'playing') {
                                Janus.log("Playout has started!");
                            } else if(event === 'stopped') {
                                Janus.log("Session has stopped!");
                                var id = result["id"];
                                if(isPlaying && onEvents && onEvents.onStopped) onEvents.onStopped();
                                isPlaying = false;
                                var container = domElements.videoplayer;
                                container.innerHTML = '';
                            }
                        }
                    }
                    else {
                        if(msg["error"] !== null && msg["error"] !== undefined) {
                            // Error
                        }
                    }
                },
                onlocalstream: function(stream) {
                    // Nothing
                },
                onremotestream: function(stream) {
                    var newId = Date.now();
                    var container = domElements.videoplayer;
                    var target = document.getElementById('container-videoplayer'+newId);
                    var tpl = '';
                    if(!target || target.innerHTML.length === 0) {
                        tpl += '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="videoplayer-'+newId+'"></video>';
                        var newNode = document.createElement('div');
                        newNode.id = 'container-videoplayer'+newId;
                        newNode.innerHTML = tpl;
                        container.appendChild(newNode);
                        var videoElem = document.getElementById('videoplayer-'+newId);
                        Janus.attachMediaStream(videoElem, stream);

                        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";
                            container.insertBefore(nodeNoCamera, container.firstChild);
                        }

                    }
                },
                oncleanup: function() {
                    var stop = { "request": "stop" };
                	handlePlayout.send({"message": stop});
                }
            });
    };

    /**
     * Play out a Video message recorded previously by the Videomail or Split
     * @param  {integer} idRecord Id Record
     * @param  {boolean} playSessionStreams Play Session Streams? (Optional)
     * @return {nothing}
     * @example
     * action.playRecord(5434232, true);
     */
    var playRecord = function(idRecord, playSessionStreams) {
        if(isPlaying) return;
        var recordsToPlay = [];
        var nameRecord = null;
        if(playSessionStreams) {
            for(var i = 0; i < recordFullList.length; i++) {
                if(recordFullList[i]["id"] === idRecord) {
                    nameRecord = recordFullList[i]["name"];
                }
            }
            for(var i = 0; i < recordFullList.length; i++) {
                if(recordFullList[i]["name"] === nameRecord) {
                    recordsToPlay.push(recordFullList[i]["id"]);
                }
            }
        }
        else {
            recordsToPlay.push(idRecord);
        }
        recordsToPlay.forEach(function(iter){
            isPlaying = true;
            playVideoRemote(iter);
        });
    };

    /**
     * Gets the list of available Records in the VideoGateway
     * @param  {RegExp} filter RegExp to filter the list of records. e.g: /^__default__/i
     * @param  {boolean} sessionStreams Show/Hide sessions streams (Optional)
     * @return {Promise<Records>}   List of records ({id, name, date})
     * @example
     * action.getRecords(/^__default__/i, true)
     *      .then(function(records) {
     *          // Success
     *          console.log(records);
     *      })
     */
    var getRecords = function(filter, sessionStreams) {

        return new Promise(function (resolve, reject) {
            // Update en gateway
            videoplayerHandle.send({
                "message": { "request": "update" },
                success: function(data) {
                    // Get records list
                    var body = { "request": "list" };
                    videoplayerHandle.send({
                        "message": body,
                        success: function(result) {
                    		if(result === null || result === undefined) {
                    			Janus.error("Got no response to our query for available recordings");
                    			return;
                    		}
                    		if(result["list"] !== undefined && result["list"] !== null) {
                    			var list = result["list"];
                    			list.sort(function(a, b) {return (a["date"] < b["date"]) ? 1 : ((b["date"] < a["date"]) ? -1 : 0);} );
                                recordFullList = list;
                    			var itemsPushed = [];
                                var goPush = null;
                    			for(var mp in list) {
                                    var _aux = "  >> [" + list[mp]["id"] + "] " + list[mp]["name"] + " (" + list[mp]["date"] + ")";
                                    // RegExp Filter
                                    if(!filter.test(list[mp]["name"])) { continue; }
                                    goPush = true;
                                    if(!sessionStreams) {
                                        for(var i=0; i<itemsPushed.length; i++) {
                                            if(itemsPushed[i]["name"].toLowerCase().indexOf(list[mp]["name"].toLowerCase()) !== -1) {
                                                // We show only one element in the dropdown for each SPLIT session
                                                goPush = false;
                                            }
                                        }
                                    }
                                    if(goPush) {
                                        itemsPushed.push({
                                            id: list[mp]["id"],
                                            name: list[mp]["name"],
                                            date: list[mp]["date"]
                                        });
                                    }
                    			}
                                recordList = itemsPushed;
                                resolve(recordList);
                    		}
                        }
                    });
                }
            });
        });
    };

    return new Promise(function (resolve, reject) {
        window.VideoRTC.connection.handle.attach({
            plugin: "janus.plugin.recordplay",
            success: function(pluginHandle) {
                videoplayerHandle = pluginHandle;
                resolve({
                    closeUsecase: closeUsecase,
                    getRecords: getRecords,
                    playRecord: playRecord
                });
            },
            error: function(cause) {
                Janus.error("  -- Error attaching plugin...", cause);
                reject(cause);
            },
            consentDialog: function(on) {
                // Nothing
            },
            onmessage: function(msg, jsep) {
                var result = msg["result"];
                if(result !== null && result !== undefined) {
                    if(result["status"] !== undefined && result["status"] !== null) {
                        var event = result["status"];
                        if(event === 'preparing') {
                            Janus.log("Preparing the recording playout");
                            videoplayerHandle.createAnswer(
                                {
                                    jsep: jsep,
                                    media: { audioSend: false, videoSend: false },	// We want recvonly audio/video
                                    success: function(jsep) {
                                        Janus.debug("Got SDP!");
                                        Janus.debug(jsep);
                                        var body = { "request": "start" };
                                        videoplayerHandle.send({"message": body, "jsep": jsep});
                                    },
                                    error: function(error) {
                                        Janus.error("WebRTC error:", error);
                                    }
                                });
                        } else if(event === 'slow_link') {
                            var uplink = result["uplink"];
                            if(uplink !== 0) {
                                // Janus detected issues when receiving our media, let's slow down
                                bandwidth = parseInt(bandwidth / 1.5);
                                videoplayerHandle.send({
                                    'message': {
                                        'request': 'configure',
                                        'video-bitrate-max': bandwidth, // Reduce the bitrate
                                        'video-keyframe-interval': 15000 // Keep the 15 seconds key frame interval
                                    }
                                });
                            }
                        } else if(event === 'playing') {
                            Janus.log("Playout has started!");
                        } else if(event === 'stopped') {
                            Janus.log("Session has stopped!");
                            videoplayerHandle.hangup();
                        }
                    }
                }
            },
            onlocalstream: function(stream) {
                // Nothing
            },
            onremotestream: function(stream) {
                // Nothing
            },
            oncleanup: function() {
                // Nothing
            },
            detached: function() {
                // Nothing
            }
        });
    });

};

exports.videoPlayer = videoPlayer;