working example
This commit is contained in:
commit
9b92824540
|
@ -0,0 +1,314 @@
|
|||
/* global $, JitsiMeetJS */
|
||||
|
||||
/*
|
||||
const options = {
|
||||
hosts: {
|
||||
domain: 'jitsi-meet.example.com',
|
||||
muc: 'conference.jitsi-meet.example.com' // FIXME: use XEP-0030
|
||||
},
|
||||
bosh: '//jitsi-meet.example.com/http-bind', // FIXME: use xep-0156 for that
|
||||
|
||||
// The name of client node advertised in XEP-0115 'c' stanza
|
||||
clientNode: 'http://jitsi.org/jitsimeet'
|
||||
}; */
|
||||
|
||||
const options = {
|
||||
hosts: {
|
||||
domain: 'beta.meet.jit.si',
|
||||
muc: 'conference.beta.meet.jit.si' // FIXME: use XEP-0030
|
||||
},
|
||||
bosh: 'https://beta.meet.jit.si/http-bind', // FIXME: use xep-0156 for that
|
||||
|
||||
// The name of client node advertised in XEP-0115 'c' stanza
|
||||
clientNode: 'http://jitsi.org/jitsimeet'
|
||||
};
|
||||
|
||||
const confOptions = {
|
||||
openBridgeChannel: true
|
||||
};
|
||||
|
||||
let connection = null;
|
||||
let isJoined = false;
|
||||
let room = null;
|
||||
|
||||
let localTracks = [];
|
||||
const remoteTracks = {};
|
||||
|
||||
/**
|
||||
* Handles local tracks.
|
||||
* @param tracks Array with JitsiTrack objects
|
||||
*/
|
||||
function onLocalTracks(tracks) {
|
||||
localTracks = tracks;
|
||||
for (let i = 0; i < localTracks.length; i++) {
|
||||
localTracks[i].addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
audioLevel => console.log(`Audio Level local: ${audioLevel}`));
|
||||
localTracks[i].addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
|
||||
() => console.log('local track muted'));
|
||||
localTracks[i].addEventListener(
|
||||
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
|
||||
() => console.log('local track stoped'));
|
||||
localTracks[i].addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
|
||||
deviceId =>
|
||||
console.log(
|
||||
`track audio output device was changed to ${deviceId}`));
|
||||
if (localTracks[i].getType() === 'video') {
|
||||
$('body').append(`<video autoplay='1' id='localVideo${i}' />`);
|
||||
localTracks[i].attach($(`#localVideo${i}`)[0]);
|
||||
} else {
|
||||
$('body').append(
|
||||
`<audio autoplay='1' muted='true' id='localAudio${i}' />`);
|
||||
localTracks[i].attach($(`#localAudio${i}`)[0]);
|
||||
}
|
||||
if (isJoined) {
|
||||
room.addTrack(localTracks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles remote tracks
|
||||
* @param track JitsiTrack object
|
||||
*/
|
||||
function onRemoteTrack(track) {
|
||||
if (track.isLocal()) {
|
||||
return;
|
||||
}
|
||||
const participant = track.getParticipantId();
|
||||
|
||||
if (!remoteTracks[participant]) {
|
||||
remoteTracks[participant] = [];
|
||||
}
|
||||
const idx = remoteTracks[participant].push(track);
|
||||
|
||||
track.addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
audioLevel => console.log(`Audio Level remote: ${audioLevel}`));
|
||||
track.addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
|
||||
() => console.log('remote track muted'));
|
||||
track.addEventListener(
|
||||
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
|
||||
() => console.log('remote track stoped'));
|
||||
track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
|
||||
deviceId =>
|
||||
console.log(
|
||||
`track audio output device was changed to ${deviceId}`));
|
||||
const id = participant + track.getType() + idx;
|
||||
|
||||
if (track.getType() === 'video') {
|
||||
$('body').append(
|
||||
`<video autoplay='1' id='${participant}video${idx}' />`);
|
||||
} else {
|
||||
$('body').append(
|
||||
`<audio autoplay='1' id='${participant}audio${idx}' />`);
|
||||
}
|
||||
track.attach($(`#${id}`)[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* That function is executed when the conference is joined
|
||||
*/
|
||||
function onConferenceJoined() {
|
||||
console.log('conference joined!');
|
||||
isJoined = true;
|
||||
for (let i = 0; i < localTracks.length; i++) {
|
||||
room.addTrack(localTracks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
function onUserLeft(id) {
|
||||
console.log('user left');
|
||||
if (!remoteTracks[id]) {
|
||||
return;
|
||||
}
|
||||
const tracks = remoteTracks[id];
|
||||
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
tracks[i].detach($(`#${id}${tracks[i].getType()}`));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* That function is called when connection is established successfully
|
||||
*/
|
||||
function onConnectionSuccess() {
|
||||
room = connection.initJitsiConference('testfoobar', confOptions);
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, track => {
|
||||
console.log(`track removed!!!${track}`);
|
||||
});
|
||||
room.on(
|
||||
JitsiMeetJS.events.conference.CONFERENCE_JOINED,
|
||||
onConferenceJoined);
|
||||
room.on(JitsiMeetJS.events.conference.USER_JOINED, id => {
|
||||
console.log('user join');
|
||||
remoteTracks[id] = [];
|
||||
});
|
||||
room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
|
||||
room.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, track => {
|
||||
console.log(`${track.getType()} - ${track.isMuted()}`);
|
||||
});
|
||||
room.on(
|
||||
JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED,
|
||||
(userID, displayName) => console.log(`${userID} - ${displayName}`));
|
||||
room.on(
|
||||
JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED,
|
||||
(userID, audioLevel) => console.log(`${userID} - ${audioLevel}`));
|
||||
room.on(
|
||||
JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED,
|
||||
() => console.log(`${room.getPhoneNumber()} - ${room.getPhonePin()}`));
|
||||
room.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the connection fail.
|
||||
*/
|
||||
function onConnectionFailed() {
|
||||
console.error('Connection Failed!');
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the connection fail.
|
||||
*/
|
||||
function onDeviceListChanged(devices) {
|
||||
console.info('current devices', devices);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when we disconnect.
|
||||
*/
|
||||
function disconnect() {
|
||||
console.log('disconnect!');
|
||||
connection.removeEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
|
||||
onConnectionSuccess);
|
||||
connection.removeEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_FAILED,
|
||||
onConnectionFailed);
|
||||
connection.removeEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
|
||||
disconnect);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function unload() {
|
||||
for (let i = 0; i < localTracks.length; i++) {
|
||||
localTracks[i].dispose();
|
||||
}
|
||||
room.leave();
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
let isVideo = true;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function switchVideo() { // eslint-disable-line no-unused-vars
|
||||
isVideo = !isVideo;
|
||||
if (localTracks[1]) {
|
||||
localTracks[1].dispose();
|
||||
localTracks.pop();
|
||||
}
|
||||
JitsiMeetJS.createLocalTracks({
|
||||
devices: [ isVideo ? 'video' : 'desktop' ]
|
||||
})
|
||||
.then(tracks => {
|
||||
localTracks.push(tracks[0]);
|
||||
localTracks[1].addEventListener(
|
||||
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
|
||||
() => console.log('local track muted'));
|
||||
localTracks[1].addEventListener(
|
||||
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
|
||||
() => console.log('local track stoped'));
|
||||
localTracks[1].attach($('#localVideo1')[0]);
|
||||
room.addTrack(localTracks[1]);
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param selected
|
||||
*/
|
||||
function changeAudioOutput(selected) { // eslint-disable-line no-unused-vars
|
||||
JitsiMeetJS.mediaDevices.setAudioOutputDevice(selected.value);
|
||||
}
|
||||
|
||||
$(window).bind('beforeunload', unload);
|
||||
$(window).bind('unload', unload);
|
||||
|
||||
// JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
|
||||
const initOptions = {
|
||||
disableAudioLevels: true,
|
||||
|
||||
// The ID of the jidesha extension for Chrome.
|
||||
desktopSharingChromeExtId: 'mbocklcggfhnbahlnepmldehdhpjfcjp',
|
||||
|
||||
// Whether desktop sharing should be disabled on Chrome.
|
||||
desktopSharingChromeDisabled: false,
|
||||
|
||||
// The media sources to use when using screen sharing with the Chrome
|
||||
// extension.
|
||||
desktopSharingChromeSources: [ 'screen', 'window' ],
|
||||
|
||||
// Required version of Chrome extension
|
||||
desktopSharingChromeMinExtVersion: '0.1',
|
||||
|
||||
// Whether desktop sharing should be disabled on Firefox.
|
||||
desktopSharingFirefoxDisabled: true
|
||||
};
|
||||
|
||||
JitsiMeetJS.init(initOptions);
|
||||
|
||||
connection = new JitsiMeetJS.JitsiConnection(null, null, options);
|
||||
|
||||
connection.addEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
|
||||
onConnectionSuccess);
|
||||
connection.addEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_FAILED,
|
||||
onConnectionFailed);
|
||||
connection.addEventListener(
|
||||
JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
|
||||
disconnect);
|
||||
|
||||
JitsiMeetJS.mediaDevices.addEventListener(
|
||||
JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED,
|
||||
onDeviceListChanged);
|
||||
|
||||
connection.connect();
|
||||
|
||||
JitsiMeetJS.createLocalTracks({ devices: [ 'audio', 'video' ] })
|
||||
.then(onLocalTracks)
|
||||
.catch(error => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output')) {
|
||||
JitsiMeetJS.mediaDevices.enumerateDevices(devices => {
|
||||
const audioOutputDevices
|
||||
= devices.filter(d => d.kind === 'audiooutput');
|
||||
|
||||
if (audioOutputDevices.length > 1) {
|
||||
$('#audioOutputSelect').html(
|
||||
audioOutputDevices
|
||||
.map(
|
||||
d =>
|
||||
`<option value="${d.deviceId}">${d.label}</option>`)
|
||||
.join('\n'));
|
||||
|
||||
$('#audioOutputSelectWrapper').show();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<script src="libs/jquery-2.1.1.min.js"></script>
|
||||
<script src="libs/strophe/strophe.js"></script>
|
||||
<script src="libs/strophe/strophe.disco.min.js?v=1"></script>
|
||||
<script src="https://meet.jit.si/libs/lib-jitsi-meet.min.js"></script>
|
||||
<script src="example.js" ></script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="#" onclick="unload()">Unload</a>
|
||||
<a href="#" onclick="switchVideo()">switchVideo</a>
|
||||
<div id="audioOutputSelectWrapper" style="display: none;">
|
||||
Change audio output device
|
||||
<select id="audioOutputSelect" onchange="changeAudioOutput(this)"></select>
|
||||
</div>
|
||||
<!-- <video id="localVideo" autoplay="true"></video> -->
|
||||
<!--<audio id="localAudio" autoplay="true" muted="true"></audio>-->
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
Strophe.addConnectionPlugin("disco",{_connection:null,_identities:[],_features:[],_items:[],init:function(conn){this._connection=conn;this._identities=[];this._features=[];this._items=[];conn.addHandler(this._onDiscoInfo.bind(this),Strophe.NS.DISCO_INFO,"iq","get",null,null);conn.addHandler(this._onDiscoItems.bind(this),Strophe.NS.DISCO_ITEMS,"iq","get",null,null)},addIdentity:function(category,type,name,lang){for(var i=0;i<this._identities.length;i++){if(this._identities[i].category==category&&this._identities[i].type==type&&this._identities[i].name==name&&this._identities[i].lang==lang){return false}}this._identities.push({category:category,type:type,name:name,lang:lang});return true},addFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]==var_name){return false}}this._features.push(var_name);return true},removeFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]===var_name){this._features.splice(i,1);return true}}return false},addItem:function(jid,name,node,call_back){if(node&&!call_back){return false}this._items.push({jid:jid,name:name,node:node,call_back:call_back});return true},info:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var info=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(info,success,error,timeout)},items:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_ITEMS};if(node){attrs.node=node}var items=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(items,success,error,timeout)},_buildIQResult:function(stanza,query_attrs){var id=stanza.getAttribute("id");var from=stanza.getAttribute("from");var iqresult=$iq({type:"result",id:id});if(from!==null){iqresult.attrs({to:from})}return iqresult.c("query",query_attrs)},_onDiscoInfo:function(stanza){var node=stanza.getElementsByTagName("query")[0].getAttribute("node");var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var iqresult=this._buildIQResult(stanza,attrs);for(var i=0;i<this._identities.length;i++){var attrs={category:this._identities[i].category,type:this._identities[i].type};if(this._identities[i].name){attrs.name=this._identities[i].name}if(this._identities[i].lang){attrs["xml:lang"]=this._identities[i].lang}iqresult.c("identity",attrs).up()}for(var i=0;i<this._features.length;i++){iqresult.c("feature",{"var":this._features[i]}).up()}this._connection.send(iqresult.tree());return true},_onDiscoItems:function(stanza){var query_attrs={xmlns:Strophe.NS.DISCO_ITEMS};var node=stanza.getElementsByTagName("query")[0].getAttribute("node");if(node){query_attrs.node=node;var items=[];for(var i=0;i<this._items.length;i++){if(this._items[i].node==node){items=this._items[i].call_back(stanza);break}}}else{var items=this._items}var iqresult=this._buildIQResult(stanza,query_attrs);for(var i=0;i<items.length;i++){var attrs={jid:items[i].jid};if(items[i].name){attrs.name=items[i].name}if(items[i].node){attrs.node=items[i].node}iqresult.c("item",attrs).up()}this._connection.send(iqresult.tree());return true}});
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue