var Janus = require('../externals/janus.nojquery');
var Promise = require('bluebird/js/release/bluebird');
/**
* VideoMail usecase
* @class
* @classdesc VideoMail usecase
* @param {object} onEvents Event handlers: onRecording, onStopped
* @param {object} domElements DOM elements: videomail
* @param {object} options Available options: stream
* @return {Promise} VideoMail methods: startRecording, stopRecording, toggleAudio, toggleVideo
* @example
* var onEvents = {
* onRecording: function() {
* // Recording
* },
* onStopped: function() {
* // Stopped
* }
* };
*
* var domElements = {
* videomail: document.getElementById('videomail')
* };
*
* var options = {
* stream: {
* audioEnabled: true,
* videoEnabled: true,
* aDeviceId: null,
* vDeviceId: null
* }
* };
*
* usecases.videoMail(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 videoMail = function(onEvents, domElements, options) {
var videomailHandle = null;
var recordingId = null;
var bandwidth = 1024 * 1024;
// Stream options
var streamOptions = (options && options.stream) ? options.stream : {};
if(!streamOptions.audioEnabled) streamOptions.audioEnabled = false;
if(!streamOptions.videoEnabled) streamOptions.videoEnabled = false;
if(!streamOptions.aDeviceId) streamOptions.aDeviceId = undefined;
if(!streamOptions.vDeviceId) streamOptions.vDeviceId = undefined;
/**
* 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 = '';
}
}
};
/**
* The User sends a request to start recording a Video message
* @param {string} recordPrefix Prefix record
* @param {string} name File name
* @return {nothing}
* @example
* action.startRecording('__default__', 'MyRecordMobile');
*/
var startRecording = function(recordPrefix, name) {
var fullname = recordPrefix + "VideoMail-" + name + "-" + Date.now();
// bitrate and keyframe interval can be set at any time:
// before, after, during recording
videomailHandle.send({
'message': {
'request': 'configure',
'video-bitrate-max': bandwidth, // a quarter megabit
'video-keyframe-interval': 15000 // 15 seconds
}
});
videomailHandle.createOffer(
{
media: { // Publishers are sendonly
audioRecv: false,
audioSend: streamOptions.audioEnabled || false,
videoRecv: false,
videoSend: streamOptions.videoEnabled || false,
data: false,
audio: {
deviceId: {
exact: streamOptions.aDeviceId
}
},
video: {
deviceId: {
exact: streamOptions.vDeviceId
}
}
},
// By default, it's sendrecv for audio and video...
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { "request": "record", "name": fullname };
videomailHandle.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error...", error);
videomailHandle.hangup();
}
});
};
/**
* The User sends a request to stop recording the current Video message
* @return {nothing}
* @example
* action.stopRecording();
*/
var stopRecording = function() {
var request = { "request": "stop" };
videomailHandle.send({"message": request});
videomailHandle.hangup();
};
/**
* Toggle Audio stream (Mute/Unmute)
* @return {boolean} Is audio muted?
* @example
* action.toggleAudio(); // true or false
*/
var toggleAudio = function() {
if (videomailHandle.isAudioMuted()) videomailHandle.unmuteAudio();
else videomailHandle.muteAudio();
return videomailHandle.isAudioMuted();
};
/**
* Toggle Video stream (Mute/Unmute)
* @return {boolean} Is video muted?
* @example
* action.toggleVideo(); // true or false
*/
var toggleVideo = function() {
if (videomailHandle.isVideoMuted()) videomailHandle.unmuteVideo();
else videomailHandle.muteVideo();
return videomailHandle.isVideoMuted();
};
return new Promise(function (resolve, reject) {
window.VideoRTC.connection.handle.attach({
plugin: "janus.plugin.recordplay",
success: function(pluginHandle) {
videomailHandle = pluginHandle;
resolve({
closeUsecase: closeUsecase,
startRecording: startRecording,
stopRecording: stopRecording,
toggleAudio: toggleAudio,
toggleVideo: toggleVideo
});
},
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 === 'recording') {
// Got an ANSWER to our recording OFFER
if(jsep !== null && jsep !== undefined)
videomailHandle.handleRemoteJsep({jsep: jsep});
var id = result["id"];
if(id !== null && id !== undefined) {
Janus.log("The ID of the current recording is " + id);
recordingId = id;
}
if(onEvents && onEvents.onRecording) onEvents.onRecording();
} 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);
videomailHandle.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 === 'stopped') {
Janus.log("Session has stopped!");
var id = result["id"];
if(recordingId !== null && recordingId !== undefined) {
if(recordingId !== id) {
Janus.warn("Not a stop to our recording?");
return;
}
}
var container = domElements.videomail;
container.innerHTML = '';
videomailHandle.hangup();
if(recordingId !== null && onEvents && onEvents.onStopped) onEvents.onStopped();
recordingId = null;
}
}
}
},
onlocalstream: function(stream) {
Janus.debug(" ::: Got a local stream :::");
var container = domElements.videomail;
container.innerHTML = '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="vmail"></video>';
var videoElem = document.getElementById('vmail');
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";
container.insertBefore(nodeNoCamera, container.firstChild);
}
},
onremotestream: function(stream) {
// Nothing
},
oncleanup: function() {
var container = domElements.videomail;
container.innerHTML = '';
},
detached: function() {
// Nothing
}
});
});
};
exports.videoMail = videoMail;