diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala index bc938437c07663a8f70a7bc9d6ba1e0bd7518adb..937ebd1cc0b65ae8f38992e502a1345780535e75 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala @@ -40,7 +40,9 @@ trait UserConnectedToGlobalAudioMsgHdlr { talking = false, listenOnly = true, "kms", - System.currentTimeMillis() + System.currentTimeMillis(), + floor = false, + lastFloorTime = "0", ) VoiceUsers.add(liveMeeting.voiceUsers, vu) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/AudioFloorChangedVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/AudioFloorChangedVoiceConfEvtMsgHdlr.scala new file mode 100644 index 0000000000000000000000000000000000000000..eaeea145a0c50d9c9336891a169ea92b106f531e --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/AudioFloorChangedVoiceConfEvtMsgHdlr.scala @@ -0,0 +1,61 @@ +package org.bigbluebutton.core.apps.voice + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers } +import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } + +trait AudioFloorChangedVoiceConfEvtMsgHdlr { + this: BaseMeetingActor => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleAudioFloorChangedVoiceConfEvtMsg(msg: AudioFloorChangedVoiceConfEvtMsg): Unit = { + + def broadcastEvent(vu: VoiceUserState): Unit = { + val routing = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + liveMeeting.props.meetingProp.intId, + vu.intId + ) + val envelope = BbbCoreEnvelope(AudioFloorChangedEvtMsg.NAME, routing) + val header = BbbClientMsgHeader( + AudioFloorChangedEvtMsg.NAME, + liveMeeting.props.meetingProp.intId, vu.intId + ) + + val body = AudioFloorChangedEvtMsgBody( + voiceConf = msg.header.voiceConf, + intId = vu.intId, + voiceUserId = vu.voiceUserId, + floor = vu.floor, + lastFloorTime = msg.body.floorTimestamp + ) + + val event = AudioFloorChangedEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + outGW.send(msgEvent) + } + + for { + oldFloorUser <- VoiceUsers.releasedFloor( + liveMeeting.voiceUsers, + msg.body.oldVoiceUserId, + floor = false + ) + } yield { + broadcastEvent(oldFloorUser) + } + + for { + newFloorUser <- VoiceUsers.becameFloor( + liveMeeting.voiceUsers, + msg.body.voiceUserId, + true, + msg.body.floorTimestamp + ) + } yield { + broadcastEvent(newFloorUser) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala index 4a49d961f1e4155bcf0f983a75b945551e08815e..e0ba15cdc9787795907ed5716214dc7830144bdb 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala @@ -268,7 +268,9 @@ object VoiceApp extends SystemConfiguration { talking, listenOnly = isListenOnly, callingInto, - System.currentTimeMillis() + System.currentTimeMillis(), + floor = false, + lastFloorTime = "0" ) VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala index c5f0662066d8730f4da62c12e9094d3f885c1697..409f29112aac27ea67da50fa89bc8e9b8cb46ea1 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala @@ -18,6 +18,7 @@ trait VoiceApp2x extends UserJoinedVoiceConfEvtMsgHdlr with RecordingStartedVoiceConfEvtMsgHdlr with VoiceConfRunningEvtMsgHdlr with SyncGetVoiceUsersMsgHdlr + with AudioFloorChangedVoiceConfEvtMsgHdlr with VoiceConfCallStateEvtMsgHdlr with UserStatusVoiceConfEvtMsgHdlr { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala index 58cfb7dcdcc1d8466331eb11db8419726420fd23..ee9d528fe11a36e249fb607cf876ada6bf695a55 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala @@ -67,6 +67,29 @@ object VoiceUsers { } } + def becameFloor(users: VoiceUsers, voiceUserId: String, floor: Boolean, timestamp: String): Option[VoiceUserState] = { + for { + u <- findWithVoiceUserId(users, voiceUserId) + } yield { + val vu = u.modify(_.floor).setTo(floor) + .modify(_.lastFloorTime).setTo(timestamp) + .modify(_.lastStatusUpdateOn).setTo(System.currentTimeMillis()) + users.save(vu) + vu + } + } + + def releasedFloor(users: VoiceUsers, voiceUserId: String, floor: Boolean): Option[VoiceUserState] = { + for { + u <- findWithVoiceUserId(users, voiceUserId) + } yield { + val vu = u.modify(_.floor).setTo(floor) + .modify(_.lastStatusUpdateOn).setTo(System.currentTimeMillis()) + users.save(vu) + vu + } + } + def setLastStatusUpdate(users: VoiceUsers, user: VoiceUserState): VoiceUserState = { val vu = user.copy(lastStatusUpdateOn = System.currentTimeMillis()) users.save(vu) @@ -130,16 +153,18 @@ case class VoiceUser2x( voiceUserId: String ) case class VoiceUserVO2x( - intId: String, - voiceUserId: String, - callerName: String, - callerNum: String, - joined: Boolean, - locked: Boolean, - muted: Boolean, - talking: Boolean, - callingWith: String, - listenOnly: Boolean + intId: String, + voiceUserId: String, + callerName: String, + callerNum: String, + joined: Boolean, + locked: Boolean, + muted: Boolean, + talking: Boolean, + callingWith: String, + listenOnly: Boolean, + floor: Boolean, + lastFloorTime: String ) case class VoiceUserState( @@ -152,5 +177,7 @@ case class VoiceUserState( talking: Boolean, listenOnly: Boolean, calledInto: String, - lastStatusUpdateOn: Long + lastStatusUpdateOn: Long, + floor: Boolean, + lastFloorTime: String ) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index fcb3dcf9251aa78d8738bec997a0ce7eb68d6504..7c45cc4cecaebd04d1f8ee143e6e474fc2a4f8fe 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -167,6 +167,8 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[MuteMeetingCmdMsg](envelope, jsonNode) case IsMeetingMutedReqMsg.NAME => routeGenericMsg[IsMeetingMutedReqMsg](envelope, jsonNode) + case AudioFloorChangedVoiceConfEvtMsg.NAME => + routeVoiceMsg[AudioFloorChangedVoiceConfEvtMsg](envelope, jsonNode) case CheckRunningAndRecordingVoiceConfEvtMsg.NAME => routeVoiceMsg[CheckRunningAndRecordingVoiceConfEvtMsg](envelope, jsonNode) case UserStatusVoiceConfEvtMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index e72b3f4bf89556dcd2d7384e55987019809c15ce..736d847577ae06e92e262ecb78c9dceca0809773 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -381,9 +381,10 @@ class MeetingActor( case m: UserTalkingInVoiceConfEvtMsg => updateVoiceUserLastActivity(m.body.voiceUserId) handleUserTalkingInVoiceConfEvtMsg(m) - case m: VoiceConfCallStateEvtMsg => handleVoiceConfCallStateEvtMsg(m) + case m: VoiceConfCallStateEvtMsg => handleVoiceConfCallStateEvtMsg(m) - case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m) + case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m) + case m: AudioFloorChangedVoiceConfEvtMsg => handleAudioFloorChangedVoiceConfEvtMsg(m) case m: MuteUserCmdMsg => usersApp.handleMuteUserCmdMsg(m) updateUserLastActivity(m.body.mutedBy) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala index 9c22ee01201d35ecdb9cd2642e9238bcc4d22b98..7b7f62a6d3a5042e02ffd13fc75a57d500f698b2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala @@ -60,19 +60,21 @@ object FakeUserGenerator { } def createFakeVoiceUser(user: RegisteredUser, callingWith: String, muted: Boolean, talking: Boolean, - listenOnly: Boolean): VoiceUserState = { + listenOnly: Boolean, floor: Boolean = false): VoiceUserState = { val voiceUserId = RandomStringGenerator.randomAlphanumericString(8) + val lastFloorTime = System.currentTimeMillis().toString(); VoiceUserState(intId = user.id, voiceUserId = voiceUserId, callingWith, callerName = user.name, - callerNum = user.name, muted, talking, listenOnly, "freeswitch", System.currentTimeMillis()) + callerNum = user.name, muted, talking, listenOnly, "freeswitch", System.currentTimeMillis(), floor, lastFloorTime) } def createFakeVoiceOnlyUser(callingWith: String, muted: Boolean, talking: Boolean, - listenOnly: Boolean): VoiceUserState = { + listenOnly: Boolean, floor: Boolean = false): VoiceUserState = { val voiceUserId = RandomStringGenerator.randomAlphanumericString(8) val intId = "v_" + RandomStringGenerator.randomAlphanumericString(16) val name = getRandomElement(firstNames, random) + " " + getRandomElement(lastNames, random) + val lastFloorTime = System.currentTimeMillis().toString(); VoiceUserState(intId, voiceUserId = voiceUserId, callingWith, callerName = name, - callerNum = name, muted, talking, listenOnly, "freeswitch", System.currentTimeMillis()) + callerNum = name, muted, talking, listenOnly, "freeswitch", System.currentTimeMillis(), floor, lastFloorTime) } def createFakeWebcamStreamFor(userId: String, viewers: Set[String]): WebcamStream = { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java index 0242b524e0501582e6007c0b506dfea901d46a4c..33b37f0e7fbf7eae2890aa5ba8df2d790327637d 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java @@ -89,6 +89,14 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene vcs.deskShareRTMPBroadcastStopped(evt.getRoom(), evt.getBroadcastingStreamUrl(), evt.getVideoWidth(), evt.getVideoHeight(), evt.getTimestamp()); } + } else if (event instanceof AudioFloorChangedEvent) { + AudioFloorChangedEvent evt = (AudioFloorChangedEvent) event; + vcs.audioFloorChanged( + evt.getRoom(), + evt.getVoiceUserId(), + evt.getOldVoiceUserId(), + evt.getFloorTimestamp() + ); } else if (event instanceof VoiceConfRunningAndRecordingEvent) { VoiceConfRunningAndRecordingEvent evt = (VoiceConfRunningAndRecordingEvent) event; if (evt.running && ! evt.recording) { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java index c60c26984314f2e73e84728a76116adccd6bda1a..3dd8fc5af2426e9fda94f55c890ef36730854960 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java @@ -64,6 +64,11 @@ public interface IVoiceConferenceService { Integer videoHeight, String timestamp); + void audioFloorChanged(String room, + String voiceUserId, + String oldVoiceUserId, + String floorTimestamp); + void voiceConfRunningAndRecording(String room, Boolean isRunning, Boolean isRecording, diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/AudioFloorChangedEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/AudioFloorChangedEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..ede258c81aa2da7305938a251abe4a6679681f29 --- /dev/null +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/AudioFloorChangedEvent.java @@ -0,0 +1,50 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ +package org.bigbluebutton.freeswitch.voice.events; + +public class AudioFloorChangedEvent extends VoiceConferenceEvent { + + private final String voiceUserId; + private final String oldVoiceUserId; + private final String floorTimestamp; + + public AudioFloorChangedEvent( + String room, + String voiceUserId, + String oldVoiceUserId, + String floorTimestamp + ) { + super(room); + this.voiceUserId = voiceUserId; + this.oldVoiceUserId = oldVoiceUserId; + this.floorTimestamp = floorTimestamp; + } + + public String getVoiceUserId() { + return voiceUserId; + } + + public String getOldVoiceUserId() { + return oldVoiceUserId; + } + + public String getFloorTimestamp() { + return floorTimestamp; + } +} diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java index c42e80f7be42b2d925ff3baadea1baddad0c8180..5711927f21a9a80b57027e403cba0fbf8be73c1b 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java @@ -26,6 +26,7 @@ public class ESLEventListener implements IEslEventListener { private static final String STOP_RECORDING_EVENT = "stop-recording"; private static final String CONFERENCE_CREATED_EVENT = "conference-create"; private static final String CONFERENCE_DESTROYED_EVENT = "conference-destroy"; + private static final String FLOOR_CHANGE_EVENT = "video-floor-change"; private static final String SCREENSHARE_CONFERENCE_NAME_SUFFIX = "-SCREENSHARE"; @@ -197,6 +198,12 @@ public class ESLEventListener implements IEslEventListener { } else if (action.equals(CONFERENCE_DESTROYED_EVENT)) { VoiceConfRunningEvent pt = new VoiceConfRunningEvent(confName, false); conferenceEventListener.handleConferenceEvent(pt); + } else if (action.equals(FLOOR_CHANGE_EVENT)) { + String holderMemberId = this.getNewFloorHolderMemberIdFromEvent(event); + String oldHolderMemberId = this.getOldFloorHolderMemberIdFromEvent(event); + String floorTimestamp = event.getEventHeaders().get("Event-Date-Timestamp"); + AudioFloorChangedEvent vFloor= new AudioFloorChangedEvent(confName, holderMemberId, oldHolderMemberId, floorTimestamp); + conferenceEventListener.handleConferenceEvent(vFloor); } else { log.warn("Unknown conference Action [" + action + "]"); } @@ -507,6 +514,22 @@ public class ESLEventListener implements IEslEventListener { return e.getEventHeaders().get("Path"); } + private String getOldFloorHolderMemberIdFromEvent(EslEvent e) { + String oldFloorHolder = e.getEventHeaders().get("Old-ID"); + if(oldFloorHolder == null || oldFloorHolder.equalsIgnoreCase("none")) { + oldFloorHolder= ""; + } + return oldFloorHolder; + } + + private String getNewFloorHolderMemberIdFromEvent(EslEvent e) { + String newHolder = e.getEventHeaders().get("New-ID"); + if(newHolder == null || newHolder.equalsIgnoreCase("none")) { + newHolder = ""; + } + return newHolder; + } + // Distinguish between recording to a file: // /path/to/a/file.mp4 // and broadcasting a stream: diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala index c6da363f8c92b878ec8fa31ca50536ac18f5a703..2194688cc87495921caebd5bcfe74db6909f1044 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala @@ -276,6 +276,28 @@ class VoiceConferenceService(healthz: HealthzService, sender.publish(fromVoiceConfRedisChannel, json) } + def audioFloorChanged( + voiceConfId: String, + voiceUserId: String, + oldVoiceUserId: String, + floorTimestamp: String + ) { + val header = BbbCoreVoiceConfHeader(AudioFloorChangedVoiceConfEvtMsg.NAME, voiceConfId) + val body = AudioFloorChangedVoiceConfEvtMsgBody( + voiceConfId, + voiceUserId, + oldVoiceUserId, + floorTimestamp + ); + val envelope = BbbCoreEnvelope(AudioFloorChangedVoiceConfEvtMsg.NAME, Map("voiceConf" -> voiceConfId)) + + val msg = new AudioFloorChangedVoiceConfEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, msg) + + val json = JsonUtil.toJson(msgEvent) + sender.publish(fromVoiceConfRedisChannel, json) + } + def voiceCallStateEvent( conf: String, callSession: String, diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala index a6d15a7ffa19d4d5a6b6ca3af0d3bcb8a71e3f77..7c9fa7b61b8970d4ecf2e1bcab9b8dfeed6ee00b 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala @@ -495,6 +495,24 @@ object SyncGetVoiceUsersRespMsg { val NAME = "SyncGetVoiceUsersRespMsg" } case class SyncGetVoiceUsersRespMsg(header: BbbClientMsgHeader, body: SyncGetVoiceUsersRespMsgBody) extends BbbCoreMsg case class SyncGetVoiceUsersRespMsgBody(voiceUsers: Vector[VoiceConfUser]) +/** + * Received from FS that a user has become a floor holder + */ +object AudioFloorChangedVoiceConfEvtMsg { val NAME = "AudioFloorChangedVoiceConfEvtMsg" } +case class AudioFloorChangedVoiceConfEvtMsg( + header: BbbCoreVoiceConfHeader, + body: AudioFloorChangedVoiceConfEvtMsgBody +) extends VoiceStandardMsg +case class AudioFloorChangedVoiceConfEvtMsgBody(voiceConf: String, voiceUserId: String, oldVoiceUserId: String, floorTimestamp: String) + +/** + * Sent to a client that an user has become a floor holder + */ + +object AudioFloorChangedEvtMsg { val NAME = "AudioFloorChangedEvtMsg" } +case class AudioFloorChangedEvtMsg(header: BbbClientMsgHeader, body: AudioFloorChangedEvtMsgBody) extends BbbCoreMsg +case class AudioFloorChangedEvtMsgBody(voiceConf: String, intId: String, voiceUserId: String, floor: Boolean, lastFloorTime: String) + /** * Received from FS call state events. */ diff --git a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java index dc5d0f6d46a9d83761d37a283015f96e37b94237..e09669031f57b8502fe2dbab39d13400d3df6c02 100755 --- a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java +++ b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java @@ -519,6 +519,12 @@ public class Client } else if (eventFunc.equals("conference_loop_input")) { listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event); return; + } else if (eventFunc.equals("conference_member_set_floor_holder")) { + listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event); + return; + } else if (eventFunc.equals("conference_video_set_floor_holder")) { + listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event); + return; } else if (eventFunc.equals("stop_talking_handler")) { listener.conferenceEventAction(uniqueId, confName, confSize, eventAction, event); return;