Merge pull request #20921 from prlanzarin/u27/fix/tlo-unhold-unmute-delay
fix(audio): change unmute/unhold flow to work around FS unmute stutter
This commit is contained in:
commit
7371aa6c18
@ -1,9 +1,10 @@
|
|||||||
package org.bigbluebutton
|
package org.bigbluebutton
|
||||||
|
|
||||||
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, MuteUserInVoiceConfSysMsg, MuteUserInVoiceConfSysMsgBody, Routing }
|
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, Routing }
|
||||||
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
|
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
|
||||||
import org.bigbluebutton.core2.{ MeetingStatus2x }
|
import org.bigbluebutton.core2.{ MeetingStatus2x }
|
||||||
import org.bigbluebutton.core.apps.webcam.CameraHdlrHelpers
|
import org.bigbluebutton.core.apps.webcam.CameraHdlrHelpers
|
||||||
|
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||||
import org.bigbluebutton.core.models.{
|
import org.bigbluebutton.core.models.{
|
||||||
Roles,
|
Roles,
|
||||||
Users2x,
|
Users2x,
|
||||||
@ -16,19 +17,19 @@ import org.bigbluebutton.core.models.{
|
|||||||
|
|
||||||
object LockSettingsUtil {
|
object LockSettingsUtil {
|
||||||
|
|
||||||
private def muteUserInVoiceConf(liveMeeting: LiveMeeting, outGW: OutMsgRouter, vu: VoiceUserState, mute: Boolean): Unit = {
|
private def muteUserInVoiceConf(
|
||||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, vu.intId)
|
liveMeeting: LiveMeeting,
|
||||||
val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing)
|
outGW: OutMsgRouter,
|
||||||
val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, liveMeeting.props.meetingProp.intId)
|
vu: VoiceUserState, mute: Boolean
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
val body = MuteUserInVoiceConfSysMsgBody(liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId, mute)
|
VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, mute)
|
||||||
val event = MuteUserInVoiceConfSysMsg(header, body)
|
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
|
||||||
|
|
||||||
outGW.send(msgEvent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def applyMutingOfUsers(disableMic: Boolean, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
|
private def applyMutingOfUsers(
|
||||||
|
disableMic: Boolean,
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
||||||
Users2x.findWithIntId(liveMeeting.users2x, vu.intId).foreach { user =>
|
Users2x.findWithIntId(liveMeeting.users2x, vu.intId).foreach { user =>
|
||||||
if (user.role == Roles.VIEWER_ROLE && !vu.listenOnly && user.locked) {
|
if (user.role == Roles.VIEWER_ROLE && !vu.listenOnly && user.locked) {
|
||||||
@ -44,12 +45,20 @@ object LockSettingsUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def enforceLockSettingsForAllVoiceUsers(liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
|
def enforceLockSettingsForAllVoiceUsers(
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
|
val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
|
||||||
applyMutingOfUsers(permissions.disableMic, liveMeeting, outGW)
|
applyMutingOfUsers(permissions.disableMic, liveMeeting, outGW)
|
||||||
}
|
}
|
||||||
|
|
||||||
def enforceLockSettingsForVoiceUser(voiceUser: VoiceUserState, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
|
def enforceLockSettingsForVoiceUser(
|
||||||
|
voiceUser: VoiceUserState,
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
|
|
||||||
val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
|
val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
|
||||||
if (permissions.disableMic) {
|
if (permissions.disableMic) {
|
||||||
Users2x.findWithIntId(liveMeeting.users2x, voiceUser.intId).foreach { user =>
|
Users2x.findWithIntId(liveMeeting.users2x, voiceUser.intId).foreach { user =>
|
||||||
@ -65,7 +74,11 @@ object LockSettingsUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def enforceListenOnlyUserIsMuted(intUserId: String, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
|
private def enforceListenOnlyUserIsMuted(
|
||||||
|
intUserId: String,
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
val voiceUser = VoiceUsers.findWithIntId(liveMeeting.voiceUsers, intUserId)
|
val voiceUser = VoiceUsers.findWithIntId(liveMeeting.voiceUsers, intUserId)
|
||||||
voiceUser.foreach { vu =>
|
voiceUser.foreach { vu =>
|
||||||
// Make sure that listen only user is muted. (ralam dec 6, 2019
|
// Make sure that listen only user is muted. (ralam dec 6, 2019
|
||||||
|
@ -43,6 +43,7 @@ trait SystemConfiguration {
|
|||||||
lazy val ejectRogueVoiceUsers = Try(config.getBoolean("voiceConf.ejectRogueVoiceUsers")).getOrElse(true)
|
lazy val ejectRogueVoiceUsers = Try(config.getBoolean("voiceConf.ejectRogueVoiceUsers")).getOrElse(true)
|
||||||
lazy val dialInApprovalAudioPath = Try(config.getString("voiceConf.dialInApprovalAudioPath")).getOrElse("ivr/ivr-please_hold_while_party_contacted.wav")
|
lazy val dialInApprovalAudioPath = Try(config.getString("voiceConf.dialInApprovalAudioPath")).getOrElse("ivr/ivr-please_hold_while_party_contacted.wav")
|
||||||
lazy val toggleListenOnlyAfterMuteTimer = Try(config.getInt("voiceConf.toggleListenOnlyAfterMuteTimer")).getOrElse(4)
|
lazy val toggleListenOnlyAfterMuteTimer = Try(config.getInt("voiceConf.toggleListenOnlyAfterMuteTimer")).getOrElse(4)
|
||||||
|
lazy val transparentListenOnlyThreshold = Try(config.getInt("voiceConf.transparentListenOnlyThreshold")).getOrElse(0)
|
||||||
|
|
||||||
lazy val recordingChapterBreakLengthInMinutes = Try(config.getInt("recording.chapterBreakLengthInMinutes")).getOrElse(0)
|
lazy val recordingChapterBreakLengthInMinutes = Try(config.getInt("recording.chapterBreakLengthInMinutes")).getOrElse(0)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.users
|
|||||||
|
|
||||||
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
|
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
|
||||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||||
|
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||||
import org.bigbluebutton.core.models.{ Roles, Users2x, VoiceUsers }
|
import org.bigbluebutton.core.models.{ Roles, Users2x, VoiceUsers }
|
||||||
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
|
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
|
||||||
import org.bigbluebutton.core2.MeetingStatus2x
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
@ -51,13 +52,12 @@ trait MuteUserCmdMsgHdlr extends RightsManagementTrait {
|
|||||||
} else {
|
} else {
|
||||||
if (u.muted != msg.body.mute) {
|
if (u.muted != msg.body.mute) {
|
||||||
log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u)
|
log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u)
|
||||||
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(
|
VoiceApp.muteUserInVoiceConf(
|
||||||
meetingId,
|
liveMeeting,
|
||||||
voiceConf,
|
outGW,
|
||||||
u.voiceUserId,
|
u.intId,
|
||||||
msg.body.mute
|
msg.body.mute
|
||||||
)
|
)
|
||||||
outGW.send(event)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
|
|
||||||
// If the user is muted or unmuted with an unheld channel, broadcast
|
// If the user is muted or unmuted with an unheld channel, broadcast
|
||||||
// the event right away.
|
// the event right away.
|
||||||
// If the user is unmuted, but channel is held, we need to wait for the
|
// If the user is unmuted, but channel is held, we need to wait for the
|
||||||
// channel to be active again to broadcast the event. See
|
// channel to be active again to broadcast the event. See
|
||||||
// VoiceApp.handleChannelHoldChanged for this second case.
|
// VoiceApp.handleChannelHoldChanged for this second case.
|
||||||
if (muted || (!muted && !mutedUser.hold)) {
|
if (muted || (!muted && !mutedUser.hold)) {
|
||||||
@ -149,7 +149,6 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
outGW
|
outGW
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +259,7 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
callingInto: String,
|
callingInto: String,
|
||||||
hold: Boolean,
|
hold: Boolean,
|
||||||
uuid: String = "unused"
|
uuid: String = "unused"
|
||||||
): Unit = {
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
|
|
||||||
def broadcastEvent(voiceUserState: VoiceUserState): Unit = {
|
def broadcastEvent(voiceUserState: VoiceUserState): Unit = {
|
||||||
val routing = Routing.addMsgToClientRouting(
|
val routing = Routing.addMsgToClientRouting(
|
||||||
@ -323,8 +322,28 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
hold,
|
hold,
|
||||||
uuid
|
uuid
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val prevTransparentLOStatus = VoiceHdlrHelpers.transparentListenOnlyAllowed(
|
||||||
|
liveMeeting
|
||||||
|
)
|
||||||
|
|
||||||
VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
|
VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
|
||||||
|
|
||||||
|
val newTransparentLOStatus = VoiceHdlrHelpers.transparentListenOnlyAllowed(
|
||||||
|
liveMeeting
|
||||||
|
)
|
||||||
|
|
||||||
|
if (prevTransparentLOStatus != newTransparentLOStatus) {
|
||||||
|
// If the transparent listen only mode was activated or deactivated
|
||||||
|
// we need to update the listen only mode for all users in the meeting
|
||||||
|
// that are not muted.
|
||||||
|
handleTransparentLOModeChange(
|
||||||
|
liveMeeting,
|
||||||
|
outGW,
|
||||||
|
newTransparentLOStatus
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
broadcastEvent(voiceUserState)
|
broadcastEvent(voiceUserState)
|
||||||
|
|
||||||
if (liveMeeting.props.meetingProp.isBreakout) {
|
if (liveMeeting.props.meetingProp.isBreakout) {
|
||||||
@ -473,6 +492,22 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handleTransparentLOModeChange(
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter,
|
||||||
|
allowed: Boolean,
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
|
VoiceUsers.findAllMutedVoiceUsers(liveMeeting.voiceUsers) foreach { vu =>
|
||||||
|
toggleListenOnlyMode(
|
||||||
|
liveMeeting,
|
||||||
|
outGW,
|
||||||
|
vu.intId,
|
||||||
|
vu.callerNum,
|
||||||
|
allowed
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def toggleListenOnlyMode(
|
def toggleListenOnlyMode(
|
||||||
liveMeeting: LiveMeeting,
|
liveMeeting: LiveMeeting,
|
||||||
outGW: OutMsgRouter,
|
outGW: OutMsgRouter,
|
||||||
@ -482,6 +517,16 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
delay: Int = 0
|
delay: Int = 0
|
||||||
)(implicit context: ActorContext): Unit = {
|
)(implicit context: ActorContext): Unit = {
|
||||||
implicit def executionContext = context.system.dispatcher
|
implicit def executionContext = context.system.dispatcher
|
||||||
|
val allowed = VoiceHdlrHelpers.transparentListenOnlyAllowed(liveMeeting)
|
||||||
|
// Guarantee there are no other tasks for this channel
|
||||||
|
removeToggleListenOnlyTask(userId)
|
||||||
|
|
||||||
|
// If the meeting has not yet hit the minium amount of duplex channels
|
||||||
|
// for transparent listen only to be enabled, we don't need to do anything
|
||||||
|
if (!allowed && enabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
def broacastEvent(): Unit = {
|
def broacastEvent(): Unit = {
|
||||||
val event = MsgBuilder.buildToggleListenOnlyModeSysMsg(
|
val event = MsgBuilder.buildToggleListenOnlyModeSysMsg(
|
||||||
liveMeeting.props.meetingProp.intId,
|
liveMeeting.props.meetingProp.intId,
|
||||||
@ -493,9 +538,6 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
outGW.send(event)
|
outGW.send(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guarantee there are no other tasks for this channel
|
|
||||||
removeToggleListenOnlyTask(userId)
|
|
||||||
|
|
||||||
if (enabled && delay > 0) {
|
if (enabled && delay > 0) {
|
||||||
// If we are enabling listen only mode, we wait a bit before actually
|
// If we are enabling listen only mode, we wait a bit before actually
|
||||||
// dispatching the command - the idea is that recently muted users
|
// dispatching the command - the idea is that recently muted users
|
||||||
@ -571,4 +613,48 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def muteUserInVoiceConf(
|
||||||
|
liveMeeting: LiveMeeting,
|
||||||
|
outGW: OutMsgRouter,
|
||||||
|
userId: String,
|
||||||
|
muted: Boolean
|
||||||
|
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||||
|
for {
|
||||||
|
u <- VoiceUsers.findWithIntId(
|
||||||
|
liveMeeting.voiceUsers,
|
||||||
|
userId
|
||||||
|
)
|
||||||
|
} yield {
|
||||||
|
if (u.muted != muted) {
|
||||||
|
val muteEvent = MsgBuilder.buildMuteUserInVoiceConfSysMsg(
|
||||||
|
liveMeeting.props.meetingProp.intId,
|
||||||
|
liveMeeting.props.voiceProp.voiceConf,
|
||||||
|
u.voiceUserId,
|
||||||
|
muted
|
||||||
|
)
|
||||||
|
|
||||||
|
// If we're unmuting, trigger a channel unhold -> toggle listen only
|
||||||
|
// mode -> unmute
|
||||||
|
if (!muted) {
|
||||||
|
holdChannelInVoiceConf(
|
||||||
|
liveMeeting,
|
||||||
|
outGW,
|
||||||
|
u.uuid,
|
||||||
|
muted
|
||||||
|
)
|
||||||
|
toggleListenOnlyMode(
|
||||||
|
liveMeeting,
|
||||||
|
outGW,
|
||||||
|
u.intId,
|
||||||
|
u.callerNum,
|
||||||
|
muted,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
outGW.send(muteEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,4 +50,14 @@ object VoiceHdlrHelpers extends SystemConfiguration {
|
|||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def transparentListenOnlyAllowed(liveMeeting: LiveMeeting): Boolean = {
|
||||||
|
// Transparent listen only meeting-wide activation threshold.
|
||||||
|
// Threshold is the number of muted duplex audio channels in a meeting.
|
||||||
|
// 0 means no threshold, all users are subject to it
|
||||||
|
val mutedDuplexChannels = VoiceUsers.findAllMutedVoiceUsers(liveMeeting.voiceUsers).length
|
||||||
|
val threshold = transparentListenOnlyThreshold
|
||||||
|
|
||||||
|
(threshold == 0) || (mutedDuplexChannels >= threshold)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ object VoiceUsers {
|
|||||||
def findAllListenOnlyVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.listenOnly == true)
|
def findAllListenOnlyVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.listenOnly == true)
|
||||||
def findAllFreeswitchCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "freeswitch")
|
def findAllFreeswitchCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "freeswitch")
|
||||||
def findAllKurentoCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "kms")
|
def findAllKurentoCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "kms")
|
||||||
|
def findAllMutedVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.muted == true && u.listenOnly == false)
|
||||||
|
|
||||||
def findAllBannedCallers(users: VoiceUsers): Vector[VoiceUserState] = users.bannedUsers.values.toVector
|
def findAllBannedCallers(users: VoiceUsers): Vector[VoiceUserState] = users.bannedUsers.values.toVector
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
|||||||
import org.bigbluebutton.core2.MeetingStatus2x
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
||||||
|
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||||
|
|
||||||
trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
||||||
this: MeetingActor =>
|
this: MeetingActor =>
|
||||||
@ -57,8 +58,8 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
|||||||
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
||||||
if (!vu.listenOnly) {
|
if (!vu.listenOnly) {
|
||||||
Users2x.findWithIntId(liveMeeting.users2x, vu.intId) match {
|
Users2x.findWithIntId(liveMeeting.users2x, vu.intId) match {
|
||||||
case Some(u) => if (!u.presenter) muteUserInVoiceConf(vu, muted)
|
case Some(u) => if (!u.presenter) VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||||
case None => muteUserInVoiceConf(vu, muted)
|
case None => VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,17 +83,4 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
|||||||
BbbCommonEnvCoreMsg(envelope, event)
|
BbbCommonEnvCoreMsg(envelope, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
def muteUserInVoiceConf(vu: VoiceUserState, mute: Boolean): Unit = {
|
|
||||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, vu.intId)
|
|
||||||
val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing)
|
|
||||||
val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, props.meetingProp.intId)
|
|
||||||
|
|
||||||
val body = MuteUserInVoiceConfSysMsgBody(props.voiceProp.voiceConf, vu.voiceUserId, mute)
|
|
||||||
val event = MuteUserInVoiceConfSysMsg(header, body)
|
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
|
||||||
|
|
||||||
outGW.send(msgEvent)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
|
|||||||
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
||||||
import org.bigbluebutton.core2.MeetingStatus2x
|
import org.bigbluebutton.core2.MeetingStatus2x
|
||||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
||||||
|
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||||
|
|
||||||
trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||||
this: MeetingActor =>
|
this: MeetingActor =>
|
||||||
@ -30,19 +31,6 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
|||||||
BbbCommonEnvCoreMsg(envelope, event)
|
BbbCommonEnvCoreMsg(envelope, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
def muteUserInVoiceConf(vu: VoiceUserState, mute: Boolean): Unit = {
|
|
||||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, vu.intId)
|
|
||||||
val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing)
|
|
||||||
val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, props.meetingProp.intId)
|
|
||||||
|
|
||||||
val body = MuteUserInVoiceConfSysMsgBody(props.voiceProp.voiceConf, vu.voiceUserId, mute)
|
|
||||||
val event = MuteUserInVoiceConfSysMsg(header, body)
|
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
|
||||||
|
|
||||||
outGW.send(msgEvent)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.body.mute != MeetingStatus2x.isMeetingMuted(liveMeeting.status)) {
|
if (msg.body.mute != MeetingStatus2x.isMeetingMuted(liveMeeting.status)) {
|
||||||
if (msg.body.mute) {
|
if (msg.body.mute) {
|
||||||
val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg(
|
val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg(
|
||||||
@ -79,7 +67,7 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
|||||||
if (muted) {
|
if (muted) {
|
||||||
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
||||||
if (!vu.listenOnly) {
|
if (!vu.listenOnly) {
|
||||||
muteUserInVoiceConf(vu, muted)
|
VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,11 @@ voiceConf {
|
|||||||
# Time (seconds) to wait before requesting an audio channel hold after
|
# Time (seconds) to wait before requesting an audio channel hold after
|
||||||
# muting a user. Used in the experimental, transparent listen only mode.
|
# muting a user. Used in the experimental, transparent listen only mode.
|
||||||
toggleListenOnlyAfterMuteTimer = 4
|
toggleListenOnlyAfterMuteTimer = 4
|
||||||
|
|
||||||
|
# Transparent listen only meeting-wide activation threshold.
|
||||||
|
# Threshold is the number of muted duplex audio channels in a meeting.
|
||||||
|
# 0 = disabled
|
||||||
|
transparentListenOnlyThreshold = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
recording {
|
recording {
|
||||||
|
Loading…
Reference in New Issue
Block a user