Implements API that allows external applications to embed Jitsi Meet.
This commit is contained in:
parent
78d60128a4
commit
667a8c1493
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* Implements API class that communicates with external api class
|
||||
* and provides interface to access Jitsi Meet features by external
|
||||
* applications that embed Jitsi Meet
|
||||
*/
|
||||
var APIConnector = (function () {
|
||||
|
||||
function APIConnector() { }
|
||||
|
||||
/**
|
||||
* List of the available commands.
|
||||
* @type {{
|
||||
* displayName: inputDisplayNameHandler,
|
||||
* muteAudio: toggleAudio,
|
||||
* muteVideo: toggleVideo,
|
||||
* filmStrip: toggleFilmStrip
|
||||
* }}
|
||||
*/
|
||||
var commands =
|
||||
{
|
||||
displayName: VideoLayout.inputDisplayNameHandler,
|
||||
muteAudio: toggleAudio,
|
||||
muteVideo: toggleVideo,
|
||||
filmStrip: BottomToolbar.toggleFilmStrip
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the API should be enabled or not.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
APIConnector.isEnabled = function () {
|
||||
var hash = location.hash;
|
||||
if(hash && hash.indexOf("external") > -1 && window.postMessage)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the APIConnector. Setups message event listeners that will
|
||||
* receive information from external applications that embed Jitsi Meet.
|
||||
* It also sends a message to the external application that APIConnector
|
||||
* is initialized.
|
||||
*/
|
||||
APIConnector.init = function () {
|
||||
if (window.addEventListener)
|
||||
{
|
||||
window.addEventListener('message',
|
||||
APIConnector.processMessage, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.attachEvent('onmessage', APIConnector.processMessage);
|
||||
}
|
||||
APIConnector.sendMessage({loaded: true});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends message to the external application.
|
||||
* @param object
|
||||
*/
|
||||
APIConnector.sendMessage = function (object) {
|
||||
window.parent.postMessage(JSON.stringify(object), "*");
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes a message event from the external application
|
||||
* @param event the message event
|
||||
*/
|
||||
APIConnector.processMessage = function(event)
|
||||
{
|
||||
var message;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {}
|
||||
for(var key in message)
|
||||
{
|
||||
if(commands[key])
|
||||
commands[key].apply(null, message[key]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the listeners.
|
||||
*/
|
||||
APIConnector.dispose = function () {
|
||||
if(window.removeEventListener)
|
||||
{
|
||||
window.removeEventListener("message",
|
||||
APIConnector.processMessage, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.detachEvent('onmessage', APIConnector.processMessage);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return APIConnector;
|
||||
})();
|
5
app.js
5
app.js
|
@ -1126,6 +1126,8 @@ function getCameraVideoSize(videoWidth,
|
|||
|
||||
$(document).ready(function () {
|
||||
document.title = brand.appName;
|
||||
if(APIConnector.isEnabled())
|
||||
APIConnector.init();
|
||||
|
||||
if(config.enableWelcomePage && window.location.pathname == "/" &&
|
||||
(!window.localStorage.welcomePageDisabled
|
||||
|
@ -1186,7 +1188,6 @@ $(document).ready(function () {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
if (!(interfaceConfig.GENERATE_ROOMNAMES_ON_WELCOME_PAGE === false)){
|
||||
var updateTimeout;
|
||||
var animateTimeout;
|
||||
|
@ -1322,6 +1323,8 @@ $(window).bind('beforeunload', function () {
|
|||
});
|
||||
}
|
||||
disposeConference(true);
|
||||
if(APIConnector.isEnabled())
|
||||
APIConnector.dispose();
|
||||
});
|
||||
|
||||
function disposeConference(onUnload) {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
Jitsi Meet API
|
||||
============
|
||||
|
||||
You can use Jitsi Meet API to embed Jitsi Meet in to your application.
|
||||
|
||||
Installation
|
||||
==========
|
||||
|
||||
To embed Jitsi Meet in your application you need to add Jitsi Meet API library
|
||||
```javascript
|
||||
<script src="https://meet.jit.si/external_api.js"></script>
|
||||
```
|
||||
|
||||
The next step for embedding Jitsi Meet is to create the Jitsi Meet API object
|
||||
```javascript
|
||||
<script>
|
||||
var domain = "meet.jit.si";
|
||||
var room = "JitsiMeetAPIExample";
|
||||
var width = 700;
|
||||
var height = 700;
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height);
|
||||
</script>
|
||||
```
|
||||
You can paste that lines in your html code where you want to be placed the Jitsi Meet conference
|
||||
or you can specify the parent HTML element for the Jitsi Meet conference in the JitsiMeetExternalAPI
|
||||
constructor.
|
||||
```javascript
|
||||
var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
|
||||
```
|
||||
If you don't specify room the user will enter in new conference with random room name.
|
||||
|
||||
Controlling embedded Jitsi Meet Conference
|
||||
=========
|
||||
|
||||
You can control the embedded Jitsi Meet conference using the JitsiMeetExternalAPI object.
|
||||
You can send command to Jitsi Meet conference using ```executeCommand```.
|
||||
```
|
||||
api.executeCommand(command, arguments)
|
||||
```
|
||||
The ```command``` parameter is String object with the name of the command.
|
||||
The ```arguments``` parameter is array with the arguments required by the command.
|
||||
If no arguments are required by the command this parameter can be omitted or you can pass empty array.
|
||||
Currently we support the following commands:
|
||||
|
||||
|
||||
* **displayName** - sets the display name of the local participant. This command requires one argument -
|
||||
the new display name to be set
|
||||
```
|
||||
api.executeCommand('displayName', ['New Nickname']);
|
||||
```
|
||||
* **muteAudio** - mutes / unmutes the audio for the local participant. No arguments are required.
|
||||
```
|
||||
api.executeCommand('muteAudio', [])
|
||||
```
|
||||
* **muteVideo** - mutes / unmutes the video for the local participant. No arguments are required.
|
||||
```
|
||||
api.executeCommand('muteVideo', [])
|
||||
```
|
||||
* **filmStrip** - hides / shows the film strip. No arguments are required.
|
||||
```
|
||||
api.executeCommand('filmStrip', [])
|
||||
```
|
||||
|
||||
You can also execute multiple commands using the method ```executeCommands```.
|
||||
```
|
||||
api.executeCommands(commands)
|
||||
```
|
||||
The ```commands``` parameter is object with keys the names of the commands and values the arguments for the
|
||||
commands.
|
||||
|
||||
```
|
||||
api.executeCommands({displayName: ['nickname'], muteAudio: []});
|
||||
```
|
||||
|
||||
You can also remove the embedded Jitsi Meet Conference with the following code:
|
||||
```
|
||||
api.dispose()
|
||||
```
|
||||
|
||||
It is a good practice to remove the conference before the page is unloaded.
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* Implements API class that embeds Jitsi Meet in external applications.
|
||||
*/
|
||||
var JitsiMeetExternalAPI = (function()
|
||||
{
|
||||
/**
|
||||
* The minimum width for the Jitsi Meet frame
|
||||
* @type {number}
|
||||
*/
|
||||
var MIN_WIDTH = 790;
|
||||
|
||||
/**
|
||||
* The minimum height for the Jitsi Meet frame
|
||||
* @type {number}
|
||||
*/
|
||||
var MIN_HEIGHT = 300;
|
||||
|
||||
/**
|
||||
* Constructs new API instance. Creates iframe element that loads
|
||||
* Jitsi Meet.
|
||||
* @param domain the domain name of the server that hosts the conference
|
||||
* @param room_name the name of the room to join
|
||||
* @param width width of the iframe
|
||||
* @param height height of the iframe
|
||||
* @param parent_node the node that will contain the iframe
|
||||
* @constructor
|
||||
*/
|
||||
function JitsiMeetExternalAPI(domain, room_name, width, height, parent_node)
|
||||
{
|
||||
this.parentNode = null;
|
||||
if(parent_node)
|
||||
{
|
||||
this.parentNode = parent_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
var scriptTag = document.scripts[document.scripts.length - 1];
|
||||
this.parentNode = scriptTag.parentNode;
|
||||
}
|
||||
|
||||
this.iframeHolder =
|
||||
this.parentNode.appendChild(document.createElement("div"));
|
||||
this.iframeHolder.id = "jitsiConference" + JitsiMeetExternalAPI.id;
|
||||
if(width < MIN_WIDTH)
|
||||
width = MIN_WIDTH;
|
||||
if(height < MIN_HEIGHT)
|
||||
height = MIN_HEIGHT;
|
||||
this.iframeHolder.style.width = width + "px";
|
||||
this.iframeHolder.style.height = height + "px";
|
||||
this.frameName = "jitsiConferenceFrame" + JitsiMeetExternalAPI.id;
|
||||
this.url = "https://" + domain + "/";
|
||||
if(room_name)
|
||||
this.url += room_name;
|
||||
this.url += "#external";
|
||||
JitsiMeetExternalAPI.id++;
|
||||
|
||||
this.frame = document.createElement("iframe");
|
||||
this.frame.src = this.url;
|
||||
this.frame.name = this.frameName;
|
||||
this.frame.width = "100%";
|
||||
this.frame.height = "100%";
|
||||
this.frame = this.iframeHolder.appendChild(this.frame);
|
||||
|
||||
this.frameLoaded = false;
|
||||
this.initialCommands = [];
|
||||
this.initListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Last id of api object
|
||||
* @type {number}
|
||||
*/
|
||||
JitsiMeetExternalAPI.id = 0;
|
||||
|
||||
/**
|
||||
* Sends the passed object to Jitsi Meet
|
||||
* @param object the object to be sent
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.sendMessage = function(object)
|
||||
{
|
||||
if(this.frameLoaded)
|
||||
{
|
||||
this.frame.contentWindow.postMessage(
|
||||
JSON.stringify(object), this.frame.src);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.initialCommands.push(object);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes command. The available commands are:
|
||||
* displayName - sets the display name of the local participant to the value
|
||||
* passed in the arguments array.
|
||||
* muteAudio - mutes / unmutes audio with no arguments
|
||||
* muteVideo - mutes / unmutes video with no arguments
|
||||
* filmStrip - hides / shows the film strip with no arguments
|
||||
* If the command doesn't require any arguments the parameter should be set
|
||||
* to empty array or it may be omitted.
|
||||
* @param name the name of the command
|
||||
* @param arguments array of arguments
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.executeCommand = function(name,
|
||||
argumentsList)
|
||||
{
|
||||
var argumentsArray = argumentsList;
|
||||
if(!argumentsArray)
|
||||
argumentsArray = [];
|
||||
var object = {};
|
||||
object[name] = argumentsArray;
|
||||
this.sendMessage(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes commands. The available commands are:
|
||||
* displayName - sets the display name of the local participant to the value
|
||||
* passed in the arguments array.
|
||||
* muteAudio - mutes / unmutes audio with no arguments
|
||||
* muteVideo - mutes / unmutes video with no arguments
|
||||
* filmStrip - hides / shows the film strip with no arguments
|
||||
* @param object the object with commands to be executed. The keys of the
|
||||
* object are the commands that will be executed and the values are the
|
||||
* arguments for the command.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.executeCommands = function (object) {
|
||||
this.sendMessage(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes message events sent from Jitsi Meet
|
||||
* @param event the event
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.processMessage = function(event)
|
||||
{
|
||||
var message;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {}
|
||||
if(message.loaded)
|
||||
{
|
||||
this.onFrameLoaded();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* That method is called when the Jitsi Meet is loaded. Executes saved
|
||||
* commands that are send before the frame was loaded.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.onFrameLoaded = function () {
|
||||
this.frameLoaded = true;
|
||||
for (var i = 0; i < this.initialCommands.length; i++)
|
||||
{
|
||||
this.sendMessage(this.initialCommands[i]);
|
||||
}
|
||||
this.initialCommands = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setups the listener for message events from Jitsi Meet.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.initListeners = function () {
|
||||
var self = this;
|
||||
this.eventListener = function (event) {
|
||||
self.processMessage(event);
|
||||
};
|
||||
if (window.addEventListener)
|
||||
{
|
||||
window.addEventListener('message',
|
||||
this.eventListener, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.attachEvent('onmessage', this.eventListener);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the listeners and removes the Jitsi Meet frame.
|
||||
*/
|
||||
JitsiMeetExternalAPI.prototype.dispose = function () {
|
||||
if (window.removeEventListener)
|
||||
{
|
||||
window.removeEventListener('message',
|
||||
this.eventListener, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.detachEvent('onmessage',
|
||||
this.eventListener);
|
||||
}
|
||||
this.iframeHolder.parentNode.removeChild(this.iframeHolder);
|
||||
};
|
||||
|
||||
return JitsiMeetExternalAPI;
|
||||
|
||||
})();
|
|
@ -34,7 +34,7 @@
|
|||
<script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
|
||||
<script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
|
||||
<script src="data_channels.js?v=3"></script><!-- data channels -->
|
||||
<script src="app.js?v=17"></script><!-- application logic -->
|
||||
<script src="app.js?v=18"></script><!-- application logic -->
|
||||
<script src="commands.js?v=1"></script><!-- application logic -->
|
||||
<script src="chat.js?v=11"></script><!-- chat logic -->
|
||||
<script src="contact_list.js?v=4"></script><!-- contact list logic -->
|
||||
|
@ -47,7 +47,7 @@
|
|||
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
|
||||
<script src="rtp_sts.js?v=4"></script><!-- RTP stats processing -->
|
||||
<script src="local_sts.js?v=2"></script><!-- Local stats processing -->
|
||||
<script src="videolayout.js?v=21"></script><!-- video ui -->
|
||||
<script src="videolayout.js?v=22"></script><!-- video ui -->
|
||||
<script src="connectionquality.js?v=1"></script>
|
||||
<script src="toolbar.js?v=6"></script><!-- toolbar ui -->
|
||||
<script src="toolbar_toggler.js?v=2"></script>
|
||||
|
@ -60,6 +60,7 @@
|
|||
<script src="tracking.js?v=1"></script><!-- tracking -->
|
||||
<script src="jitsipopover.js?v=3"></script>
|
||||
<script src="message_handler.js?v=1"></script>
|
||||
<script src="api_connector.js?v=1"></script>
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/font.css?v=4"/>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=26"/>
|
||||
|
|
|
@ -622,36 +622,14 @@ var VideoLayout = (function (my) {
|
|||
$('#editDisplayName').focus();
|
||||
$('#editDisplayName').select();
|
||||
|
||||
var inputDisplayNameHandler = function (name) {
|
||||
if (nickname !== name) {
|
||||
nickname = name;
|
||||
window.localStorage.displayname = nickname;
|
||||
connection.emuc.addDisplayNameToPresence(nickname);
|
||||
connection.emuc.sendPresence();
|
||||
|
||||
Chat.setChatConversationMode(true);
|
||||
}
|
||||
|
||||
if (!$('#localDisplayName').is(":visible")) {
|
||||
if (nickname)
|
||||
$('#localDisplayName').text(nickname + " (me)");
|
||||
else
|
||||
$('#localDisplayName')
|
||||
.text(defaultLocalDisplayName);
|
||||
$('#localDisplayName').show();
|
||||
}
|
||||
|
||||
$('#editDisplayName').hide();
|
||||
};
|
||||
|
||||
$('#editDisplayName').one("focusout", function (e) {
|
||||
inputDisplayNameHandler(this.value);
|
||||
VideoLayout.inputDisplayNameHandler(this.value);
|
||||
});
|
||||
|
||||
$('#editDisplayName').on('keydown', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
inputDisplayNameHandler(this.value);
|
||||
VideoLayout.inputDisplayNameHandler(this.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -659,6 +637,28 @@ var VideoLayout = (function (my) {
|
|||
}
|
||||
};
|
||||
|
||||
my.inputDisplayNameHandler = function (name) {
|
||||
if (nickname !== name) {
|
||||
nickname = name;
|
||||
window.localStorage.displayname = nickname;
|
||||
connection.emuc.addDisplayNameToPresence(nickname);
|
||||
connection.emuc.sendPresence();
|
||||
|
||||
Chat.setChatConversationMode(true);
|
||||
}
|
||||
|
||||
if (!$('#localDisplayName').is(":visible")) {
|
||||
if (nickname)
|
||||
$('#localDisplayName').text(nickname + " (me)");
|
||||
else
|
||||
$('#localDisplayName')
|
||||
.text(defaultLocalDisplayName);
|
||||
$('#localDisplayName').show();
|
||||
}
|
||||
|
||||
$('#editDisplayName').hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows/hides the display name on the remote video.
|
||||
* @param videoSpanId the identifier of the video span element
|
||||
|
|
Loading…
Reference in New Issue