Commit Graph

12 Commits

Author SHA1 Message Date
prlanzarin
d2dde8a9b1 feat: add experimental support for ICE restart
We currently use full renegotiation for audio, video, and screen sharing
reconnections, which involves re-creating transports and signaling channels
from scratch. While effective in some scenarios, this approach is slow and,
especially with outbound cameras and screen sharing, prone to failures.

To counter that, WebRTC provides a mechanism to restart ICE without needing
to re-create the peer connection. This allows us to avoid full renegotiation
and bypass some server-side signaling limitations. Implementing ICE restart
should make outbound camera/screen sharing reconnections more reliable and
faster.

This commit implements the ICE restart procedure for all WebRTC components,
based on bbb-webrtc-sfu >= v2.15.0-beta.0, which added support for ICE restart
requests. This feature is off by default. To enable it, adjust the following
flags:

- `/etc/bigbluebutton/bbb-webrtc-sfu/production.yml`: `allowIceRestart: true`
- `/etc/bigbluebutton/bbb-html5.yml`: `public.kurento.restartIce`
  * Refer to the inline documentation; this can be enabled on the client side
    per media type.
  * Note: The default max retries for audio is lower than for cameras/screen
    sharing (1 vs 3). This is because the full renegotiation process for audio
    is more reliable, so ICE restart is attempted first, followed by full
    renegotiation if necessary. This approach is less suitable for cameras/
    screen sharing, where longer retry periods for ICE restart make sense
    since full renegotation there is... iffy.
2024-08-23 09:59:51 -03:00
prlanzarin
555a8f6522 fix(audio): acquire streams before negotiation when peer is answerer
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).
2024-04-12 14:29:38 -03:00
prlanzarin
8feb934169 feat(audio): add experimental transparent listen only mode
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`
2023-08-07 19:43:18 -03:00
prlanzarin
be6a23a003 feat: add option to force/extend gathering window in SFU components
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 :).
2023-04-05 13:22:38 -03:00
prlanzarin
0f24e5634d fix(audio): bypass overconstrained errors in SFU-based audio 2022-09-15 20:42:43 +00:00
prlanzarin
0e162f1cda feat: configurable DSCP marking for WebRTC media
RTCRTPSender exposes DSCP marking via `networkPriority` in the encodings
configuration dictionaries. That should allow us to control
QoS priorities for different media streams, eg audio with higher network
priority than video. The only browser that implements that right
now is Chromium.

To use this, the public.app.media.networkPriorities configuration in
settings.yml. Audio, camera and screenshare priorities can be controlled
separately. For further info on the possible values, see:
  - https://www.w3.org/TR/webrtc-priority/
  - https://datatracker.ietf.org/doc/html/rfc8837#section-5
2022-08-15 21:24:05 +00:00
prlanzarin
45049cbd65 refactor: swap kurento-utils for new peer wrapper in screen sharing and audio 2022-07-15 14:00:12 +00:00
prlanzarin
602238b84e refactor(audio): remove caller ID from fullaudio bridge start request
The callerId is assembled server-side as of bbb-webrtc-sfu
v2.9.0-alpha.3 based on the work done in commit
d940bff541b6fe3c4976428ca471457bc67ac97e.
2022-06-28 20:33:36 +00:00
prlanzarin
1d860d64d0 fix(audio): remove deprecated getLocalStreams usage
Use the built-in getLocalStream from the peer wrapper instead (which
relies on getSenders - the proper, spec-compliant way).

Two different issues are addressed:
  - RTCPeerConnection.getLocalStreams is a pre-1.0 WebRTC spec which is
    deprecated and not recommended.
  - Fixed an issue where a switch from full audio to listen only could
  cause the latter to be rejected with an error 1004 in rare scenarios.
2022-05-27 14:02:10 +00:00
prlanzarin
6a0e0a87c2 fix(audio): abide to signalCandidates configuration flag 2022-05-02 13:49:47 +00:00
prlanzarin
6fd6a52d47 fix(audio): prevent uncaught rejections in the experimental audio bridge startup 2022-04-20 17:40:06 +00:00
prlanzarin
1e80d050b7 refactor(audio): generic use of sfu audio broker to cover mic and listen only 2022-04-20 17:26:52 +00:00