Commit Graph

220 Commits

Author SHA1 Message Date
prlanzarin
47018e5a65 fix(audio): ensure initial local mute state when muteOnStart=true
When `muteOnStart=true`, the initial local mute state in AudioManager is
desynced from the server. This issue stems from two recent changes:
  - Decoupling voice activity updates from the main user_voice subscription,
    which introduced an implicit muted state placeholder value
    of true instead of false. See user_voice_activity's DB schema
    propagation rules.
  - Introduction of dialplan-level muteOnStart, muting channels on creation
    rather than after.

Without properly updating AudioManager's `isMuted` placeholder, no
user_voice_activity update triggers *when joining audio* with
muteOnStart=true, causing two issues:
  - Sender tracks are not locally muted on audio join.
  - Opening the audio settings modal while muted will cause the
    microphone to be incorrectly *unmuted* once it's closed (first try only).

This fix sets AudioManager's `isMuted` placeholder to true, matching the
server. Additionally:
  - Enforce the local mute state before joining audio to ensure the desired
    sender track state. Should make this a bit more future proof.
  - Track `user_voice_activity` before joining audio (rather than after)
    to avoid race conditions.
  - Clean up `AudioManager.init` (loadBridges no longer returns a promise etc).
2024-09-11 19:16:57 +00:00
prlanzarin
1e53140a00 fix(audio): prevent permission check loop in Safari
Safari may enter a microphone permission check loop due to buggy behavior
in the Permissions API. When permission isn't permanently denied, gUM
requests fail with a NotAllowedError for a few seconds. During this time,
the permission state remains 'prompt' instead of transitioning to 'denied'
and back to 'prompt' after the timeout.

This leads to an issue where, on retrying while in 'prompt' + blocked,
the client loops through gUM checks via: 1) checking permission in the API,
2) receiving 'prompt', so trying gUM, 3) gUM fails, 4) returning to the
modal and checking permission again because the API still says 'prompt'.

Additionally, the `isUsingAudio` flag incorrectly counts the local echo
test/audio settings modal as "using audio," which toggles the flag on/off,
triggering the useEffect that causes the loop more frequently.

To fix this, remove the unnecessary AudioModal permission check that
causes the loop. Also, exclude "isEchoTest" from the `isUsingAudio` flag.
2024-08-20 19:19:08 +00:00
prlanzarin
9040cb86cb fix(audio): prevent spurious mute toggle due to AudioSettings remount
When listen only mode is deactivated and an user joins audio, an incorrect
remount of AudioSettings can trigger a spurious mute toggle. This happens
because AudioManager clears the `isConnecting` flag before setting the
`isConnected` flag. This creates a brief period where audio is flagged as
"disconnected," leading to a remount and unmount cycle that causes unwanted
mute/unmute actions due to AudioSettings' logic of muting/unmuting
active devices.

Ensure the `isConnected` flag is set before clearing the
`isConnecting` flag, preventing audio from being incorrectly flagged as
disconnected.
2024-08-16 01:51:10 +00:00
prlanzarin
381718a353 fix(audio): unmute when going from "no mic" -> mic via unmute trigger, +
When going from "no mic" -> mic via the unmute action, the client isn't
unmuting itself after confirming the change. This is caused by not
waiting the liveChangeInputDevice method (which is a Promise) to be
fully executed before unmounting the AudioSettings modal -- the one
responsible for triggering the unmute. Since it unmounts before the
device is changed, the unmute action will be ignored because the device
is still "listen-only" (no mic).

Properly unmute audio when transitioning from "no mic" -> "mic" via the
unmute trigger by waiting for liveChangeInputDevice to resolve.
Additionally, some general improvements to UI/UX:
  - Display the AudioSettings modal title when gUM is on prompt mode
  - Add specific subtitles to the AudioSettings modal to 1) warn that no
    mic is selected 2) Give a hint that the user can test their devices
  - Always honor settings.yml's "initialHearingState" state (whether
    local echo feedback should be played by default in AudioSettings)
