Listen only has a built-in retry routine on join failures that's
convoluted half-broken. It stems from the Kurento era where it could
fail randomly due to a myriad of reasons.
Production logs indicate that the retry is seldom used nowadays in
mediasoup-based environments. The presence of the retry also breaks
the error troubleshooting modal when actual failures happening, leaving
users in the dark about what's happening.
Remove the listen only retry code from AudioManager and bubble up any
join failure to the callers.
In scenarios where the join audio flow skips echo test, NotAllowedError
(and any other errors) are all being mashed together under a generic
MEDIA_ERROR object.
Properly handle specific errors in audio-manager so they're correctly
render in the audio modal help screen.
WebRTC-based stats generation in the connection status modal is broken
on Firefox >= 125. A broken type check coupled with a new partially
implemented RTCIceTransport dictionary causes and undefined function
call when fetching the selected candidate pair. Since that error is
unhandled, collection breaks.
Correctly check for the getSelectedCandidatePair method availability in
RTCIceTransport so that it skips to pair inference from getStats if
necessary.
There's a race condition that may cause a client crash whenever a
connectionstatechange callback is cleaned up in a peer without a
valid peer connection present in our custom RTCPeerConnection wrapper.
Check for peerConnection availability in the WebRtcPeer wrapper before
trying to clean up its connectionstatechange callback.
When a sendrecv peer acts as the answerer, gUM is only called _after_
the remote offer is received. This is fine, but the error handling runs
different in that scenario in a way that eventual gUM errors are treated
as negotiation errors, leading to inconsistencies when surfacing the
error to end users.
If a peer is acting as answerer and is a transceiver, acquire the local
streams _before_ actual negotiation so that gUM errors are surfaced
correctly (and we spare uneeded negotiation steps).
Audio exit toasts are fired in some redundant situations, e.g.: when the
error help screen is toast.
Change the logic a bit so that it's only fired when the audio help modal
won't be shown, i.e.: when audio had succesfully connected.
This is an initial, experimental implementation of the feature proposed in
https://github.com/bigbluebutton/bigbluebutton/issues/14021.
The intention is to phase out the explicit listen only mode with two
overarching goals:
- Reduce UX friction and increase familiarity: the existence of a separate
listen only mode is a source of confusion for the majority of users
Reduce average server-side CPU usage while also making it possible for
having full audio-only meetings.
The proof-of-concept works based on the assumption that a "many
concurrent active talkers" scenario is both rare and not useful. With
that in mind, this including two server-side triggers:
- On microphone inactivity (currently mute action that is sustained for
4 seconds, configurable): FreeSWITCH channels are held (which translates
to much lower CPU usage, virtually 0%). Receiving channels are switched,
server side, to a listening mode (SFU, mediasoup).
* This required an extension to mediasoup two allow re-assigning producers
to already established consumers. No re-negotiation is done.
- On microphone activity (currently unmute action, immediate):
FreeSWITCH channels are unheld, listening mode is deactivated and the
mute state is updated accordingly (in this order).
This is *off by default*. It needs to be enabled in two places:
- `/etc/bigbluebutton/bbb-webrtc-sfu/production.yml` ->
`transparentListenOnly: true`
- End users:
* Server wide: `/etc/bigbluebutton/bbb-html5.yml` ->
`public.media.transparentListenOnly: true`
* Per user: `userdata-bbb_transparent_listen_only=true`
Add secondsToActivateAudio, inputDeviceId, outputDeviceId and isListenOnly
to audio_joined.extraInfo
Add inputDeviceId, outputDeviceId and isListenOnly to
audio_failure.extraInfo
Add a try-catch to the device enforcement procedure triggered by
onAudioJoin - it may throw and block the modal.
In peer.js offer generation method, the provided constraitns are only
being type checked. It needs a value check when the constraint is a
boolean.
This commit should prevent useless transceivers from being added when
explictly specifying audio/video as `false`
There's an edge case in finnicky networks where ALG-like firewalls
tamper with USE-CANDIDATE STUN packets and, consequently, bork ICE-lite
connectivity establishment. The odd part is that client-side gathering
seems to complete if intermediate STUN bindings work (before the final
USE-CANDIDATE), which may cause the peer not to generate relay
candidates == connectivity fails.
This adds the `public.kurento.gatheringTimeout` option to forcefully extend
the candidate gathering window in peers that act as offerers. The
behavior is as follows: if the flag is set (ms), the peer will wait
either the gathering completed stage or, _at most_,
public.kurento.gatheringTimeout ms before proceeding with calls chained
to setLocalDescription.
This option is disabled by default and intentionally ommited from the
base settings.yml file as to not encourage its use. Don't use it unless
you know what you're doing :).
There are still a bunch of edge cases and issues with reconnection
scenarios for video:
- Signaling socket refuses to reconnect once maxRetries expire
- Race conditions on local stream attachment: local camera wouldn't be
correctly rendered _if_ the attached stream existed _without_ video
tracks yet
- Video tracks leak on local streams when replacing them (virtual bgs)
- Completely ignoring Meteor state when trying to reconnect cameras
- Streams aren't proactively stopped when the signaling socket dies
- Outbound request queues aren't isolated by stream nor are they
flushed when a newer peer with the same ID is created
- Server originated negotiation errors won't trigger a local peer
cleanup - thus leaving dangling peers that take way too long to
reconnect
This commit fixes or improves all of the aforementioned issues, +:
- Remove unused arguments in the peer (client->SFU) 'start' request
- Prevent crashes when trying to render video-list-items without user
data (which might happen on re-connections)
Same rationale as in video-provider's commit
(34fa37ae4f092af4a5aef0cf01d96c033d97473c).
This commit does the following:
- Implement actual heartbeat checks to trigger reconnects when
necessary
- Properly catch and log WebSocket.send errors