fix(audio): change unmute/unhold flow to work around FS unmute stutter
FS has an intermittent issue where unmuting a HELD channel sometimes takes significantly (seconds) longer than usual. conference <XYZ> unmute <WVU> simply gets stuck with no FS_API response, which delays the unmute action whenever transparent listen only is active. Apparently, unholding the channel PRIOR TO unmuting works around the issue - at least it could not be reproduced with the scenario at hand. The unmute API already triggered an unhold in FS internally, which is the reason why this was not done beforehand. The aforementioned issue is way worse than an extra "redudant" API call, though. Always unhold audio channels manually _before_ unmuting.
This commit is contained in:
parent
e6e1f28036
commit
cf6202c572
@ -1,9 +1,10 @@
|
||||
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.core2.{ MeetingStatus2x }
|
||||
import org.bigbluebutton.core.apps.webcam.CameraHdlrHelpers
|
||||
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||
import org.bigbluebutton.core.models.{
|
||||
Roles,
|
||||
Users2x,
|
||||
@ -16,19 +17,19 @@ import org.bigbluebutton.core.models.{
|
||||
|
||||
object LockSettingsUtil {
|
||||
|
||||
private def muteUserInVoiceConf(liveMeeting: LiveMeeting, outGW: OutMsgRouter, vu: VoiceUserState, mute: Boolean): Unit = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, vu.intId)
|
||||
val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing)
|
||||
val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, liveMeeting.props.meetingProp.intId)
|
||||
|
||||
val body = MuteUserInVoiceConfSysMsgBody(liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId, mute)
|
||||
val event = MuteUserInVoiceConfSysMsg(header, body)
|
||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||
|
||||
outGW.send(msgEvent)
|
||||
private def muteUserInVoiceConf(
|
||||
liveMeeting: LiveMeeting,
|
||||
outGW: OutMsgRouter,
|
||||
vu: VoiceUserState, mute: Boolean
|
||||
)(implicit context: akka.actor.ActorContext): Unit = {
|
||||
VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, mute)
|
||||
}
|
||||
|
||||
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 =>
|
||||
Users2x.findWithIntId(liveMeeting.users2x, vu.intId).foreach { user =>
|
||||
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)
|
||||
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)
|
||||
if (permissions.disableMic) {
|
||||
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)
|
||||
voiceUser.foreach { vu =>
|
||||
// Make sure that listen only user is muted. (ralam dec 6, 2019
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.users
|
||||
|
||||
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
|
||||
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.running.{ LiveMeeting, OutMsgRouter }
|
||||
import org.bigbluebutton.core2.MeetingStatus2x
|
||||
@ -51,13 +52,12 @@ trait MuteUserCmdMsgHdlr extends RightsManagementTrait {
|
||||
} else {
|
||||
if (u.muted != msg.body.mute) {
|
||||
log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u)
|
||||
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(
|
||||
meetingId,
|
||||
voiceConf,
|
||||
u.voiceUserId,
|
||||
VoiceApp.muteUserInVoiceConf(
|
||||
liveMeeting,
|
||||
outGW,
|
||||
u.intId,
|
||||
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
|
||||
// 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
|
||||
// VoiceApp.handleChannelHoldChanged for this second case.
|
||||
if (muted || (!muted && !mutedUser.hold)) {
|
||||
@ -149,7 +149,6 @@ object VoiceApp extends SystemConfiguration {
|
||||
outGW
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,4 +613,48 @@ object VoiceApp extends SystemConfiguration {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
|
||||
import org.bigbluebutton.core2.MeetingStatus2x
|
||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
||||
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||
|
||||
trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
||||
this: MeetingActor =>
|
||||
@ -57,8 +58,8 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
||||
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
||||
if (!vu.listenOnly) {
|
||||
Users2x.findWithIntId(liveMeeting.users2x, vu.intId) match {
|
||||
case Some(u) => if (!u.presenter) muteUserInVoiceConf(vu, muted)
|
||||
case None => muteUserInVoiceConf(vu, muted)
|
||||
case Some(u) => if (!u.presenter) VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||
case None => VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,17 +83,4 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait {
|
||||
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.core2.MeetingStatus2x
|
||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
||||
import org.bigbluebutton.core.apps.voice.VoiceApp
|
||||
|
||||
trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
this: MeetingActor =>
|
||||
@ -30,19 +31,6 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
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) {
|
||||
val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg(
|
||||
@ -79,7 +67,7 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait {
|
||||
if (muted) {
|
||||
VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
|
||||
if (!vu.listenOnly) {
|
||||
muteUserInVoiceConf(vu, muted)
|
||||
VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user