2024-08-15 03:30:18 +00:00
prlanzarin
325887e325 feat(audio): rework audio join without listen only
This is a rework of the audio join procedure whithout the explict listen
only separation in mind. It's supposed to be used in conjunction with
the transparent listen only feature so that the distinction between
modes is seamless with minimal server-side impact. An abridged list of
changes:
  - Let the user pick no input device when joining microphone while
    allowing them to set an input device on the fly later on
  - Give the user the option to join audio with no input device whenever
    we fail to obtain input devices, with the option to try re-enabling
    them on the fly later on
  - Add the option to open the audio settings modal (echo test et al)
    via the in-call device selection chevron
  - Rework the SFU audio bridge and its services to support
    adding/removing tracks on the fly without renegotiation
  - Rework the SFU audio bridge and its services to support a new peer
    role called "passive-sendrecv". That role is used by dupled peers
    that have no active input source on start, but might have one later
    on.
  - Remove stale PermissionsOverlay component from the audio modal
  - Rework how permission errors are detected using the Permissions API
  - Rework the local echo test so that it uses a separate media tag
    rather than the remote
  - Add new, separate dialplans that mute/hold FreeSWITCH channels on
    hold based on UA strings. This is orchestrated server-side via
    webrtc-sfu and akka-apps. The basic difference here is that channels
    now join in their desired state rather than waiting for client side
    observers to sync the state up. It also mitigates transparent listen
    only performance edge cases on multiple audio channels joining at
    the same time.

