Included extra BigBlueButton messages to connect a listen only user
This commit is contained in:
parent
11e6c445da
commit
722ab679e3
@ -57,7 +57,7 @@ module.exports = class AudioManager {
|
||||
this._audioSessions[sessionId] = session;
|
||||
|
||||
// starts audio session by sending sessionID, websocket and sdpoffer
|
||||
session.start(sessionId, connectionId, message.sdpOffer, message.callerName, (error, sdpAnswer) => {
|
||||
session.start(sessionId, connectionId, message.sdpOffer, message.callerName, message.userId, message.userName, (error, sdpAnswer) => {
|
||||
Logger.info("[AudioManager] Started presenter ", sessionId, " for connection", connectionId);
|
||||
Logger.debug("[AudioManager] SDP answer was", sdpAnswer);
|
||||
if (error) {
|
||||
|
@ -6,7 +6,7 @@ const kurentoUrl = config.get('kurentoUrl');
|
||||
const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
|
||||
const C = require('../bbb/messages/Constants');
|
||||
const Logger = require('../utils/Logger');
|
||||
|
||||
const Messaging = require('../bbb/messages/Messaging');
|
||||
|
||||
module.exports = class Audio {
|
||||
constructor(_bbbGW, _id, voiceBridge) {
|
||||
@ -21,6 +21,7 @@ module.exports = class Audio {
|
||||
this.webRtcEndpoint = null;
|
||||
this.userId;
|
||||
|
||||
this.connectedUsers = {};
|
||||
this.candidatesQueue = {}
|
||||
}
|
||||
|
||||
@ -56,6 +57,43 @@ module.exports = class Audio {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Include user to a hash object indexed by it's connectionId
|
||||
* @param {String} connectionId Current connection id at the media manager
|
||||
* @param {Object} user {userId: String, userName: String}
|
||||
*/
|
||||
addUser(connectionId, user) {
|
||||
if (this.connectedUsers.hasOwnProperty(connectionId)) {
|
||||
Logger.warn("[audio] Updating user for connectionId", connectionId)
|
||||
}
|
||||
this.connectedUsers[connectionId] = user;
|
||||
};
|
||||
|
||||
/**
|
||||
* Exclude user from a hash object indexed by it's connectionId
|
||||
* @param {String} connectionId Current connection id at the media manager
|
||||
*/
|
||||
removeUser(connectionId) {
|
||||
if (this.connectedUsers.hasOwnProperty(connectionId)) {
|
||||
delete this.connectedUsers[connectionId];
|
||||
} else {
|
||||
Logger.error("[audio] Missing connectionId", connectionId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Consult user from a hash object indexed by it's connectionId
|
||||
* @param {String} connectionId Current connection id at the media manager
|
||||
* @return {Object} user {userId: String, userName: String}
|
||||
*/
|
||||
getUser(connectionId) {
|
||||
if (this.connectedUsers.hasOwnProperty(connectionId)) {
|
||||
return this.connectedUsers[connectionId];
|
||||
} else {
|
||||
Logger.error("[audio] Missing connectionId", connectionId);
|
||||
}
|
||||
};
|
||||
|
||||
mediaState (event) {
|
||||
let msEvent = event.event;
|
||||
|
||||
@ -96,16 +134,26 @@ module.exports = class Audio {
|
||||
break;
|
||||
|
||||
case "MediaFlowInStateChange":
|
||||
Logger.info('[audio]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ', event.id);
|
||||
if (msEvent.state === 'FLOWING') {
|
||||
this._onRtpMediaFlowing(id);
|
||||
} else {
|
||||
this._onRtpMediaNotFlowing(id);
|
||||
}
|
||||
break;
|
||||
|
||||
default: Logger.warn("[audio] Unrecognized event", event);
|
||||
}
|
||||
}
|
||||
|
||||
async start (sessionId, connectionId, sdpOffer, callerName, callback) {
|
||||
async start (sessionId, connectionId, sdpOffer, callerName, userId, userName, callback) {
|
||||
Logger.info("[audio] Starting audio instance for", this.id);
|
||||
let sdpAnswer;
|
||||
|
||||
// Storing the user data to be used by the pub calls
|
||||
let user = {userId: userId, userName: userName};
|
||||
this.addUser(connectionId, user);
|
||||
|
||||
try {
|
||||
if (!this.sourceAudioStarted) {
|
||||
this.userId = await this.mcs.join(this.voiceBridge, 'SFU', {});
|
||||
@ -151,6 +199,8 @@ module.exports = class Audio {
|
||||
let listener = this.audioEndpoints[id];
|
||||
Logger.info('[audio] Releasing endpoints for', listener);
|
||||
|
||||
this.sendUserDisconnectedFromGlobalAudioMessage(id);
|
||||
|
||||
if (listener) {
|
||||
try {
|
||||
if (this.audioEndpoints && Object.keys(this.audioEndpoints).length === 1) {
|
||||
@ -187,6 +237,10 @@ module.exports = class Audio {
|
||||
delete this.candidatesQueue[queue];
|
||||
}
|
||||
|
||||
for (var connection in this.connectedUsers) {
|
||||
this.sendUserDisconnectedFromGlobalAudioMessage(connection);
|
||||
}
|
||||
|
||||
this.sourceAudioStarted = false;
|
||||
|
||||
Promise.resolve();
|
||||
@ -197,4 +251,56 @@ module.exports = class Audio {
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
sendUserDisconnectedFromGlobalAudioMessage(connectionId) {
|
||||
let user = this.getUser(connectionId);
|
||||
let msg = Messaging.generateUserDisconnectedFromGlobalAudioMessage(this.voiceBridge, user.userId, user.userName);
|
||||
Logger.info('[audio] Sending global audio disconnection for user', user);
|
||||
|
||||
// Interoperability between transcoder messages
|
||||
switch (C.COMMON_MESSAGE_VERSION) {
|
||||
case "1.x":
|
||||
this.bbbGW.publish(msg, C.TO_BBB_MEETING_CHAN, function(error) {});
|
||||
break;
|
||||
default:
|
||||
this.bbbGW.publish(msg, C.TO_AKKA_APPS_CHAN_2x, function(error) {});
|
||||
}
|
||||
|
||||
this.removeUser(connectionId);
|
||||
};
|
||||
|
||||
sendUserConnectedToGlobalAudioMessage(connectionId) {
|
||||
let user = this.getUser(connectionId);
|
||||
let msg = Messaging.generateUserConnectedToGlobalAudioMessage(this.voiceBridge, user.userId, user.userName);
|
||||
Logger.info('[audio] Sending global audio connection for user', user);
|
||||
|
||||
// Interoperability between transcoder messages
|
||||
switch (C.COMMON_MESSAGE_VERSION) {
|
||||
case "1.x":
|
||||
this.bbbGW.publish(msg, C.TO_BBB_MEETING_CHAN, function(error) {});
|
||||
break;
|
||||
default:
|
||||
this.bbbGW.publish(msg, C.TO_AKKA_APPS_CHAN_2x, function(error) {});
|
||||
}
|
||||
};
|
||||
|
||||
_onRtpMediaFlowing(connectionId) {
|
||||
Logger.info("[audio] RTP Media FLOWING for voice bridge", this.voiceBridge);
|
||||
this.sendUserConnectedToGlobalAudioMessage(connectionId);
|
||||
this.bbbGW.publish(JSON.stringify({
|
||||
connectionId: connectionId,
|
||||
id: "webRTCAudioSuccess",
|
||||
success: "MEDIA_FLOWING"
|
||||
}), C.FROM_AUDIO);
|
||||
};
|
||||
|
||||
_onRtpMediaNotFlowing(connectionId) {
|
||||
Logger.warn("[audio] RTP Media NOT FLOWING for voice bridge" + this.voiceBridge);
|
||||
this.bbbGW.publish(JSON.stringify({
|
||||
connectionId: connectionId,
|
||||
id: "webRTCAudioError",
|
||||
error: C.MEDIA_ERROR
|
||||
}), C.FROM_AUDIO);
|
||||
this.removeUser(connectionId);
|
||||
};
|
||||
};
|
||||
|
@ -29,6 +29,8 @@ const config = require('config');
|
||||
FROM_BBB_TRANSCODE_SYSTEM_CHAN : "bigbluebutton:from-bbb-transcode:system",
|
||||
FROM_VOICE_CONF_SYSTEM_CHAN: "from-voice-conf-redis-channel",
|
||||
TO_BBB_TRANSCODE_SYSTEM_CHAN: "bigbluebutton:to-bbb-transcode:system",
|
||||
TO_BBB_MEETING_CHAN: "bigbluebutton:to-bbb-apps:meeting",
|
||||
TO_AKKA_APPS_CHAN_2x: "to-akka-apps-redis-channel",
|
||||
FROM_SCREENSHARE: config.get('from-screenshare'),
|
||||
TO_SCREENSHARE: config.get('to-screenshare'),
|
||||
FROM_VIDEO: config.get('from-video'),
|
||||
@ -49,6 +51,8 @@ const config = require('config');
|
||||
STOP_TRANSCODER_REPLY: "stop_transcoder_reply_message",
|
||||
DESKSHARE_RTMP_BROADCAST_STARTED: "deskshare_rtmp_broadcast_started_message",
|
||||
DESKSHARE_RTMP_BROADCAST_STOPPED: "deskshare_rtmp_broadcast_stopped_message",
|
||||
GLOBAL_AUDIO_CONNECTED: "user_connected_to_global_audio",
|
||||
GLOBAL_AUDIO_DISCONNECTED: "user_disconnected_from_global_audio",
|
||||
|
||||
//Message identifiers 2x
|
||||
SCREENSHARE_RTMP_BROADCAST_STARTED_2x: "ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg",
|
||||
@ -57,6 +61,8 @@ const config = require('config');
|
||||
START_TRANSCODER_RESP_2x: "StartTranscoderSysRespMsg",
|
||||
STOP_TRANSCODER_REQ_2x: "StopTranscoderSysReqMsg",
|
||||
STOP_TRANSCODER_RESP_2x: "StopTranscoderSysRespMsg",
|
||||
GLOBAL_AUDIO_CONNECTED_2x: "UserConnectedToGlobalAudioMsg",
|
||||
GLOBAL_AUDIO_DISCONNECTED_2x: "UserDisconnectedFromGlobalAudioMsg",
|
||||
|
||||
USER_CAM_BROADCAST_STARTED_2x: "UserBroadcastCamStartMsg",
|
||||
USER_CAM_BROADCAST_STOPPED_2x: "UserBroadcastCamStopMsg",
|
||||
@ -86,6 +92,10 @@ const config = require('config');
|
||||
VIDEO_WIDTH: "vidWidth",
|
||||
VIDEO_HEIGHT: "vidHeight",
|
||||
|
||||
// Audio
|
||||
NAME: "name",
|
||||
USERID: "userid",
|
||||
|
||||
// RTP params
|
||||
MEETING_ID : "meeting_id",
|
||||
VOICE_CONF : "voice_conf",
|
||||
|
@ -23,6 +23,14 @@ let ScreenshareRTMPBroadcastStoppedEventMessage2x =
|
||||
let UserCamBroadcastStoppedEventMessage2x =
|
||||
require('./video/UserCamBroadcastStoppedEventMessage2x.js')(Constants);
|
||||
let WebRTCShareEvent = require('./video/WebRTCShareEvent.js')(Constants);
|
||||
let UserConnectedToGlobalAudio =
|
||||
require('./audio/UserConnectedToGlobalAudio.js')(Constants);
|
||||
let UserDisconnectedFromGlobalAudio =
|
||||
require('./audio/UserDisconnectedFromGlobalAudio.js')(Constants);
|
||||
let UserConnectedToGlobalAudio2x =
|
||||
require('./audio/UserConnectedToGlobalAudio2x.js')(Constants);
|
||||
let UserDisconnectedFromGlobalAudio2x =
|
||||
require('./audio/UserDisconnectedFromGlobalAudio2x.js')(Constants);
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
@ -78,4 +86,31 @@ Messaging.prototype.generateWebRTCShareEvent =
|
||||
let stodrbem = new WebRTCShareEvent(name, meetingId, streamUrl);
|
||||
return stodrbem.payload;
|
||||
}
|
||||
|
||||
Messaging.prototype.generateUserConnectedToGlobalAudioMessage =
|
||||
function(voiceConf, userId, name) {
|
||||
let msg;
|
||||
switch (Constants.COMMON_MESSAGE_VERSION) {
|
||||
case "1.x":
|
||||
msg = new UserConnectedToGlobalAudio(voiceConf, userId, name);
|
||||
break;
|
||||
default:
|
||||
msg = new UserConnectedToGlobalAudio2x(voiceConf, userId, name);
|
||||
}
|
||||
return msg.toJson();
|
||||
}
|
||||
|
||||
Messaging.prototype.generateUserDisconnectedFromGlobalAudioMessage =
|
||||
function(voiceConf, userId, name) {
|
||||
let msg;
|
||||
switch (Constants.COMMON_MESSAGE_VERSION) {
|
||||
case "1.x":
|
||||
msg = new UserDisconnectedFromGlobalAudio(voiceConf, userId, name);
|
||||
break;
|
||||
default:
|
||||
msg = new UserDisconnectedFromGlobalAudio2x(voiceConf, userId, name);
|
||||
}
|
||||
return msg.toJson();
|
||||
}
|
||||
|
||||
module.exports = new Messaging();
|
||||
|
@ -0,0 +1,16 @@
|
||||
var inherits = require('inherits');
|
||||
var OutMessage = require('../OutMessage');
|
||||
|
||||
module.exports = function(Constants) {
|
||||
function UserConnectedToGlobalAudio(voiceConf, userId, name) {
|
||||
UserConnectedToGlobalAudio.super_.call(this, Constants.GLOBAL_AUDIO_CONNECTED);
|
||||
|
||||
this.payload = {};
|
||||
this.payload[Constants.VOICE_CONF] = voiceConf;
|
||||
this.payload[Constants.USERID] = userId;
|
||||
this.payload[Constants.NAME] = name;
|
||||
};
|
||||
|
||||
inherits(UserConnectedToGlobalAudio, OutMessage);
|
||||
return UserConnectedToGlobalAudio;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
var inherits = require('inherits');
|
||||
var OutMessage2x = require('../OutMessage2x');
|
||||
|
||||
// TODO: Check if this is correct!
|
||||
module.exports = function(Constants) {
|
||||
function UserConnectedToGlobalAudio2x(voiceConf, userId, name) {
|
||||
UserConnectedToGlobalAudio2x.super_.call(
|
||||
this,
|
||||
Constants.GLOBAL_AUDIO_CONNECTED_2x,
|
||||
{voiceConf: voiceConf},
|
||||
{voiceConf: voiceConf}
|
||||
);
|
||||
|
||||
this.core.body = {};
|
||||
this.core.body[Constants.USER_ID_2x] = userId;
|
||||
this.core.body[Constants.NAME] = name;
|
||||
};
|
||||
|
||||
inherits(UserConnectedToGlobalAudio2x, OutMessage2x);
|
||||
return UserConnectedToGlobalAudio2x;
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
var inherits = require('inherits');
|
||||
var OutMessage = require('../OutMessage');
|
||||
|
||||
module.exports = function(Constants) {
|
||||
function UserDisconnectedFromGlobalAudio(voiceConf, userId, name) {
|
||||
UserDisconnectedFromGlobalAudio.super_.call(this, Constants.GLOBAL_AUDIO_DISCONNECTED);
|
||||
|
||||
this.payload = {};
|
||||
this.payload[Constants.VOICE_CONF] = voiceConf;
|
||||
this.payload[Constants.USERID] = userId;
|
||||
this.payload[Constants.NAME] = name;
|
||||
};
|
||||
|
||||
inherits(UserDisconnectedFromGlobalAudio, OutMessage);
|
||||
return UserDisconnectedFromGlobalAudio;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
var inherits = require('inherits');
|
||||
var OutMessage2x = require('../OutMessage2x');
|
||||
|
||||
// TODO: Check if this is correct!
|
||||
module.exports = function(Constants) {
|
||||
function UserDisconnectedFromGlobalAudio2x(voiceConf, userId, name) {
|
||||
UserDisconnectedFromGlobalAudio2x.super_.call(
|
||||
this,
|
||||
Constants.GLOBAL_AUDIO_DISCONNECTED_2x,
|
||||
{voiceConf: voiceConf},
|
||||
{voiceConf: voiceConf}
|
||||
);
|
||||
|
||||
this.core.body = {};
|
||||
this.core.body[Constants.USER_ID_2x] = userId;
|
||||
this.core.body[Constants.NAME] = name;
|
||||
};
|
||||
|
||||
inherits(UserDisconnectedFromGlobalAudio2x, OutMessage2x);
|
||||
return UserDisconnectedFromGlobalAudio2x;
|
||||
};
|
Loading…
Reference in New Issue
Block a user