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
|
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
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,6 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
outGW
|
outGW
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user