var Janus = require('../externals/janus.nojquery');
var Promise = require('bluebird/js/release/bluebird');
var DataChannel = require('../modules/datachannel');
/**
* SplitAgent usecase
* @class
* @classdesc SplitAgent usecase
* @param {object} onEvents Event handlers: onDestroyed, onError, onJoined, onDataReceived, onAcceptedVideo, onAcceptedData, onReadyLocalStream, onFileTransferOk, onFileTransferKo, onScreensharingAccepted, onScreensharingClosed, onNotified
* @param {object} domElements DOM elements: client, agent, screenRemote, screenLocal
* @param {object} options Available options: dataChannel, session, stream
* @return {Promise} SplitAgent methods: getLicense, sendData, startRecording, startScreensharing, stopRecording, stopScreensharing, toggleVideo
* @example
* var onEvents = {
* onDestroyed: function() {
* // Destroyed
* },
* onError: function(cause) {
* // Error
* },
* onJoined: function(screenRoom) {
* // Joined
* },
* onDataReceived: function(type, data, filename) {
* // Data received
* if(type === 'application/x-chat') { }
* else if(type === 'text/plain') { }
* else if(type === 'application/pdf') { }
* else if(type === 'application/zip') { }
* else if(type === 'application/x-rar') { }
* else if(type === 'image/jpeg') {}
* else if(type === 'image/png') {}
* else if(type === 'application/x-docx') {}
* else if(type === 'application/x-pptx') {}
* else if(type === 'application/x-xlsx') {}
* else if(type === 'application/vnd.oasis.opendocument.text') {}
* },
* onAcceptedVideo: function(stream) {
* // Accepted Video
* },
* onAcceptedData: function() {
* // Accepted Data
* },
* onReadyLocalStream: function(isReady) {
* // Local Video is ready
* },
* onScreensharingAccepted: function() {
* // ScreenSharing Accepted
* },
* onScreensharingClosed: function() {
* // ScreenSharing Closed
* },
* onFileTransferOk: function(fileId) {
* // File Transfer OK
* },
* onFileTransferKo: function(fileId) {
* // File Transfer KO
* },
* onNotified: function(action, data) {
* // Notification
* }
* };
*
* var domElements = {
* client: document.getElementById('clientvideo'),
* agent: document.getElementById('agentvideo'),
* screenRemote: document.getElementById('screenRemote'),
* screenLocal: document.getElementById('localscreen')
* };
*
* var options = {
* dataChannel: {
* dataEnabled: true,
* allowedTypes: ['application/x-chat', 'image/jpeg', 'image/png', 'application/pdf'],
* maxSize: 5, // In MB
* fileTransmission: {
* timeout: 5, // Minutes
* retransmissionDelay: 15 // Seconds
* }
* },
* session: {
* agentName: 'Anna',
* sessionId: 6655
* },
* stream: {
* videoEnabled: true,
* aDeviceId: null,
* vDeviceId: null,
* videoStream: null
* }
* };
*
* usecases.splitAgent(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 splitAgent = function(onEvents, domElements, options) {
if(!domElements || !domElements.agent || !domElements.client || domElements.agent.nodeType !== 1 || domElements.client.nodeType !== 1) return null;
if(domElements.screenAgent) domElements.screenLocal = domElements.screenAgent; // Support last version (until major update 4.X)
// Stream options
var streamOptions = (options && options.stream) ? options.stream : {};
var isDataEnabled = (options && options.dataChannel && options.dataChannel.dataEnabled) ? options.dataChannel.dataEnabled : false;
if(!streamOptions.videoEnabled) streamOptions.videoEnabled = false;
if(!streamOptions.aDeviceId) streamOptions.aDeviceId = undefined;
if(!streamOptions.vDeviceId) streamOptions.vDeviceId = undefined;
if(!streamOptions.videoStream) streamOptions.videoStream = undefined;
// Session options
var sessionOptions = (options && options.session) ? options.session : {};
if(!sessionOptions.agentName) sessionOptions.agentName = 'Unknown';
if(!sessionOptions.sessionId) sessionOptions.sessionId = 1234;
// Vars
var splitAgentHandle = null;
var screenRoomHandle = null;
var agentName = sessionOptions.agentName;
var sessionId = sessionOptions.sessionId;
var screenid = null;
var feeds = [];
var bitrateTimer = [];
var prefixName = null;
var screenFeed = null;
var screenRoom = null;
var recordId = 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 = '';
}
}
};
/**
* The Agent can connect to establish a Video session
* @param {integer} id Session ID
* @param {string} display Display name
* @return {nothing}
* @private
*/
var joinVideoSession = function(id, display) {
var register = {
"request": "join",
"room": id || 1234,
"ptype": "publisher",
"display": display || 'Agent'
};
splitAgentHandle.send({"message": register});
};
/**
* The Agent sends a request to start recording the session
* @param {string} recordPrefix Prefix of records: e.g: '__default__'
* @return {nothing}
* @example
* action.startRecording();
*/
var startRecording = function(recordPrefix) {
prefixName = recordPrefix;
var req = {
"request": "startRec",
"room": sessionId
}
splitAgentHandle.send({"message": req});
// ScreenSharing
/*if(screenRoomHandle !== null) {
var req = {
"request": "startRec",
"room": screenid
}
splitAgentHandle.send({"message": req});
}*/
};
/**
* The Agent sends a request to stop recording the session
* @return {nothing}
* @example
* action.stopRecording();
*/
var stopRecording = function() {
var req = {
"request": "stopRec",
"room": sessionId
}
splitAgentHandle.send({"message": req});
// ScreenSharing
/*if(screenRoomHandle !== null) {
var req = {
"request": "stopRec",
"room": screenid
}
splitAgentHandle.send({"message": req});
}*/
};
/**
* Start recording (Slave)
* @param {integer} id Session ID
* @param {string} recordPrefix Prefix of records: e.g: '__default__'
* @return {nothing}
* @private
*/
var recordVideoroom = function(id, recordPrefix) {
var req = {
"request": "configure",
//"audio": true,
"room": id,
"record": true,
"prefixtheme": recordPrefix,
"record_id": recordId,
"role": "agent"
}
splitAgentHandle.send({"message": req});
};
/**
* Start recording (Slave) (ScreenRoom)
* @param {integer} id Screen ID
* @param {string} recordPrefix Prefix of records: e.g: '__ScreenSharingdefault__'
* @return {nothing}
* @private
*/
var recordScreenroom = function(id, recordPrefix, recordId) {
var req = {
"request": "configure",
//"audio": true,
"room": id,
"record": true,
"prefixtheme": recordPrefix + 'ScreenSharing', // Hidden on VideoPlayer
"record_id": recordId
}
screenRoomHandle.send({"message": req});
};
/**
* Stop recording (Slave)
* @param {integer} id Session ID
* @return {nothing}
* @private
*/
var stoprecordVideoroom = function(id) {
var req = {
"request": "configure",
"room": id,
"record": false
}
splitAgentHandle.send({"message": req});
};
/**
* Stop recording (Slave)
* @param {integer} id Session ID
* @return {nothing}
* @private
*/
var stoprecordScreenroom = function(id) {
var req = {
"request": "configure",
"room": id,
"record": false
}
screenRoomHandle.send({"message": req});
};
/**
* The VideoGateway is requested about the features of the contracted license
* @return {Object} License Information (Screensharing, Livechat and VideoRecording )
* @example
* var myLicense = action.getLicense();
* console.log(myLicense);
*/
var getLicense = function() {
return window.VideoRTC.license;
};
/**
* Toggle local Video stream (Mute/Unmute)
* @return {boolean} Is video muted?
* @example
* action.toggleVideo(); // true or false
*/
var toggleVideo = function() {
if (splitAgentHandle.isVideoMuted()) splitAgentHandle.unmuteVideo();
else splitAgentHandle.muteVideo();
return splitAgentHandle.isVideoMuted();
};
/**
* Sends a message (Chat or File) through the DataChannel
* @param {string} type MIME Type (e.g: 'application/x-chat', 'text/plain', 'application/pdf', 'application/zip', 'application/x-rar', 'image/jpeg', 'image/png', 'application/x-docx', 'application/x-pptx', 'application/x-xlsx', 'application/vnd.oasis.opendocument.text')
* @param {string} data Data Content
* @param {function} cOk Callback success function
* @param {function} cKo Callback failed function
* @param {string} (Optional) filename File Name (e.g: file.zip)
* @return {nothing}
* @example
* action.sendData('application/x-chat', 'Hello Mike!',
* function(cOk) {
* // Success
* },
* function(error) {
* // Error
* console.log(error);
* }
* )
*/
var sendData = function(type, data, cOk, cKo, filename) {
DataChannel.send(type, data, cOk, cKo, filename);
};
/**
* New remote Feed
* @param {integer} id Session ID
* @param {string} display Display name
* @return {nothing}
* @private
*/
var newRemoteFeed = function(id, display) {
var remoteFeed = null;
window.VideoRTC.connection.handle.attach({
plugin: "janus.plugin.split",
success: function(pluginHandle) {
remoteFeed = pluginHandle;
var listen = {
"request": "join",
"room": sessionId,
"ptype": "listener",
"feed": id
};
remoteFeed.send({"message": listen});
},
error: function(cause) {
console.log(" -- Error attaching plugin...", error);
},
destroyed: function() {
},
consentDialog: function(on) {
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (listener) :::");
var event = msg["split"];
if (event != undefined && event != null) {
if (event === "attached") {
// Subscriber created and attached
for (var i = 1; i < 6; i++) {
if (feeds[i] === undefined || feeds[i] === null) {
feeds[i] = remoteFeed;
remoteFeed.rfindex = i;
break;
}
}
remoteFeed.rfid = msg["id"];
remoteFeed.rfdisplay = msg["display"];
Janus.log("Successfully attached to feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") in room " + msg["room"]);
} else if (msg["error"] !== undefined && msg["error"] !== null) {
console.log(msg["error"]);
} else {
// What has just happened?
}
}
if (jsep !== undefined && jsep !== null) {
// Answer and attach
remoteFeed.createAnswer(
{
jsep: jsep,
media: {audioSend: false, videoSend: false, data: true}, // We want recvonly audio/video
success: function (jsep) {
var body = {"request": "start", "room": sessionId};
remoteFeed.send({"message": body, "jsep": jsep});
},
error: function (error) {
Janus.error("WebRTC error:", error);
}
});
}
},
onlocalstream: function(stream) {
},
onremotestream: function(stream) {
Janus.debug("Remote feed #" + remoteFeed.rfindex);
var generateLabel = function(id, content, backgroundColor, position) {
var output = '';
output += '<span id="'+id+'" style="';
output += ' position:absolute;margin:10px;padding:3px 5px;color:white;font-weight:bold;border-radius:5px;';
output += 'background:'+backgroundColor+';';
output += position;
output += '">'+content+'</span>';
return output;
};
var container = domElements.client;
var tpl = '';
tpl += '<div id="container-remote1">';
tpl += '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="videoremote1"></video>';
tpl += generateLabel('remote-name', remoteFeed.rfdisplay, '#55D8D5', 'left:0; margin-top: 10px;');
tpl += generateLabel('remote-resolution', '', '#8DCC6D', 'left:0; margin-top: 40px;');
tpl += generateLabel('remote-bitrate', '', '#FF6E5F', 'left:0; margin-top: 70px;');
tpl += '</div>';
container.innerHTML += tpl;
var remoteContainer = document.getElementById('container-remote1');
var videoElem = document.getElementById('videoremote1');
videoElem.onplaying = function() {
var width = this.videoWidth;
var height = this.videoHeight;
document.getElementById('remote-resolution').innerHTML = width+'x'+height;
if(window.VideoRTC.getBrowser() === 'firefox') {
// Firefox Stable has a bug: width and height are not immediately available after a playing
setTimeout(function() {
var width = videoElem.videoWidth;
var height = videoElem.videoHeight;
document.getElementById('remote-resolution').innerHTML = width+'x'+height;
}, 2000);
}
};
Janus.attachMediaStream(videoElem, stream);
videoElem.muted = true;
var videoTracks = stream.getVideoTracks();
if(videoTracks === null || videoTracks === undefined || videoTracks.length === 0 || videoTracks[0].muted) {
// 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";
remoteContainer.insertBefore(nodeNoCamera, remoteContainer.firstChild);
// We Hide Bitrate and Resolution labels
for(var i = 0; i < remoteContainer.childNodes.length; i++) {
if(remoteContainer.childNodes[i].id && (remoteContainer.childNodes[i].id.indexOf('remote-resolution') >= 0 || remoteContainer.childNodes[i].id.indexOf('remote-bitrate') >= 0 )) {
remoteContainer.childNodes[i].style.display = 'none';
}
}
}
bitrateTimer[remoteFeed.rfindex] = setInterval(function() {
// Display updated bitrate, if supported
var bitrate = remoteFeed.getBitrate();
if(document.getElementById('remote-bitrate')) document.getElementById('remote-bitrate').innerHTML = bitrate;
}, 1000);
if(onEvents && onEvents.onAcceptedVideo) onEvents.onAcceptedVideo(stream);
},
oncleanup: function() {
Janus.log(" ::: Got a cleanup notification (remote feed " + id + ") :::");
if (bitrateTimer[remoteFeed.rfindex] !== null && bitrateTimer[remoteFeed.rfindex] !== null)
clearInterval(bitrateTimer[remoteFeed.rfindex]);
bitrateTimer[remoteFeed.rfindex] = null;
},
detached: function() {
},
ondataopen: function () {
Janus.log("The DataChannel is available!");
if(onEvents && onEvents.onAcceptedData) onEvents.onAcceptedData();
},
ondata: function (data) {
Janus.debug("We got data from the DataChannel! " + data);
DataChannel.receive(data, onEvents.onDataReceived);
}
});
};
/**
* Publish own stream
* @return {nothing}
* @private
*/
var publishOwnFeed = function() {
var mediaOffer = {
audioRecv: false,
videoRecv: false,
audioSend: false,
videoSend: streamOptions.videoEnabled,
data: isDataEnabled,
video: {
deviceId: {
exact: streamOptions.vDeviceId || undefined
}
}
};
splitAgentHandle.createOffer(
{
media: mediaOffer, // Publishers are sendonly
stream: streamOptions.videoStream,
success: function (jsep) {
var publish = {"request": "configure", "audio": false, "video": true, "record": false}; // useAudio
splitAgentHandle.send({"message": publish, "jsep": jsep});
},
error: function (error) {
console.log("WebRTC error:", error);
publishOwnFeed();
}
});
};
/**
* Join Screen Room
* @param {integer} screenRoom Screen Room ID
* @return {nothing}
* @private
*/
var joinScreenroom = function(screenRoom) {
window.VideoRTC.connection.handle.attach({
plugin: "janus.plugin.split",
success: function(pluginHandle) {
// Plugin attached! 'pluginHandle' is our handle
screenRoomHandle = pluginHandle;
var register = { "request": "join", "room": screenRoom, "ptype": "publisher", "display": 'ScreenAgent' };
screenRoomHandle.send({"message": register});
},
error: function(cause) {
},
consentDialog: function(on) {
},
onmessage: function(msg, jsep) {
var event = msg.split;
if(event !== undefined && event !== null) {
if(event === "joined") {
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
Janus.debug(" >> [" + id + "] " + display);
listenScreenSharing(screenRoom, id);
}
}
} else if(event === "destroyed") {
Janus.warn("The room has been destroyed!");
} else if(event === "event") {
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
Janus.debug(" >> [" + id + "] " + display);
listenScreenSharing(screenRoom, id);
}
} else if(msg["leaving"] !== undefined && msg["leaving"] !== null) {
var leaving = msg["leaving"];
Janus.log("Publisher left: " + leaving);
var container = domElements.screenRemote;
container.innerHTML = '';
container.style = '';
//container.className = '';
screenFeed.detach();
if(onEvents && onEvents.onScreensharingClosed) onEvents.onScreensharingClosed();
} else if(msg["unpublished"] !== undefined && msg["unpublished"] !== null) {
var unpublished = msg["unpublished"];
Janus.log("Publisher left: " + unpublished);
var container = domElements.screenRemote;
container.innerHTML = '';
container.style = '';
//container.className = '';
screenFeed.detach();
} else if(msg["error"] !== undefined && msg["error"] !== null) {
Janus.error(msg["error"]);
}
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
screenRoomHandle.handleRemoteJsep({jsep: jsep});
}
},
onlocalstream: function(stream) {
// We have a local stream (getUserMedia worked!) to display
var container = domElements.screenLocal;
container.innerHTML = '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="screenAgent"></video>';
var videoElem = document.getElementById('screenAgent');
Janus.attachMediaStream(videoElem, stream);
videoElem.muted = true;
},
onremotestream: function(stream) {
},
oncleanup: function() {
},
detached: function() {
}
});
};
/**
* Listen ScreenSharing
* @param {integer} screenRoom Screen Room ID
* @param {integer} peerId Peer ID
* @return {nothing}
* @private
*/
var listenScreenSharing = function(screenRoom, peerId) {
window.VideoRTC.connection.handle.attach(
{
plugin: "janus.plugin.split",
success: function(pluginHandle) {
//if(screenFeed) screenFeed.detach();
screenFeed = pluginHandle;
var listen = { "request": "join", "room": screenRoom, "ptype": "listener", "feed": peerId };
screenFeed.send({"message": listen});
},
error: function(error) {
Janus.error(" -- Error attaching plugin...", error);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (listener) :::");
var event = msg["split"];
if(event !== undefined && event !== null) {
if(event === "attached") {
} else if(msg["error"] !== undefined && msg["error"] !== null) {
Janus.error(msg["error"]);
} else {
// What has just happened?
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
// Answer and attach
screenFeed.createAnswer(
{
jsep: jsep,
media: {
audioSend: false,
videoSend: false,
audioRecv: false,
videoRecv: true,
data: false
}, // We want recvonly audio/video
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { "request": "start", "room": sessionId };
screenFeed.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
}
});
}
},
onlocalstream: function(stream) {
// The subscriber stream is recvonly, we don't expect anything here
},
onremotestream: function(stream) {
var container = domElements.screenRemote;
var tpl = '';
tpl += '<div id="container-screenremote">';
tpl += '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="screenremote"></video>';
tpl += '</div>';
container.innerHTML = tpl;
var videoElem = document.getElementById('screenremote');
Janus.attachMediaStream(videoElem, stream);
videoElem.muted = true;
if(onEvents && onEvents.onScreensharingAccepted) onEvents.onScreensharingAccepted();
},
oncleanup: function() {
}
});
};
/**
* The Agent sends a request to start Screensharing
* @param {integer} screenId Screen Id
* @param {function} cOk Callback Ok
* @param {function} cKo Callback Error
* @return {nothing}
* @example
* action.startScreensharing(1234, function() {
* // Success
* }, function(cause) {
* // Error
* })
*/
var startScreensharing = function(screenId, cOk, cKo) {
if(!getLicense().screensharing) {
cKo ('Screensharing is not a feature of your Gateway');
return false;
}
if(window.location.protocol !== 'https:') {
cKo ('Screensharing requires HTTPS');
return false;
}
if(window.isMobile) {
cKo ('Screensharing is not available on Mobile devices');
return false;
}
if(!Janus.isExtensionEnabled()) {
cKo("You're using a recent version of Chrome but don't have the screensharing extension installed: click <b><a href='https://chrome.google.com/webstore/detail/videortc-screensharing/pkilckpboojemoogepfpkgbihkfkikel' target='_blank'>here</a></b> to do so");
return false;
}
screenid = screenId;
var capture = 'screen';
screenRoomHandle.createOffer(
{
//media: { audioRecv: false, videoRecv: false, audioSend: useAudio, videoSend: true/*, video:"hires"*/}, // Publishers are sendonly
media: { video: capture, audio: false, videoRecv: false },
success: function(jsep) {
var publish = { "request": "configure", "audio": false, "video": true };
screenRoomHandle.send({"message": publish, "jsep": jsep});
cOk();
},
error: function(error) {
console.log(error);
if(error && error.name === 'NotAllowedError' && window.getBrowser() === 'firefox') {
cKo('Firefox needs that the domain this web application is from is listed in Allowed domains.');
}
Janus.error("WebRTC error:", error);
}
}
);
};
/**
* The Agent sends a request to stop Screensharing
* @param {function} cOk Callback Ok
* @param {function} cKo Callback Error
* @return {nothing}
* @example
* action.stopScreensharing(function() {
* // Success
* }, function(cause) {
* // Error
* })
*/
var stopScreensharing = function(cOk, cKo) {
var leave = { "request": "leave" };
screenRoomHandle.send({"message": leave});
screenRoomHandle.detach();
joinScreenroom(screenRoom);
var container = domElements.screenLocal;
container.innerHTML = '';
container.style = '';
cOk();
};
/**
* Send a notification to the other peer via the VideoGateway
* @param {string} action Identifies the notification type
* @param {string} data Useful for sending extra data (Optional)
* @example
* action.notify('open-map');
*/
var notify = function(action, data) {
if(!action) return;
var not = {
"request": "notify",
"action": action,
"room": sessionId,
"origin": "agent"
};
if(data) not.data = data;
splitAgentHandle.send({"message": not});
};
return new Promise(function (resolve, reject) {
window.VideoRTC.connection.handle.attach({
plugin: "janus.plugin.split",
success: function(pluginHandle) {
// Plugin attached! 'pluginHandle' is our handle
splitAgentHandle = pluginHandle;
// DataChannel options
var optionsDataChannel = (options && options.dataChannel) ? options.dataChannel : {};
var cbks = {
fileOk: onEvents.onFileTransferOk || function() {},
fileKo: onEvents.onFileTransferKo || function() {}
};
var result = DataChannel.initialize(optionsDataChannel, pluginHandle, cbks);
if(!result) console.log("Datachannel options can't be loaded:");
joinVideoSession(sessionId, agentName);
splitAgentHandle.send({
message: {
request: "license_info"
},
success: function(data) {
if(data && data["error_code"]){
reject(data["error"]);
}
else {
/*resolve({
closeUsecase: closeUsecase,
getLicense: getLicense,
startRecording: startRecording,
stopRecording: stopRecording,
startScreensharing: startScreensharing,
stopScreensharing: stopScreensharing,
toggleVideo: toggleVideo,
sendData: sendData
});*/
}
}
});
},
error: function(cause) {
if(cause && cause.indexOf('482') >= 0) {
reject("Sorry, all channels are busy!");
}
else if(cause && cause.indexOf('480') >= 0) {
reject("License has been expired. Please, contact with an Administrator");
}
else {
reject(cause);
}
},
destroyed: function() {
},
consentDialog: function(on) {
},
onmessage: function(msg, jsep) {
var event = msg["split"];
if (event != undefined && event != null) {
if (event === "joined") {
// Publisher/manager created, negotiate WebRTC and attach to existing feeds, if any
publishOwnFeed();
// Any new feed to attach to?
if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
for (var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
newRemoteFeed(id, display);
}
}
screenRoom = msg["screenroom"] > 0 ? msg["screenroom"] : undefined;
if(onEvents && onEvents.onJoined) onEvents.onJoined(screenRoom);
if(screenRoom && screenRoom > 0 && domElements.screenRemote) joinScreenroom(screenRoom);
} else if (event === "destroyed") {
// The room has been destroyed
if(onEvents && onEvents.onDestroyed) onEvents.onDestroyed();
} else if (event === "event") {
// Any new feed to attach to?
if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
for (var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
newRemoteFeed(id, display);
}
} else if (msg["leaving"] !== undefined && msg["leaving"] !== null) {
// One of the publishers has gone away?
var leaving = msg["leaving"];
var remoteFeed = null;
for (var i = 1; i < 6; i++) {
if (feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == leaving) {
remoteFeed = feeds[i];
break;
}
}
if (remoteFeed != null) {
// REVIEW: Clean container?
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
} else if (msg["unpublished"] !== undefined && msg["unpublished"] !== null) {
// One of the publishers has unpublished?
var unpublished = msg["unpublished"];
Janus.log("Publisher left: " + unpublished);
if (unpublished === 'ok') {
// That's us
splitAgentHandle.hangup();
return;
}
var remoteFeed = null;
for (var i = 1; i < 6; i++) {
if (feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == unpublished) {
remoteFeed = feeds[i];
break;
}
}
if (remoteFeed != null) {
// TODO: Clean container?
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
} else if(msg["startedRec"] !== undefined && msg["startedRec"] !== null) {
recordId = msg["recordId"];
recordVideoroom(sessionId, prefixName);
//if(screenRoomHandle !== null) recordScreenroom(screenid, prefixName, msg["recordId"]);
} else if(msg["stoppedRec"] !== undefined && msg["stoppedRec"] !== null) {
stoprecordVideoroom(sessionId);
//if(screenRoomHandle !== null) stoprecordScreenroom(screenid);
} else if(msg["notified"] !== undefined && msg["notified"] !== null) {
if(onEvents && onEvents.onNotified && msg["origin"] !== 'agent') {
Janus.debug("Notification received: " + msg["action"]);
onEvents.onNotified(msg["action"], msg["data"]);
}
} else if (msg["error"] !== undefined && msg["error"] !== null) {
if(msg["error"].toLowerCase().indexOf('already attached') > -1) window.VideoRTC.connection.handle.destroy();
if(onEvents && onEvents.onError) onEvents.onError(msg["error"]);
} else if (msg['result'] !== undefined && msg['result'] !== null) {
var result = msg['result'];
if (result['event'] == 'license_info') {
window.VideoRTC.license = {
screensharing: (result['screensharing'] == 'true'),
livechat: (result['livechat'] == 'true'),
videorecording: (result['videorecording'] == 'true')
};
Janus.debug("License", window.VideoRTC.license);
resolve({
closeUsecase: closeUsecase,
getLicense: getLicense,
notify: notify,
startRecording: startRecording,
stopRecording: stopRecording,
startScreensharing: startScreensharing,
stopScreensharing: stopScreensharing,
toggleVideo: toggleVideo,
sendData: sendData
});
}
}
}
}
if (jsep !== undefined && jsep !== null) {
splitAgentHandle.handleRemoteJsep({jsep: jsep});
}
},
onlocalstream: function(stream) {
// We have a local stream (getUserMedia worked!) to display
var container = domElements.agent;
container.innerHTML = '<video autoplay poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="videoAgent"></video>';
var videoElem = document.getElementById('videoAgent');
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);
if(onEvents && onEvents.onReadyLocalStream) onEvents.onReadyLocalStream(false);
}
else {
if(onEvents && onEvents.onReadyLocalStream) onEvents.onReadyLocalStream(true);
}
},
onremotestream: function(stream) {
},
oncleanup: function() {
},
detached: function() {
}
});
});
};
exports.splitAgent = splitAgent;