Adds call support

This commit is contained in:
hristoterezov 2015-12-10 23:57:44 +11:00
parent 42473476e3
commit ac3d0858f6
8 changed files with 408 additions and 150 deletions

View File

@ -454,6 +454,45 @@ JitsiConference.prototype.toggleRecording = function (token) {
reject(new Error("The conference is not created yet!"))});
}
/**
* Dials a number.
* @param number the number
*/
JitsiConference.prototype.dial = function (number) {
if(this.room)
return this.room.dial(number);
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Hangup an existing call
*/
JitsiConference.prototype.hangup = function () {
if(this.room)
return this.room.hangup();
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Returns the phone number for joining the conference.
*/
JitsiConference.prototype.getPhoneNumber = function () {
if(this.room)
return this.room.getPhoneNumber();
return null;
}
/**
* Returns the pin for joining the conference with phone.
*/
JitsiConference.prototype.getPhonePin = function () {
if(this.room)
return this.room.getPhonePin();
return null;
}
/**
* Setups the listeners needed for the conference.
* @param conference the conference
@ -495,8 +534,16 @@ function setupListeners(conference) {
conference.room.addListener(XMPPEvents.CONNECTION_INTERRUPTED, function () {
conference.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_INTERRUPTED);
});
conference.room.addListener(XMPPEvents.RECORDING_STATE_CHANGED, function () {
conference.eventEmitter.emit(JitsiConferenceEvents.RECORDING_STATE_CHANGED);
conference.room.addListener(XMPPEvents.RECORDING_STATE_CHANGED,
function () {
conference.eventEmitter.emit(
JitsiConferenceEvents.RECORDING_STATE_CHANGED);
});
conference.room.addListener(XMPPEvents.PHONE_NUMBER_CHANGED, function () {
conference.eventEmitter.emit(
JitsiConferenceEvents.PHONE_NUMBER_CHANGED);
});
conference.room.addListener(XMPPEvents.CONNECTION_RESTORED, function () {

View File

@ -87,7 +87,11 @@ var JitsiConferenceEvents = {
/**
* Indicates that recording state changed.
*/
RECORDING_STATE_CHANGED: "conference.recordingStateChanged"
RECORDING_STATE_CHANGED: "conference.recordingStateChanged",
/**
* Indicates that phone number changed.
*/
PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged"
};
module.exports = JitsiConferenceEvents;

View File

@ -1,5 +1,7 @@
var options = {
hosts: {
call_control: "callcontrol.chaos.hipchat.me",
focus: "focus.chaos.hipchat.me",
domain: 'chaos.hipchat.me',
muc: 'conference.chaos.hipchat.me', // FIXME: use XEP-0030
bridge: 'jitsi-videobridge.chaos.hipchat.me', // FIXME: use XEP-0030
@ -37,8 +39,8 @@ function onLocalTracks(tracks)
$("body").append("<video autoplay='1' id='localVideo" + i + "' />");
localTracks[i].attach($("#localVideo" + i ));
} else {
$("body").append("<audio autoplay='1' id='localAudio" + i + "' />");
localTracks[i].attach($("#localAudio" + i ));
// $("body").append("<audio autoplay='1' id='localAudio" + i + "' />");
// localTracks[i].attach($("#localAudio" + i ));
}
}
}
@ -85,6 +87,7 @@ function onConferenceJoined () {
}
function onUserLeft(id) {
console.log("user left");
if(!remoteTracks[id])
return;
var tracks = remoteTracks[id];
@ -96,13 +99,13 @@ function onUserLeft(id) {
* That function is called when connection is established successfully
*/
function onConnectionSuccess(){
room = connection.initJitsiConference("conference2", confOptions);
room = connection.initJitsiConference("conference6", confOptions);
room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function (track) {
console.debug("track removed!!!" + track);
});
room.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
room.on(JitsiMeetJS.events.conference.USER_JOINED, function(id){ remoteTracks[id] = [];});
room.on(JitsiMeetJS.events.conference.USER_JOINED, function(id){ console.log("user join");remoteTracks[id] = [];});
room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
room.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, function (track) {
console.debug(track.getType() + " - " + track.isMuted());
@ -118,7 +121,12 @@ function onConnectionSuccess(){
console.log(room.isRecordingSupported() + " - " +
room.getRecordingState() + " - " +
room.getRecordingURL());
})
});
room.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, function () {
console.log(
room.getPhoneNumber() + " - " +
room.getPhonePin());
});
room.join();
};