The old, decoupled listen only mode is still present in code while we
validate this new approach. To test this, transparentListenOnly
must be enabled and listen only mode must be disable on audio join so
that the user skips straight through microphone join.
2024-08-15 00:43:28 +00:00
Tainan Felipe
4d6f4b3ded
Refactor: Make bundle using webpack (#20811)
* Refactor: Make bundle using webpack

* Fix: restore after install codes and a few settings

* Fix: build script folder permission

* Refactor: Remove support to async import on audio bridges

* Upgrade npm using nvm

* Avoid questions on npm ci execution

* Let npm ci install dev dependencies (as we need the build tools here)

* Fix: enconding

* Fix: old lock files

* Remove: bbb-config dependency to bbb-html5 service, bbb-html5 isn't a service anymore

* Fix: TS errors

* Fix: eslint

* Fix: chat styles

* npm install with "lockfileVersion": 3 (newer npm)

* build: allow nodejs 22

* node 22; drop meteor from CI and bbb-conf

* TEMP: use bbb-install without mongo but with node 22 and newer image

* build: relax nodejs condition to not trip 22.6

* build: ensure dir /usr/share/bigbluebutton/nginx exists

* init sites-available/bbb; drop disable-transparent-

* nginx complaining of missing file and ;

* TMP: print status of services

* WIP: tweak nginx location to debug

* Fix: webcam widgets alignments

* akka-apps -- update location of settings.yml

* build: add locales path for nginx

* docs and config changes for removal of meteor

* Fix: build encoding and locales enpoint folder path

* build: set wss url for media

* Add: Enable minimizer and modify to Terser

* Fix: TS errors

---------

Co-authored-by: Tiago Jacobs <tiago.jacobs@gmail.com>
Co-authored-by: Anton Georgiev <anto.georgiev@gmail.com>
Co-authored-by: Anton Georgiev <antobinary@users.noreply.github.com>
2024-08-09 13:58:44 -04:00
Ramón Souza
d3406a2e93
refactor: remove instanceId from client (#20850) 2024-08-02 14:10:39 -04:00
João Victor
8f232656fa fix: talking indicator getting stuck on audio exit 2024-07-05 12:15:02 -03:00
João Victor Nunes
d016b69b0c
refactor: remove standalone voice user subscription (#20600) 2024-06-28 16:58:29 -03:00
Tiago Jacobs
ba02a327e1
Revert "refactor(core-html5): custom hook for voice data" 2024-06-19 14:18:58 -03:00
João Victor
7ede343490 refactor(core-html5): custom hook for voice data 2024-06-18 15:40:14 -03:00
João Victor Nunes
1b87055343
refactor(audio): replace Tracker.Dependency with makeVar (#20408) 2024-06-12 09:25:46 -04:00
João Victor
089ddb5946 Add default voice value 2024-06-10 13:14:50 -03:00
João Victor
af52a8574c refactor: remove voice users adapter 2024-06-06 15:47:41 -03:00
João Victor Nunes
06500be757
refactor(storage): replace Tracker.Dependency with observer hook (#20322)
* refactor(storage): replace Tracker.Dependency with observer hook

* fix(storage): set initial value

* refactor(storage): stop using Meteor's Session singleton
2024-06-06 10:50:03 -03:00
Lucas
4f741b8cc0
fix(captions): Fixed captions mute/unmute, adding some debug logs (#20345)
* fix(captions): Fixed captions mute/unmute

* typescript updates

* more lint adjustments

---------

Co-authored-by: João Victor Nunes <joaovictornunes973@gmail.com>
Co-authored-by: Anton Georgiev <anto.georgiev@gmail.com>
2024-05-29 16:48:07 -04:00
Ramón Souza
7514066fc3
fix: Client can't load in certain cases (#20336)
* move settings

* remove meteor cache files
2024-05-29 09:26:11 -04:00
João Victor
7d07576554 fix: drop audio and video when joining breakout room 2024-05-21 12:31:17 -03:00
prlanzarin
d6e160a2c3 refactor(audio): remove stale iOS webview polyfills
Shouldn't be necessary anymore
2024-05-03 21:42:36 +00:00
prlanzarin
983b8a85cf fix(audio): improve help modal for listen only scenarios
The audio troubleshooting modal has very microphone-specific strings,
which might confuse users trying to join listen only.

Review the Help screen so that listen only scenarios are more generic.
As a bonus, review the unknownError locale with a more actionable text.
2024-05-03 21:41:06 +00:00
prlanzarin
a748d8ccbb fix(audio): remove listen only retry routines
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.
2024-05-03 21:18:44 +00:00
prlanzarin
027d5ad288 fix(audio): handle NotAllowedError in skipCheck:true scenarios
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.
2024-05-03 21:15:58 +00:00
Anton Georgiev
0df167180e
Merge pull request #20162 from prlanzarin/u30/fix/ff-pairselection
fix(audio): broken connection stats on Firefox >= 125
2024-05-03 08:53:40 -04:00
prlanzarin
20daf56390 fix(audio): broken connection stats on Firefox >= 125
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.
2024-05-02 23:37:44 +00:00
prlanzarin
d658d81148 fix(audio): minimize redundant audio exit toasts
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.
2024-05-02 22:09:56 +00:00
Tainan Felipe
d5bb06349b Fix: audio not disconnected when user leave the meeting 2024-05-01 14:11:04 -03:00
Tainan Felipe
a5f26da361 Merge remote-tracking branch 'upstream/v3.0.x-release' into refactor-voice-user 2024-03-07 14:16:05 -03:00
André Castro
58a0efe708
Migrate auth and settings to graphQL (#19507) 2024-03-06 14:28:18 -03:00
Tainan Felipe
00e055ff6e Refactor: move voice users to graphql 2024-03-06 13:08:32 -03:00
Tainan Felipe
aa27e8be68 Refactor: migrate audio captions to TS + Graphql 2023-09-21 10:48:00 -03:00
Tiago Jacobs
5cf2293c38
refactor (typescript): fix typescript build errors (#18454) 2023-08-14 17:52:35 -03:00
Gustavo Trott
3758dd89e2 Merge 2.7 into Develop 2023-07-31 11:24:25 -03:00
Tainan Felipe
9869ee7f2b Refactor: actions bar audio button 2023-07-24 15:56:40 -03:00
prlanzarin
80414a9cc4 feat(audio): add userdata-bbb_fullaudio_bridge
Allows controlling which audio bridge should be used, per user
2023-05-31 17:07:10 -03:00
prlanzarin
b3eebbb926 fix(audio): retry gUM without pre-set deviceIds on OverconstrainedError(s)
There are some situations where previously set deviceIds (
local/session storage) may become stale. This causes an unexpected
behavior where audio is temporarily borked until the user clears their
local storage.
This issue has been seen more recently on Safari endpoints when switching
back-and-forth breakout rooms in environments running under iframes.
Also seen randomly on endpoints with virtual input devices.

This centralizes audio gUM calling into a single method that retries the
gUM procedure without pre-set deviceIds only if the initial call fails
due with an OverconstrainedError - hopefully circumventing the issue.
2022-09-15 19:25:30 +00:00
prlanzarin
ec1879f96b fix(audio): add inputDeviceId enforcement for post-join/gUM
Extract the deviceId again from the stream to guarantee consistency
between stream DID vs chosen DID. That's necessary in scenarios where,
eg, there's no default/pre-set deviceId ('') and the browser's
default device has been altered by the user (browser default != system's
default).
2022-08-24 14:39:09 +00:00
prlanzarin
89e814d570 fix(audio): centralize device change code, add rollbacks, surface errors
There's no rollback procedure in case a device switch fails right now,
nor does the code entrypoints that call the switching procedures wait
for resolution or failure before marking the new device as chosen. That
may cause inconsistent states in a couple of ways:
  - No rollback: switch fails, audio is still on but no actual
    microphone input is being transmitted
  - Not waiting for resolutions: inconsistent chosen devices on failures
Device switching errors are also not surfaced to the end user

This commit:
  - Adds device rollback and proper resolution/failure response
    awaits to try and make the state a bit more consistent.
  - Centralizes the input device switching code to be reused between
    different bridges
  - Centralizes device ID state management in audio-manager to try and
    mantain them a bit more consistent across the board
  - Surface device switching failures to the end user
  - Guarantee device IDs are set to the session storage on all
    appropriate scenarios
2022-08-24 13:28:27 +00:00
prlanzarin
ac71167ba5 refactor(audio): add debug logs for microphone device changes
In/out device changes are mostly silent which makes it hard to track
them to look for problems.
2022-08-23 14:50:50 +00:00
prlanzarin
ccc95583ee refactor(audio): restore trickle candidate filtering in new audio bridge
+ better error handling, log messages for that code
2022-04-25 16:45:18 +00:00
prlanzarin
459e1a9514 refactor(audio): remove old listen only bridge (kurento.js)
- Remove the old listen only bridge (kurento.js), superseded by the equivalent
  and equally stable (AS FAR AS LISTEN ONLY IS CONCERNED) sfu-audio-bridge
  - Rename FullAudioBridge.js -> sfu-audio-bridge.js
    * A more generic name that better represents the capabilities and
      the nature of the bridge
    * The bridge name identifier in configuration is still the same
      ('fullaudio')
  - Remove the FreeSWITCH listen only fallback
  - Temporarily disable the "trickle ICE" pair gathering feature used
    in SIP.js (which was always experimental, nonstandard and disabled
    by default)
  - Updates to settings.yml keys in places where relevant
2022-04-20 20:46:32 +00:00
prlanzarin
0d85905c83 fix(audio): centralize default in/out device id definitions, make them an empty string
"default" is not an universally valid default value for deviceIds which was causing issues with Firefox and Safari in some specific scenarios where exact deviceId constraints were being used
2022-04-11 19:23:32 +00:00
Anton Georgiev
3cee20c489 fix: Drop old postMessage leftover 2022-04-07 15:27:41 +00:00
prlanzarin
adc13add67 refactor(audio): remove duplicated loadBridges method definition
Seems to have been introduced by a partial merge commit

There were a bunch of style changes introduced by that partial commit as well; I kept those changes to avoid introducing further conflicts between v2.4-2.5...
2022-02-22 13:42:20 -03:00
Anton Georgiev
797fc49633 TEMP 2021-12-09 20:37:05 +00:00
Ramón Souza
16fd642e33 interrupt connection proccess if audio modal is closed 2021-12-03 11:45:07 +00:00
Maxim Khlobystov
b7cf670aec Remove the support for iframe postMessage API (recording and self-muting) 2021-11-29 22:53:12 +00:00
Mario Jr
9578efbcd3 fix(audio): prevent audio to hang when user is transferred to breakout room
When joining breakouts, we now wait for the bridge to be loaded before
automatically start user's audio.
This problems happens only on fullaudio bridge
2021-11-09 15:04:10 -03:00
Mario Jr
70815fad4f feat(audio): add meta param for selecting fullaudio bridge
This can be passed through API. For example, for setting fullaudio bridge, you
can pass the param "meta_fullaudio-bridge=fullaudio"
2021-11-09 12:09:36 -03:00
Mario Jr
cf2d595f12 fix(audio): correctly retrieve Object class from bridge module 2021-11-09 12:08:31 -03:00
Mario Jr
5c85f4c5b2 fix(audio): promisify loadBridges function
New bridges were being loaded with undefined value, since we didn't
wait for this to fully load before instantiating it
2021-11-09 12:08:25 -03:00