Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix failure to leave when the only remaining participants are hidden #537

Merged
merged 5 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions src/main/kotlin/org/jitsi/jibri/selenium/pageobjects/CallPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,12 @@ class CallPage(driver: RemoteWebDriver) : AbstractPageObject(driver) {
return result
}

/** Returns the number of participants excluding hidden participants. */
fun getNumParticipants(): Int {
val result = driver.executeScript(
"""
try {
return APP.conference.membersCount;
return (APP.conference._room.getParticipants().$PARTICIPANT_FILTER_SCRIPT).length + 1;
} catch (e) {
return e.message;
}
Expand Down Expand Up @@ -203,13 +204,15 @@ class CallPage(driver: RemoteWebDriver) : AbstractPageObject(driver) {
}

/**
* Return how many of the participants are Jigasi clients
* Return how many of the participants are Jigasi clients.
* Note: excludes any participants that are hidden (for example transcribers)
*/
fun numRemoteParticipantsJigasi(): Int {
val result = driver.executeScript(
"""
try {
return APP.conference._room.getParticipants()
.$PARTICIPANT_FILTER_SCRIPT
.filter(participant => participant.getProperty("features_jigasi") == true)
.length;
} catch (e) {
Expand All @@ -226,6 +229,28 @@ class CallPage(driver: RemoteWebDriver) : AbstractPageObject(driver) {
}
}

/** How many of the participants are hidden or hiddenFromRecorder. */
fun numHiddenParticipants(): Int {
val result = driver.executeScript(
"""
try {
return APP.conference._room.getParticipants()
.filter(p => (p.isHidden() || p.isHiddenFromRecorder())
.length;
} catch (e) {
return e.message;
}
""".trimMargin()
)
return when (result) {
is Number -> result.toInt()
else -> {
logger.error("error running numHiddenParticipants script: $result ${result::class.java}")
0
}
}
}

/**
* Return true if ICE is connected.
*/
Expand Down Expand Up @@ -267,12 +292,14 @@ class CallPage(driver: RemoteWebDriver) : AbstractPageObject(driver) {
* Returns a count of how many remote participants are totally muted (audio
* and video). We ignore jigasi participants as they maybe muted in their presence
* but also hard muted via the device, and we later ignore their state.
* Note: Excludes hidden participants.
*/
fun numRemoteParticipantsMuted(): Int {
val result = driver.executeScript(
"""
try {
return APP.conference._room.getParticipants()
.$PARTICIPANT_FILTER_SCRIPT
.filter(participant => participant.isAudioMuted() && participant.isVideoMuted()
&& participant.getProperty("features_jigasi") !== true)
.length;
Expand Down Expand Up @@ -353,4 +380,11 @@ class CallPage(driver: RemoteWebDriver) : AbstractPageObject(driver) {
else -> true
}
}

companion object {
/**
* Javascript to apply a filter to the list of participants to exclude ones which should be hidden from jibri.
*/
const val PARTICIPANT_FILTER_SCRIPT = "filter(p => !(p.isHidden() || p.isHiddenFromRecorder()))"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ class MediaReceivedStatusCheck(
val numParticipants = callPage.getNumParticipants() - 1
val numMutedParticipants = callPage.numRemoteParticipantsMuted()
val numJigasiParticipants = callPage.numRemoteParticipantsJigasi()
val numHiddenParticipants = callPage.numHiddenParticipants()
// We don't get any mute state for Jigasi participants, so to prevent timing out when only Jigasi participants
// may be speaking, always count them as "muted"
val allClientsMuted = (numMutedParticipants + numJigasiParticipants) == numParticipants
logger.info(
"Jibri client receive bitrates: $bitrates, num participants: $numParticipants, " +
"numMutedParticipants: $numMutedParticipants, numJigasis: $numJigasiParticipants, " +
"all clients muted? $allClientsMuted"
"numHiddenParticipants: $numHiddenParticipants, all clients muted? $allClientsMuted"
)
clientsAllMutedTransitionTime.maybeUpdate(allClientsMuted)
val downloadBitrate = bitrates.getOrDefault("download", 0L) as Long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class MediaReceivedStatusCheckTest : ShouldSpec() {
override fun isolationMode(): IsolationMode? = IsolationMode.InstancePerLeaf

private val clock: FakeClock = spyk()
private val callPage: CallPage = mockk()
private val callPage: CallPage = mockk {
every { numHiddenParticipants() } returns 0
}
private val logger: Logger = mockk(relaxed = true)

private val check = MediaReceivedStatusCheck(logger, clock)
Expand Down
Loading