View File

@ -456,6 +456,45 @@ JitsiConference.prototype.toggleRecording = function (token) {
reject(new Error("The conference is not created yet!"))});
}
/**
* Dials a number.
* @param number the number
*/
JitsiConference.prototype.dial = function (number) {
if(this.room)
return this.room.dial(number);
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Hangup an existing call
*/
JitsiConference.prototype.hangup = function () {
if(this.room)
return this.room.hangup();
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Returns the phone number for joining the conference.
*/
JitsiConference.prototype.getPhoneNumber = function () {
if(this.room)
return this.room.getPhoneNumber();
return null;
}
/**
* Returns the pin for joining the conference with phone.
*/
JitsiConference.prototype.getPhonePin = function () {
if(this.room)
return this.room.getPhonePin();
return null;
}
/**
* Setups the listeners needed for the conference.
* @param conference the conference
@ -497,8 +536,16 @@ function setupListeners(conference) {
conference.room.addListener(XMPPEvents.CONNECTION_INTERRUPTED, function () {
conference.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_INTERRUPTED);
});
conference.room.addListener(XMPPEvents.RECORDING_STATE_CHANGED, function () {
conference.eventEmitter.emit(JitsiConferenceEvents.RECORDING_STATE_CHANGED);
conference.room.addListener(XMPPEvents.RECORDING_STATE_CHANGED,
function () {
conference.eventEmitter.emit(
JitsiConferenceEvents.RECORDING_STATE_CHANGED);
});
conference.room.addListener(XMPPEvents.PHONE_NUMBER_CHANGED, function () {
conference.eventEmitter.emit(
JitsiConferenceEvents.PHONE_NUMBER_CHANGED);
});
conference.room.addListener(XMPPEvents.CONNECTION_RESTORED, function () {
@ -666,7 +713,11 @@ var JitsiConferenceEvents = {
/**
* Indicates that recording state changed.
*/
RECORDING_STATE_CHANGED: "conference.recordingStateChanged"
RECORDING_STATE_CHANGED: "conference.recordingStateChanged",
/**
* Indicates that phone number changed.
*/
PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged"
};
module.exports = JitsiConferenceEvents;
@ -5830,6 +5881,8 @@ function ChatRoom(connection, jid, password, XMPP, options) {
this.session = null;
var self = this;
this.lastPresences = {};
this.phoneNumber = null;
this.phonePin = null;
}
ChatRoom.prototype.initPresenceMap = function () {
@ -5947,6 +6000,7 @@ ChatRoom.prototype.createNonAnonymousRoom = function () {
};
ChatRoom.prototype.onPresence = function (pres) {
console.log(pres);
var from = pres.getAttribute('from');
// Parse roles.
var member = {};
@ -6000,6 +6054,16 @@ ChatRoom.prototype.onPresence = function (pres) {
break;
case "jibri-recording-status":
var jibri = node;
break;
case "call-control":
console.log(pres);
var att = node.attributes;
if(!att)
break;
this.phoneNumber = att.phone || null;
this.phonePin = att.pin || null;
this.eventEmitter.emit(XMPPEvents.PHONE_NUMBER_CHANGED);
break;
default :
this.processNode(node, from);
}
@ -6440,13 +6504,44 @@ ChatRoom.prototype.getRecordingURL = function () {
* @param token token for authentication
*/
ChatRoom.prototype.toggleRecording = function (token) {
if(this.recording/** && this.isModerator()**/)
if(this.recording)
return this.recording.toggleRecording(token);
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Dials a number.
* @param number the number
*/
ChatRoom.prototype.dial = function (number) {
return this.connection.rayo.dial(number, "fromnumber",
Strophe.getNodeFromJid(this.myroomjid), this.password,
this.focusMucJid);
}
/**
* Hangup an existing call
*/
ChatRoom.prototype.hangup = function () {
return this.connection.rayo.hangup();
}
/**
* Returns the phone number for joining the conference.
*/
ChatRoom.prototype.getPhoneNumber = function () {
return this.phoneNumber;
}
/**
* Returns the pin for joining the conference with phone.
*/
ChatRoom.prototype.getPhonePin = function () {
return this.phonePin;
}
module.exports = ChatRoom;
}).call(this,"/modules/xmpp/ChatRoom.js")
@ -10582,9 +10677,11 @@ module.exports = Moderator;
}).call(this,"/modules/xmpp/moderator.js")
},{"../../service/authentication/AuthenticationEvents":87,"../../service/xmpp/XMPPEvents":91,"../settings/Settings":21,"jitsi-meet-logger":48}],35:[function(require,module,exports){
(function (__filename){
/* global $, $iq, config, connection, focusMucJid, messageHandler,
Toolbar, Util, Promise */
var XMPPEvents = require("../../service/XMPP/XMPPEvents");
var logger = require("jitsi-meet-logger").getLogger(__filename);
function Recording(ee, connection, focusMucJid) {
this.eventEmitter = ee;
@ -10624,7 +10721,7 @@ Recording.prototype.setRecording = function (state, streamId, callback,
streamid: streamId
}).up();
console.log('Set jibri recording: '+state, iq);
logger.log('Set jibri recording: '+state, iq);
this.connection.sendIQ(
iq,
@ -10633,7 +10730,7 @@ Recording.prototype.setRecording = function (state, streamId, callback,
$(result).find('jibri').attr('url'));
},
function (error) {
console.log('Failed to start recording, error: ', error);
logger.log('Failed to start recording, error: ', error);
errCallback(error);
});
};
@ -10642,8 +10739,14 @@ Recording.prototype.toggleRecording = function (token) {
var self = this;
return new Promise(function(resolve, reject) {
if (!token) {
console.error("No token passed!");
reject(new Error("No token passed!"));
logger.error("No token passed!");
return;
}
if(self.state === "on") {
reject(new Error("Recording is already started!"));
logger.error("Recording is already started!");
return;
}
var oldState = self.state;
@ -10652,7 +10755,7 @@ Recording.prototype.toggleRecording = function (token) {
self.setRecording(newState,
token,
function (state, url) {
console.log("New recording state: ", state);
logger.log("New recording state: ", state);
if (state && state !== oldState) {
self.state = state;
self.url = url;
@ -10692,7 +10795,8 @@ Recording.prototype.getURL = function () {
module.exports = Recording;
},{"../../service/XMPP/XMPPEvents":86}],36:[function(require,module,exports){
}).call(this,"/modules/xmpp/recording.js")
},{"../../service/XMPP/XMPPEvents":86,"jitsi-meet-logger":48}],36:[function(require,module,exports){
(function (__filename){
/* jshint -W117 */
/* a simple MUC connection plugin
@ -11251,85 +11355,102 @@ module.exports = function() {
}
this.connection.addHandler(
this.onRayo.bind(this),
this.RAYO_XMLNS, 'iq', 'set', null, null);
this.onRayo.bind(this), this.RAYO_XMLNS, 'iq', 'set',
null, null);
},
onRayo: function (iq) {
logger.info("Rayo IQ", iq);
},
dial: function (to, from, roomName, roomPass) {
dial: function (to, from, roomName, roomPass, focusMucJid) {
var self = this;
var req = $iq(
{
type: 'set',
to: this.connection.emuc.focusMucJid
return new Promise(function (resolve, reject) {
if(self.call_resource) {
reject(new Error("There is already started call!"));
return;
}
);
req.c('dial',
{
xmlns: this.RAYO_XMLNS,
to: to,
from: from
});
req.c('header',
{
name: 'JvbRoomName',
value: roomName
}).up();
if (roomPass !== null && roomPass.length) {
if(!focusMucJid) {
reject(new Error("Internal error!"));
return;
}
var req = $iq(
{
type: 'set',
to: focusMucJid
}
);
req.c('dial',
{
xmlns: self.RAYO_XMLNS,
to: to,
from: from
});
req.c('header',
{
name: 'JvbRoomPassword',
value: roomPass
name: 'JvbRoomName',
value: roomName
}).up();
}
this.connection.sendIQ(
req,
function (result) {
logger.info('Dial result ', result);
if (roomPass !== null && roomPass.length) {
var resource = $(result).find('ref').attr('uri');
this.call_resource = resource.substr('xmpp:'.length);
logger.info(
"Received call resource: " + this.call_resource);
},
function (error) {
logger.info('Dial error ', error);
req.c('header',
{
name: 'JvbRoomPassword',
value: roomPass
}).up();
}
);
self.connection.sendIQ(
req,
function (result) {
logger.info('Dial result ', result);
var resource = $(result).find('ref').attr('uri');
self.call_resource = resource.substr('xmpp:'.length);
logger.info(
"Received call resource: " + self.call_resource);
resolve();
},
function (error) {
logger.info('Dial error ', error);
reject(error);
}
);
});
},
hang_up: function () {
if (!this.call_resource) {
logger.warn("No call in progress");
return;
}
hangup: function () {
var self = this;
var req = $iq(
{
type: 'set',
to: this.call_resource
return new Promise(function (resolve, reject) {
if (!self.call_resource) {
reject(new Error("No call in progress"));
logger.warn("No call in progress");
return;
}
);
req.c('hangup',
{
xmlns: this.RAYO_XMLNS
});
this.connection.sendIQ(
req,
function (result) {
logger.info('Hangup result ', result);
self.call_resource = null;
},
function (error) {
logger.info('Hangup error ', error);
self.call_resource = null;
}
);
var req = $iq(
{
type: 'set',
to: self.call_resource
}
);
req.c('hangup',
{
xmlns: self.RAYO_XMLNS
});
self.connection.sendIQ(
req,
function (result) {
logger.info('Hangup result ', result);
self.call_resource = null;
resolve();
},
function (error) {
logger.info('Hangup error ', error);
self.call_resource = null;
reject(new Error('Hangup error '));
}
);
});
}
}
);
@ -22915,7 +23036,11 @@ var XMPPEvents = {
/**
* Indicates that recording state changed.
*/
RECORDING_STATE_CHANGED: "xmpp.recordingStateChanged"
RECORDING_STATE_CHANGED: "xmpp.recordingStateChanged",
/**
* Indicates that phone number changed.
*/
PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged"
};
module.exports = XMPPEvents;

View File

@ -80,6 +80,8 @@ function ChatRoom(connection, jid, password, XMPP, options) {
this.session = null;
var self = this;
this.lastPresences = {};
this.phoneNumber = null;
this.phonePin = null;
}
ChatRoom.prototype.initPresenceMap = function () {
@ -197,6 +199,7 @@ ChatRoom.prototype.createNonAnonymousRoom = function () {
};
ChatRoom.prototype.onPresence = function (pres) {
console.log(pres);
var from = pres.getAttribute('from');
// Parse roles.
var member = {};
@ -250,6 +253,16 @@ ChatRoom.prototype.onPresence = function (pres) {
break;
case "jibri-recording-status":
var jibri = node;
break;
case "call-control":
console.log(pres);
var att = node.attributes;
if(!att)
break;
this.phoneNumber = att.phone || null;
this.phonePin = att.pin || null;
this.eventEmitter.emit(XMPPEvents.PHONE_NUMBER_CHANGED);
break;
default :
this.processNode(node, from);
}
@ -690,11 +703,42 @@ ChatRoom.prototype.getRecordingURL = function () {
* @param token token for authentication
*/
ChatRoom.prototype.toggleRecording = function (token) {
if(this.recording/** && this.isModerator()**/)
if(this.recording)
return this.recording.toggleRecording(token);
return new Promise(function(resolve, reject){
reject(new Error("The conference is not created yet!"))});
}
/**
* Dials a number.
* @param number the number
*/
ChatRoom.prototype.dial = function (number) {
return this.connection.rayo.dial(number, "fromnumber",
Strophe.getNodeFromJid(this.myroomjid), this.password,
this.focusMucJid);
}
/**
* Hangup an existing call
*/
ChatRoom.prototype.hangup = function () {
return this.connection.rayo.hangup();
}
/**
* Returns the phone number for joining the conference.
*/
ChatRoom.prototype.getPhoneNumber = function () {
return this.phoneNumber;
}
/**
* Returns the pin for joining the conference with phone.
*/
ChatRoom.prototype.getPhonePin = function () {
return this.phonePin;
}
module.exports = ChatRoom;

View File

@ -1,6 +1,7 @@
/* global $, $iq, config, connection, focusMucJid, messageHandler,
Toolbar, Util, Promise */
var XMPPEvents = require("../../service/XMPP/XMPPEvents");
var logger = require("jitsi-meet-logger").getLogger(__filename);
function Recording(ee, connection, focusMucJid) {
this.eventEmitter = ee;
@ -40,7 +41,7 @@ Recording.prototype.setRecording = function (state, streamId, callback,
streamid: streamId
}).up();
console.log('Set jibri recording: '+state, iq);
logger.log('Set jibri recording: '+state, iq);
this.connection.sendIQ(
iq,
@ -49,7 +50,7 @@ Recording.prototype.setRecording = function (state, streamId, callback,
$(result).find('jibri').attr('url'));
},
function (error) {
console.log('Failed to start recording, error: ', error);
logger.log('Failed to start recording, error: ', error);
errCallback(error);
});
};
@ -58,8 +59,14 @@ Recording.prototype.toggleRecording = function (token) {
var self = this;
return new Promise(function(resolve, reject) {
if (!token) {
console.error("No token passed!");
reject(new Error("No token passed!"));
logger.error("No token passed!");
return;
}
if(self.state === "on") {
reject(new Error("Recording is already started!"));
logger.error("Recording is already started!");
return;
}
var oldState = self.state;
@ -68,7 +75,7 @@ Recording.prototype.toggleRecording = function (token) {
self.setRecording(newState,
token,
function (state, url) {
console.log("New recording state: ", state);
logger.log("New recording state: ", state);
if (state && state !== oldState) {
self.state = state;
self.url = url;

View File

@ -13,85 +13,104 @@ module.exports = function() {
}
this.connection.addHandler(
this.onRayo.bind(this),
this.RAYO_XMLNS, 'iq', 'set', null, null);
this.onRayo.bind(this), this.RAYO_XMLNS, 'iq', 'set',
null, null);
},
onRayo: function (iq) {
logger.info("Rayo IQ", iq);
},
dial: function (to, from, roomName, roomPass) {
dial: function (to, from, roomName, roomPass, focusMucJid) {
var self = this;
var req = $iq(
{
type: 'set',
to: this.connection.emuc.focusMucJid
return new Promise(function (resolve, reject) {
if(self.call_resource) {
reject(new Error("There is already started call!"));
return;
}
);
req.c('dial',
{
xmlns: this.RAYO_XMLNS,
to: to,
from: from
});
req.c('header',
{
name: 'JvbRoomName',
value: roomName
}).up();
if (roomPass !== null && roomPass.length) {
if(!focusMucJid) {
reject(new Error("Internal error!"));
return;
}
var req = $iq(
{
type: 'set',
to: focusMucJid
}
);
req.c('dial',
{
xmlns: self.RAYO_XMLNS,
to: to,
from: from
});
req.c('header',
{
name: 'JvbRoomPassword',
value: roomPass
name: 'JvbRoomName',
value: roomName
}).up();
}
this.connection.sendIQ(
req,
function (result) {
logger.info('Dial result ', result);
if (roomPass !== null && roomPass.length) {
var resource = $(result).find('ref').attr('uri');
this.call_resource = resource.substr('xmpp:'.length);
logger.info(
"Received call resource: " + this.call_resource);
},
function (error) {
logger.info('Dial error ', error);
req.c('header',
{
name: 'JvbRoomPassword',
value: roomPass
}).up();
}
);
self.connection.sendIQ(
req,
function (result) {
logger.info('Dial result ', result);
var resource = $(result).find('ref').attr('uri');
self.call_resource =
resource.substr('xmpp:'.length);
logger.info(
"Received call resource: " +
self.call_resource);
resolve();
},
function (error) {
logger.info('Dial error ', error);
reject(error);
}
);
});
},
hang_up: function () {
if (!this.call_resource) {
logger.warn("No call in progress");
return;
}
hangup: function () {
var self = this;
var req = $iq(
{
type: 'set',
to: this.call_resource
return new Promise(function (resolve, reject) {
if (!self.call_resource) {
reject(new Error("No call in progress"));
logger.warn("No call in progress");
return;
}
);
req.c('hangup',
{
xmlns: this.RAYO_XMLNS
});
this.connection.sendIQ(
req,
function (result) {
logger.info('Hangup result ', result);
self.call_resource = null;
},
function (error) {
logger.info('Hangup error ', error);
self.call_resource = null;
}
);
var req = $iq(
{
type: 'set',
to: self.call_resource
}
);
req.c('hangup',
{
xmlns: self.RAYO_XMLNS
});
self.connection.sendIQ(
req,
function (result) {
logger.info('Hangup result ', result);
self.call_resource = null;
resolve();
},
function (error) {
logger.info('Hangup error ', error);
self.call_resource = null;
reject(new Error('Hangup error '));
}
);
});
}
}
);

View File

@ -101,6 +101,10 @@ var XMPPEvents = {
/**
* Indicates that recording state changed.
*/
RECORDING_STATE_CHANGED: "xmpp.recordingStateChanged"
RECORDING_STATE_CHANGED: "xmpp.recordingStateChanged",
/**
* Indicates that phone number changed.
*/
PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged"
};
module.exports = XMPPEvents;