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;