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;