Skip to main content
Version: 4.0

Server Customization

BigBlueButton has many configuration files that offer you opportunities to customize your installation.

General​

Preserving changes to configuration files​

BigBlueButton's components use various configuration files which are included with the installation packages. If you were to make a change to these configuration files, your changes would be lost when an updated version of the package is installed during upgrades. To prevent this loss of customizations, most components also accept overriding configuration files from /etc/bigbluebutton. That directory is not interfered with by BigBlueButton (except in cases when using the command bbb-conf --setip or --setsecret placing new values you specify).

For the full list of the configuration files and their overriding counterpart, see Configuration Files

Preserving customizations using apply-config.sh​

We strongly recommend adding your custom settings to /etc/bigbluebutton instead. See the list of override files

Whenever you upgrade a server to the latest version of BigBlueButton, either using the upgrade steps or the bbb-install.sh script, if you have made custom changes to BigBlueButton's configuration files [that are deployed from packages], the packaging scripts may overwrite these changes.

To make it easier to apply your configuration changes, you can create a BASH script at /etc/bigbluebutton/bbb-conf/apply-config.sh that contains commands to apply your changes. The bbb-conf script, which is run as part of the last steps in a manual upgrade steps or using bbb-install.sh, will detect apply-config.sh and invoke it just before starting all of BigBlueButton's components.

In this way, you can use apply-config.sh to apply your custom configuration changes after all packages have updated but just before BigBlueButton starts.

For example, if you create /etc/bigbluebutton/bbb-conf/apply-config.sh with the following contents and make it executable with chmod +x /etc/bigbluebutton/bbb-conf/apply-config.sh

#!/bin/bash

# Pull in the helper functions for configuring BigBlueButton
source /etc/bigbluebutton/bbb-conf/apply-lib.sh

enableUFWRules

then when called by bbb-conf, the above apply-config.sh script will

  • use the helper function enableUFWRules to restrict access to specific ports, and

Notice that apply-conf.sh includes a helper script apply-lib.sh. This helper script contains some functions to make it easy to apply common configuration changes, along with some helper variables, such as HTML5_CONFIG.

The contents of apply-config.sh are not owned by any package, so it will never be overwritten.

Common Customizations​

Recording​

Delete raw data from published recordings​

When a meeting finishes, the BigBlueButton server archives the meeting data (referred to as the "raw" data).

Retaining the raw data lets you rebuild a recording if there was a processing issue, to enabled a new recording format, or if it was accidentally deleted by a user; however, the tradeoff is the storage of raw data will consume more disk space over time.

By default, the BigBlueButton server automatically removes the raw data for a recording 14 days after it was published. The period is the variable published_days of /etc/cron.daily/bigbluebutton; override it in /etc/default/bigbluebutton-cron-config, which survives upgrades:

published_days=30

If you would instead like to completely disable the cleanup of raw recording data, comment out the following line, near the bottom of /etc/cron.daily/bigbluebutton (this edit is lost on upgrades; alternatively set published_days to a very large value):

remove_raw_of_published_recordings

The same file also deletes the raw data of meetings without recording marks after unrecorded_days (default 14), presentations after history (default 5) days and rotated logs after log_history (default 28) days. All of these can be overridden the same way.

Delete recordings older than N days​

To delete recordings older than 14 days, create the file /etc/cron.daily/bbb-recording-cleanup with the contents

#!/bin/bash

MAXAGE=14

LOGFILE=/var/log/bigbluebutton/bbb-recording-cleanup.log

shopt -s nullglob

NOW=$(date +%s)

echo "$(date --rfc-3339=seconds) Deleting recordings older than ${MAXAGE} days" >>"${LOGFILE}"

for donefile in /var/bigbluebutton/recording/status/published/*-presentation.done ; do
MTIME=$(stat -c %Y "${donefile}")
# Check the age of the recording
if [ $(( ( $NOW - $MTIME ) / 86400 )) -gt $MAXAGE ]; then
MEETING_ID=$(basename "${donefile}")
MEETING_ID=${MEETING_ID%-presentation.done}
echo "${MEETING_ID}" >> "${LOGFILE}"

bbb-record --delete "${MEETING_ID}" >>"${LOGFILE}"
fi
done

for eventsfile in /var/bigbluebutton/recording/raw/*/events.xml ; do
MTIME=$(stat -c %Y "${eventsfile}")
# Check the age of the recording
if [ $(( ( $NOW - $MTIME ) / 86400 )) -gt $MAXAGE ]; then
MEETING_ID="${eventsfile%/events.xml}"
MEETING_ID="${MEETING_ID##*/}"
echo "${MEETING_ID}" >> "${LOGFILE}"

bbb-record --delete "${MEETING_ID}" >>"${LOGFILE}"
fi
done

Change the value for MAXAGE to specify how many days to retain the presentation format recordings on your BigBlueButton server. After you create the file, make it executable.

$ chmod +x /etc/cron.daily/bbb-recording-cleanup

Move recordings to a different partition​

Most of BigBlueButton's storage occurs in the /var/bigbluebutton directory (this is where all the recordings are stored). If you want to move this directory to another partition, say to /mnt/data, do the following

$ sudo bbb-conf --stop
$ mv /var/bigbluebutton /mnt/data
$ ln -s /mnt/data/bigbluebutton /var/bigbluebutton
$ sudo bbb-conf --start

Migrate recordings from a previous version​

Depending of the previous version there may be some differences in the metadata generated. In order to fix that it will be necessary to execute the corresponding scripts for updating the migrated recordings.

$ cd /usr/local/bigbluebutton/core/scripts
From version 0.9​
$ sudo ./bbb-0.9-beta-recording-update
$ sudo ./bbb-0.9-recording-size
From version 1.0​
$ sudo ./bbb-1.1-meeting-tag

If for some reason the scripts have to be run more than once, use the --force modifier.

$ sudo ./bbb-x.x-script --force

Play recordings made with BigBlueButton 0.81 or 0.9​

Recordings made with BigBlueButton 0.81 and 0.9 are played by their own players, served under /playback/presentation/0.81/ and /playback/presentation/0.9.0/. Those players are no longer installed by default. bbb-playback-presentation still ships the processing scripts and the nginx configuration that serves /playback/presentation, but not the players, so the links to the old players answer 404. If you migrated recordings from those versions and still need to play them, install the optional package that provides them:

$ sudo apt-get install bbb-playback-presentation-legacy

The package installs both players and the redirect from the unversioned link /playback/presentation/playback.html to the 0.81 player, so links published by those versions keep working. These players only render recordings created by BigBlueButton 0.81 and 0.9; recordings made with the current version use the 2.3 player from bbb-playback. To remove the players again, run sudo apt-get remove bbb-playback-presentation-legacy.

Enable playback of recordings on iOS​

The presentation playback format encodes the video shared during the session (webcam and screen share) as .webm (VP8) files; however, iOS devices only support playback of .mp4 (h.264) video files. To enable playback of the presentation recording format on iOS devices, add mp4 to video_formats in /etc/bigbluebutton/recording/presentation.yml (the override of /usr/local/bigbluebutton/core/scripts/presentation.yml).

video_formats:
- webm
- mp4

This change will cause BigBlueButton to generate an additional .mp4 file for the video components (webcam and screen share) that was shared during the session. This change only applies to new recordings. If you want this change to apply to any existing recordings, you need use the bbb-record command to rebuild them.

This change will increase the processing time and storage size of recordings with video files as it will now generate two videos: .webm and .mp4 for the webcam and screen share videos.

Always record every meeting​

By default, the BigBlueButton server will produce a recording when both of the following are true:

  1. the meeting has been created with record=true in the create API call, and
  2. a moderator has clicked the Start/Stop Record button (at least once) during the meeting.

However, you can configure a BigBlueButton server to record every meeting and disable the ability for a moderator to stop the recording. Edit /etc/bigbluebutton/bbb-web.properties and set the following properties:

# Start recording when first user joins the meeting.
# For backward compatibility with 0.81 where whole meeting
# is recorded.
autoStartRecording=true

# Allow the user to start/stop recording.
allowStartStopRecording=false

To apply the changes, restart the BigBlueButton server using the command

$ sudo bbb-conf --restart

Transfer recordings​

When setting up BigBlueButton on a server, you may want to transfer recordings from an older server. If your old server has all of the original recording files in the /var/bigbluebutton/recording/raw directory, then you can transfer these files to the new server using rsync.

For example, running this rsync command new server will copy over the recording file from the old server.

$ rsync -rP root@old-bbb-server.example.com:/var/bigbluebutton/recording/raw/ /var/bigbluebutton/recording/raw/

Alternatively, you could create a tar archive of the /var/bigbluebutton/recording/raw directory, and copy it with scp, or use a shared NFS mount.

After you copy over the files (either through rsync or tar-and-copy), you will then need to fix the permissions on the new server using the following chown command.

$ chown -R bigbluebutton:bigbluebutton /var/bigbluebutton/recording/raw

After transfer of recordings, view a sampling of the recordings to ensure they playback correctly (they should).

Re-process raw recordings​

If you have transferred over the raw content, you can also reprocess the recordings using the newer scripts to rebuild them with the latest playback format (including any bug fixes made in the latest version). Note: Re-processing can take a long time (around 25% to 50% of the original length of the recordings), and will use a lot of CPU on your new BigBlueButton server while you wait for the recordings to process.

If you are interested in reprocessing the older recordings, try it first with one or two of the larger recordings. If there is no perceptible difference, you don't need to reprocess the others.

And initiate the re-processing of a single recording, you can do

$ sudo bbb-record --rebuild <recording_id>

where <recording_id> is the the file name of the raw recording in /var/bigbluebutton/recording/raw, such as

$ sudo bbb-record --rebuild f4ae6fd61e2e95940e2e5a8a246569674c63cb4a-1517234271176

If your old server has all of the original recording files in the /var/bigbluebutton/recording/raw directory, then you can transfer these files to the new server, for example with rsync:

If you want to rebuild all your recordings, enter the command

Warning: If you have a large number of recordings, this will rebuild all of them, and not process any new recordings until the rebuild process finishes. Do not do this unless this is you intent. Do not do this command to troubleshoot recording errors, instead see Recording Troubleshooting.

$ sudo bbb-record --rebuildall

The BigBlueButton server will automatically go through the recordings and rebuild and publish them. You can use the bbb-record --watch command to see the progress.

Transfer published recordings from another server​

If you want to do the minimum amount of work to quickly make your existing recordings on an older BigBlueButton server, transfer the contents of the /var/bigbluebutton/published and /var/bigbluebutton/unpublished directories. In addition, to preserve the backup of the original raw media, you should transfer the contents of the /var/bigbluebutton/recording/raw directory.

Here is an example set of rsync commands that would accomplish this; run these on the new server to copy the files from the old server.

$ rsync -rP root@old-bbb-server:/var/bigbluebutton/published/ /var/bigbluebutton/published/
$ rsync -rP root@old-bbb-server:/var/bigbluebutton/unpublished/ /var/bigbluebutton/unpublished/
$ rsync -rP root@old-bbb-server:/var/bigbluebutton/recording/raw/ /var/bigbluebutton/recording/raw/

Other methods of transferring these files can also be used; for example, you could create a tar archive of each of the directories, and transfer it via scp, or use a shared NFS mount.

You will then need to fix the permissions on the newly copied recordings:

$ chown -R bigbluebutton:bigbluebutton /var/bigbluebutton/published /var/bigbluebutton/unpublished /var/bigbluebutton/recording/raw

If the recordings were copied from a server with a different hostname, you will have to run the following command to fix the stored hostnames. (If you don't do this, it'll either return a 404 error, or attempt to load the recordings from the old server instead of the new server!)

Note that this command will restart the BigBlueButton server, interrupting any live sessions.

$ sudo bbb-conf --setip <ip_address_or_hostname>

For example,

$ sudo bbb-conf --setip bigbluebutton.example.com

The transferred recordings should be immediately visible via the BigBlueButton recordings API.

Change processing time​

The BigBlueButton server processes recordings as meetings finish: bbb-rap-starter queues each recording and the bbb-rap-resque-worker service works through the queue. To restrict the processing to specific hours, stop the worker during the day and start it in the evening with a cron job; the queued recordings wait until the worker runs again. For example, in /etc/cron.d/bbb-recording-hours:

0 7 * * * root systemctl stop bbb-rap-resque-worker
0 21 * * * root systemctl start bbb-rap-resque-worker

bbb-conf --restart also starts the worker, so a restart during the day resumes processing until the next stop.

Allow all recordings to be returned​

The configuration property allowFetchAllRecordings in bigbluebutton.properties determines whether every recording on the server can be returned in a single response from a getRecordings call. By default this property is set to true. On a server with a large number of recordings an attempt to return every recording in a single response can cause a large amount of load on the server and therefore it is advised that this property be switched to false. When this is done any request to getRecordings that does not specify any recording or meeting IDs as well as no pagination parameters will return no recordings to prevent all recordings from being returned.

Increase the number of recording workers​

Warning

If the defaultKeepEvents or meetingKeepEvents setting in bbb-web is enabled, you must not increase the number of BigBlueButton recording workers. Doing so could result in data loss, as meeting events will not be correctly archived.

For more information, see BigBlueButton issue #12503.

Run systemctl edit bbb-rap-resque-worker.service, and insert the following into the editor, replacing the number with the desired number of recordings to process concurrently.

[Service]
Environment=COUNT=3

Then restart the worker process: systemctl restart bbb-rap-resque-worker.service

If you run systemctl status bbb-rap-resque-worker.service now, you will see that it has the desired number of workers ready to process recordings in parallel:

● bbb-rap-resque-worker.service - BigBlueButton resque worker for recordings
Loaded: loaded (/usr/lib/systemd/system/bbb-rap-resque-worker.service; disabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/bbb-rap-resque-worker.service.d
└─override.conf
Active: active (running) since Sat 2021-01-09 12:19:22 UTC; 6s ago
Main PID: 23630 (sh)
Tasks: 15 (limit: 4915)
CGroup: /system.slice/bbb-rap-resque-worker.service
├─23630 /bin/sh -c /usr/bin/rake -f ../Rakefile resque:workers >> /var/log/bigbluebutton/bbb-rap-worker.log
├─23631 /usr/bin/ruby /usr/bin/rake -f ../Rakefile resque:workers
├─23650 resque-2.0.0: Waiting for rap:archive,rap:publish,rap:process,rap:sanity,rap:captions
├─23651 resque-2.0.0: Waiting for rap:archive,rap:publish,rap:process,rap:sanity,rap:captions
└─23652 resque-2.0.0: Waiting for rap:archive,rap:publish,rap:process,rap:sanity,rap:captions

Install additional recording processing formats​

In addition to the presentation format that is installed and enabled by default, there are several optional recording formats available for BigBlueButton:

  • notes: Makes the shared notes from the meeting available as a document.
  • screenshare: Generate a single video file from the screensharing and meeting audio.
  • podcast: Generate an audio-only recording.
  • video: Generate a recording containing the webcams, presentation area, and screensharing combined into a single video file.

The processing scripts and playback support files for these recording formats can be installed from the packages named bbb-playback-formatname (e.g. bbb-playback-video)

There is currently an issue where the recording formats are not automatically enabled when they are installed - see #12241 for details.

In order to enable the recording formats manually, you need to edit the file /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml. Look for the section named steps:. In this section, the recording processing workflow is defined, including what recording processing steps are performed, and what order they need to be performed in. To ensure that your modifications are not lost when a new version of the packages is installed, you can [create the file and] write your changes to /etc/bigbluebutton/recording/recording.yml.

To enable a new recording format, you need to add a new step named process:formatname that runs after the step named captions, and a new step named publish:formatname that runs after process:formatname. You may have to convert some of the steps to list format.

For example, here are the stock steps with the presentation format enabled:

steps:
archive: 'sanity'
sanity: 'captions'
captions: 'process:presentation'
'process:presentation': 'publish:presentation'

If you additionally enable the video recording format, the steps will have to be changed to look like this:

cat /etc/bigbluebutton/recording/recording.yml

steps:
archive: 'sanity'
sanity: 'captions'
captions:
- 'process:presentation'
- 'process:video'
'process:presentation': 'publish:presentation'
'process:video': 'publish:video'

This pattern can be repeated for additional recording formats. Note that it's very important to put the step names containing a colon (:) in quotes.

After you edit the configuration file, you must restart the recording processing queue: systemctl restart bbb-rap-resque-worker.service in order to pick up the changes.

To disable one or more enabled recording formats for a single meeting, pass meta_bbb-disable-recording-formats on the create API call with a comma-separated list of format names. For example, meta_bbb-disable-recording-formats=video,presentation (or meta_bbb-disable-recording-formats=[video,presentation]) skips the video and presentation recording formats for that meeting. The format names are case-insensitive and match the format part of the recording steps. Disabled formats are not processed or published, so they do not trigger recording-ready callbacks.

The following script enables the video recording format.

#!/bin/bash
mkdir -p /etc/bigbluebutton/recording
cat > /etc/bigbluebutton/recording/recording.yml << REC
steps:
archive: "sanity"
sanity: "captions"
captions:
- process:presentation
- process:video
process:presentation: publish:presentation
process:video: publish:video
REC
if ! dpkg -l | grep -q bbb-playback-video; then
apt install -y bbb-playback-video
systemctl restart bbb-rap-resque-worker.service
fi

Enable generating mp4 (H.264) video output​

By default, the presentation and screenshare recording formats generate their videos as .webm files using the VP9 video codec. These are supported in most desktop web browsers, but might not work on iOS mobile devices. You can additionally enable the H.264 video codec (keep in mind that the .yml files mentioned below only exist when the respective format package is installed):

video

The video format already produces an .mp4 (H.264) file by default. To generate a .webm file as well, edit /usr/local/bigbluebutton/core/scripts/video.yml and uncomment the video/webm entry under formats:.

The encoding options can be adjusted to speed up encoding or increase quality of video generation as desired.

presentation

Add mp4 to video_formats in /etc/bigbluebutton/recording/presentation.yml (the override of /usr/local/bigbluebutton/core/scripts/presentation.yml):

video_formats:
- webm
- mp4

screenshare

Edit the file /usr/local/bigbluebutton/core/scripts/screenshare.yml and uncomment the lines under the :formats: label for the mime type video/mp4:

- :mimetype: 'video/mp4; codecs="avc1.640028, mp4a.40.2"'
:extension: mp4
:parameters:
- [ '-c:v', 'libx264', '-crf', '21', '-preset', 'medium', '-profile:v', 'high', '-level', '40', '-g', '240',
'-c:a', 'aac', '-b:a', '96K',
'-threads', '2', '-f', 'mp4', '-movflags', 'faststart' ]

The encoding options can be adjusted to speed up encoding or increase quality of video generation as desired.

Video​

Reduce bandwidth from webcams​

You can use a bandwidth usage on your BigBlueButton server using a tool such as bmon (sudo apt-get install bmon). You can change the maximum bandwidth settings for each webcam options (low, medium, high, high definition) by editing /usr/share/bigbluebutton/html5-client/private/config/settings.yml and modifying the entries for

cameraProfiles:
- id: low
name: Low quality
default: false
bitrate: 100
- id: medium
name: Medium quality
default: true
bitrate: 200
- id: high
name: High quality
default: false
bitrate: 500
- id: hd
name: High definition
default: false
bitrate: 800

The settings for bitrate are in kbits/sec (i.e. 100 kbits/sec). After your modify the values, save the file, restart your BigBlueButton server sudo bbb-conf --restart to have the settings take effect. The lowest setting allowed for WebRTC is 30 Kbits/sec.

If you have sessions that like to share lots of webcams, such as ten or more, then setting the bitrate for low to 50 and medium to 100 will help reduce the overall bandwidth on the server. When many webcams are shared, the size of the webcams get so small that the reduction in bitrate will not be noticeable during the live sessions.

To ensure that your modifications are not lost when a new version of the packages is installed, you can [create the file and] write your changes to /etc/bigbluebutton/bbb-html5.yml.

Validating client settings overrides​

When you override the HTML5 client settings - via /etc/bigbluebutton/bbb-html5.yml, or per meeting via the clientSettingsOverride / clientSettingsOverrideJsonUrl create parameters - keys that do not exist in the base settings.yml (typos, obsolete parameters, or values placed at the wrong level in the structure) are merged in but never read by the client, so they are silently ignored.

BigBlueButton logs a WARN in bbb-apps-akka for each such key so the problem is visible. The warning is non-blocking: the value is still applied.

For test and staging environments you can additionally enable strict validation, which turns those warnings into hard failures. It is disabled by default and controlled by a single setting, clientSettingsOverrideStrictValidation, in /etc/bigbluebutton/bbb-web.properties. Both bbb-web and bbb-apps-akka read this same property (akka reads the file directly at boot), so there is one switch and no risk of the two processes disagreeing. When set to true:

  • Filesystem override (/etc/bigbluebutton/bbb-html5.yml), enforced by bbb-apps-akka at boot. If the override file has issues, bbb-apps-akka logs an explicit error listing each offending key and exits (the service fails to start), so a bad config breaks the deploy instead of running silently wrong.
  • API override (clientSettingsOverride / clientSettingsOverrideJsonUrl), enforced by bbb-web at create. If a /create call carries an override with issues, the call is rejected with returncode=FAILED and messageKey=clientSettingsOverrideValidationError, with the offending keys listed in the message; the meeting is not created.

Keep it false in production unless you specifically want such overrides to be rejected.

Disable webcams​

You can disable webcams by setting enableVideo to false in the /etc/bigbluebutton/bbb-html5.yml file for the HTML5 client.

test -s /etc/bigbluebutton/bbb-html5.yml || echo '{}' > /etc/bigbluebutton/bbb-html5.yml

yq-go e -i '.public.kurento.enableVideo = false' /etc/bigbluebutton/bbb-html5.yml

and run bbb-conf --restart

Disable screen sharing​

You can disable screen sharing by setting enableScreensharing to false in the /etc/bigbluebutton/bbb-html5.yml file for the HTML5 client.

test -s /etc/bigbluebutton/bbb-html5.yml || echo '{}' > /etc/bigbluebutton/bbb-html5.yml

yq-go e -i '.public.kurento.enableScreensharing = false' /etc/bigbluebutton/bbb-html5.yml

Reduce bandwidth for webcams​

If you expect users to share many webcams, you can reduce the bandwidth for webcams. For this you would need to make changes to public.kurento.cameraProfiles through an override.

Note: if you have made other changes in the section public.kurento.cameraProfiles in /etc/bigbluebutton/bbb-html5.yml you would want to proceed with caution. You would likely only want to run the commands on the bottom, skipping the loading of cameraProfiles.

The following command will copy ALL of the DEFAULT camera profiles from the source /usr/share/bigbluebutton/html5-client/private/config/settings.yml to the override location /etc/bigbluebutton/bbb-html5.yml. If you had previous related overrides, you likely do not want to run this command.

test -s /etc/bigbluebutton/bbb-html5.yml || echo '{}' > /etc/bigbluebutton/bbb-html5.yml

yq-go e -i '.public.kurento.cameraProfiles = (load("/usr/share/bigbluebutton/html5-client/private/config/settings.yml") | .public.kurento.cameraProfiles)' /etc/bigbluebutton/bbb-html5.yml

Now that you have the list of camera profiles in /etc/bigbluebutton/bbb-html5.yml, the following yq-go commands will tweak the bitrate and whether the profile is default.

echo " - Setting camera defaults"

test -s /etc/bigbluebutton/bbb-html5.yml || echo '{}' > /etc/bigbluebutton/bbb-html5.yml

yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "low") ).bitrate = 50' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "medium") ).bitrate = 100' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "high") ).bitrate = 200' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "hd") ).bitrate = 300' /etc/bigbluebutton/bbb-html5.yml

yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "low") ).default = true' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "medium") ).default = false' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "high") ).default = false' /etc/bigbluebutton/bbb-html5.yml
yq-go e -i '( .public.kurento.cameraProfiles[] | select(.id == "hd") ).default = false' /etc/bigbluebutton/bbb-html5.yml

Change screen sharing quality parameters​

Screen sharing quality can be tweaked to either improve quality or reduce bandwidth usage. There are different configurations for live meetings and recordings and they need to be changed independently from each other.

For recordings, the following parameters can be changed (presentation format):

  • /usr/local/bigbluebutton/core/scripts/presentation.yml: deskshare_output_width (default: 1280)
  • /usr/local/bigbluebutton/core/scripts/presentation.yml: deskshare_output_height (default: 720)
  • /usr/local/bigbluebutton/core/scripts/presentation.yml: deskshare_output_framerate (default: 5)

As an example, suppose you want to increase the output resolution and framerate of the recorded screen share media to match a 1080p/15 FPS stream. The following changes would be necessary:

  • $ yq-go e -i '.deskshare_output_width = 1920' /usr/local/bigbluebutton/core/scripts/presentation.yml
  • $ yq-go e -i '.deskshare_output_height = 1080' /usr/local/bigbluebutton/core/scripts/presentation.yml
  • $ yq-go e -i '.deskshare_output_framerate = 15' /usr/local/bigbluebutton/core/scripts/presentation.yml

For live meetings, the following parameters can be changed:

  • /etc/bigbluebutton/bbb-html5.yml: public.kurento.screenshare.bitrate
  • /etc/bigbluebutton/bbb-html5.yml: public.kurento.screenshare.constraints

The bitrate is specified in kbps and represents screen sharing's maximum bandwidth usage. Setting it to a higher value may improve quality but also increase bandwidth usage, while setting it to a lower value may reduce quality but will reduce average bandwidth usage. The constraints are specified as an YAML object with the same semantics as the MediaTrackConstraints from the WebRTC specification. We recommend checking the aforementioned MDN link as well as the Media Capture and Streams API spec for an extensive list of constraints. To set new screen sharing constraints, translate the JSON constraints object into an YAML format object and put it into public.kurento.screenshare.constraints. Restart BigBlueButton afterwards (sudo bbb-conf --restart). As an example, suppose you want to set the maximum screen sharing resolution to 1080p, alter the maximum bitrate to 2000 kbps and set a 10 FPS target. The following would need to be added to /etc/bigbluebutton/bbb-html5.yml:

public:
kurento:
screenshare:
bitrate: 2000
constraints:
audio: true
video:
width:
max: 1920
height:
max: 1080
frameRate:
ideal: 10
max: 10

Limit overall media streams​

On any setup for BigBlueButton server there is a cap for how many media streams can be shared. A media stream is created when a user broadcasts or receives a webcam or screen share video, or when a user joins audio listening only. If your server will be using webcams, you can set limits per user, per room, and an overall limit per server in /usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml. The default is no limit.

mediaThresholds:
global: 0
perRoom: 0
perUser: 0

For example, the following settings would limit the overall number of media across all meetings to 1000 streams, the maximum number of webcam streams per meeting to 300, and no limit on the number of webcam streams per user.

mediaThresholds:
global: 1000
perRoom: 300
perUser: 0

On a BigBlueButton 2.3 (or later) server, you can place the above in /etc/bigbluebutton/bbb-webrtc-sfu/production.yml, which bbb-webrtc-sfu will use to override the settings in default.yml (even after package upgrades).

If any of these thresholds are reached, then a user will receive a "Media resources not available (2002)" error when sharing webcams.

BigBlueButton will dynamically reduce the number of webcams in a meeting as the meeting grows larger. These are set in /usr/share/bigbluebutton/html5-client/private/config/settings.yml, but you can override them by placing them in /etc/bigbluebutton/bbb-html5.yml.

For example, the following /etc/bigbluebutton/bbb-html5.yml file would ensure that no single meeting will have more than 300 streams. For example, in a meeting with 30 users, the moderator will see 25 webcams and the viewers 6 webcams. This gives 25 + 29 _ 6 = 196 webcam streams. If the meeting grows to 100 users, the moderator will see 8 webcams and viewers will see 2 webcams. This gives 8 + 99 _ 2 = 206 webcam streams.

public:
app:
defaultSettings:
application:
paginationEnabled: true
kurento:
pagination:
desktopPageSizes:
moderator: 0
viewer: 5
mobilePageSizes:
moderator: 2
viewer: 2
paginationToggleEnabled: false
paginationThresholds:
enabled: true
thresholds:
- desktopPageSizes:
moderator: 25
viewer: 6
users: 30
- desktopPageSizes:
moderator: 20
viewer: 5
users: 40
- desktopPageSizes:
moderator: 16
viewer: 4
users: 50
- desktopPageSizes:
moderator: 12
viewer: 4
users: 60
- desktopPageSizes:
moderator: 8
viewer: 3
users: 70
- desktopPageSizes:
moderator: 8
viewer: 2
users: 80
- desktopPageSizes:
moderator: 8
viewer: 2
users: 90
- desktopPageSizes:
moderator: 8
viewer: 2
users: 100

In the example above, paginationToggleEnabled: false hides the "Video pagination" switch in Settings, so no user can turn pagination off. To keep the switch for moderators only, leave paginationToggleEnabled: true and set paginationToggleModeratorOnly: true:

public:
kurento:
pagination:
paginationToggleEnabled: true
paginationToggleModeratorOnly: true

A user who cannot see the switch always gets the default from public.app.defaultSettings.application.paginationEnabled, even if they changed it earlier (for example, before being demoted from moderator).

The switch only shows when the user's page size is above 0. With the default desktopPageSizes.moderator: 0, moderators on desktop see every webcam and get no switch; set a moderator page size to give it to them.

Use custom images for virtual background​

BigBlueButton offers virtual backgrounds for webcams. To use your own background images copy them into the directory /usr/share/bigbluebutton/html5-client/resources/images/virtual-backgrounds. For each image copy a thumbnail of the image of 50x50 pixels size into /usr/share/bigbluebutton/html5-client/resources/images/virtual-backgrounds/thumbnails.

To generate thumbnails you can use the following shell snippet:

#!/bin/bash
FULL="/usr/share/bigbluebutton/html5-client/resources/images/virtual-backgrounds"
THUMB="${FULL}/thumbnails"

cd "$FULL"
for pic in *.jpg; do
convert "$pic" -resize 50x50^ -gravity Center -extent 50x50 "${THUMB}/${pic}"
done

Reference them in the configuration file /etc/bigbluebutton/bbb-html5.yml:

public:
virtualBackgrounds:
fileNames:
- image1.jpg
- image2.jpg
- image3.jpg

Background images should not be too large as clients have to download them. You can optimize them using the jpegoptim command which is available as an Ubuntu package.

Audio​

Mute all users on startup​

If you want to have all users join muted, you can add an overwrite in /etc/bigbluebutton/bbb-web.properties and set this as a server-wide configuration.

# Mute the meeting on start
muteOnStart=true

Mute state is applied to all users joining the meeting, except telephone (dial-in) users. If desired, enforcement can be enabled for telephone users by setting the following property in /etc/bigbluebutton/bbb-apps-akka.conf:

voiceConf {
dialInEnforceMuteOnStart = true
}

Restart your server with sudo bbb-conf --restart to apply the changes.

Turn off "you are now muted"​

When using audio through FreeSWITCH and/or mediasoup, you can remove this sound for all users by editing /opt/freeswitch/etc/freeswitch/autoload_configs/conference.conf.xml and moving the lines containing muted-sound and unmuted-sound into the commented section.

<profile name="cdquality">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<!--
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
-->
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="true"/>

<!-- <param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|minimize-video-encoding"/> -->

<!-- <param name="video-mode" value="mux"/> -->
<!-- <param name="video-layout-name" value="3x3"/> -->
<!-- <param name="video-layout-name" value="group:grid"/> -->
<!-- <param name="video-canvas-size" value="1920x1080"/> -->
<!-- <param name="video-canvas-bgcolor" value="#333333"/> -->
<!-- <param name="video-layout-bgcolor" value="#000000"/> -->
<!-- <param name="video-codec-bandwidth" value="2mb"/> -->
<!-- <param name="video-fps" value="15"/> -->

</profile>

If you're using audio through LiveKit, you can turn off the mute sound via /etc/bigbluebutton/bbb-html5.yml:

public:
app:
defaultSettings:
application:
muteUnmuteAudioAlerts: false

Afterwards, restart bbb-apps-akka: $ sudo systemctl restart bbb-apps-akka.

Enable background music when only one person is in a session​

FreeSWITCH enables you to have music play in the background when only one users is in the voice conference. To enable background music, edit /opt/freeswitch/conf/autoload_configs/conference.conf.xml (as root) and around line 204 you'll see the music on hold (moh-sound) commented out

<!--
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
-->

Uncomment it and save this file.

<param name="moh-sound" value="$${hold_music}"/>
<!--
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
-->

The default BigBlueButton installation does not come with any music files. You'll need to upload a music file in WAV format to the server and change a reference in /opt/freeswitch/conf/vars.xml.

For example, to use the file /opt/freeswitch/share/freeswitch/sounds/en/us/callie/ivr/48000/ivr-to_listen_to_moh.wav as music on hold, edit /opt/freeswitch/conf/vars.xml and change the line

<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>

to

<X-PRE-PROCESS cmd="set" data="hold_music=/opt/freeswitch/share/freeswitch/sounds/en/us/callie/ivr/48000/ivr-to_listen_to_moh.wav" />

and then restart BigBlueButton

$ bbb-conf --restart

and join an audio session. You should now hear music on hold if there is only one user in the session.

Add a phone number to the conference bridge​

info

This dial-in path is handled by FreeSWITCH and applies to meetings that use the FreeSWITCH audio bridge (audioBridge=bbb-webrtc-sfu). LiveKit is the default audio bridge in BigBlueButton 4.0; to set up dial-in for LiveKit meetings, see Dial-in with the LiveKit audio bridge below.

The built-in WebRTC-based audio in BigBlueButton is very high quality audio. Still, there may be cases where you want users to be able to dial into the conference bridge using a telephone number.

Before you can configure FreeSWITCH to route the call to the right conference, you need to first obtain a phone number from an Internet Telephone Service Provider (see the FreeSWITCH documentation) and configure FreeSWITCH accordingly to receive incoming calls via session initiation protocol (SIP) from that provider. Ensure that the context is public and that the file is called /opt/freeswitch/conf/sip_profiles/external/YOUR-PROVIDER.xml. Here is an example; of course, hostname and ALL-CAPS values need to be changed:

<include>
<gateway name="ANY-NAME-FOR-YOUR-PROVIDER">
<param name="proxy" value="sip.example.net"/>
<param name="username" value="PROVIDER-ACCOUNT"/>
<param name="password" value="PROVIDER-PASSWORD"/>
<param name="extension" value="EXTERNALDID"/>
<param name="register" value="true"/>
<param name="context" value="public"/>
</gateway>
</include>

To route the incoming call to the correct BigBlueButton audio conference, you need to create a dialplan which, for FreeSWITCH, is a set of instructions that it runs when receiving an incoming call. When a user calls the phone number, the dialplan will prompt the user to enter a five digit number associated with the conference.

To create the dialplan, use the XML below and save it to /opt/freeswitch/conf/dialplan/public/my_provider.xml. Replace EXTERNALDID with the value specified as the extension in the SIP profile (such as 6135551234, but see above).

<extension name="from_my_provider">
<condition field="destination_number" expression="^EXTERNALDID">
<action application="start_dtmf" />
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="play_and_get_digits" data="5 9 3 30000 # conference/conf-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>

<!-- Uncomment the following block if you want to mask the phone number in the list of participants. -->
<!-- Instead of `01711233121` it will then show `xxx-xxx-3121`. -->
<!--
<action application="set_profile_var" data="caller_id_name=${regex(${caller_id_name}|^.*(.{4})$|xxx-xxx-%1)}"/>
-->

<action application="transfer" data="SEND_TO_CONFERENCE XML public"/>
</condition>
</extension>
<extension name="check_if_conference_active">
<condition field="${conference ${pin} list}" expression="/sofia/g" />
<condition field="destination_number" expression="^SEND_TO_CONFERENCE$">
<action application="set" data="bbb_authorized=true"/>
<action application="transfer" data="${pin} XML default"/>
</condition>
</extension>

<extension name="conf_bad_pin">
<condition field="${pin}" expression="^\d{5}$">
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="play_and_get_digits" data="5 9 3 30000 # conference/conf-bad-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>
<action application="transfer" data="SEND_TO_CONFERENCE XML public"/>
</condition>
</extension>

Change ownership of this file to freeswitch:daemon

$ chown freeswitch:daemon /opt/freeswitch/conf/dialplan/public/my_provider.xml

and then restart FreeSWITCH:

$ sudo systemctl restart freeswitch

Try calling the phone number. It should connect to FreeSWITCH and you should hear a voice prompting you to enter the five digit PIN number for the conference. Please note, that dialin will currently only work if at least one web participant has joined with their microphone.

To always show users the phone number along with the 5-digit PIN number within BigBlueButton, not only while selecting the microphone participation, edit /etc/bigbluebutton/bbb-web.properties and set the phone number provided by your Internet Telephone Service Provider

#----------------------------------------------------
# Default dial access number
defaultDialAccessNumber=613-555-1234

and set defaultWelcomeMessageFooter to

defaultWelcomeMessageFooter=<br><br>To join this meeting by phone, dial:<br> %%DIALNUM%%<br>Then enter %%CONFNUM%%# as the conference PIN number.

Save /etc/bigbluebutton/bbb-web.properties and restart BigBlueButton again. Each user that joins a session will see a message in the chat similar to.

To join this meeting by phone, dial:
613-555-1234
and enter 12345 as the conference PIN number.

Finally, setup the firewall rules so you are only accepting incoming calls from the IP address of your SIP provider. For example, if your SIP provider forwards incoming calls from 64.2.142.33, then setup the following firewall rules on your server.

iptables -A INPUT -i eth0 -p tcp --dport 5060 -s 0.0.0.0/0 -j REJECT
iptables -A INPUT -i eth0 -p udp --dport 5060 -s 0.0.0.0/0 -j REJECT
iptables -A INPUT -i eth0 -p tcp --dport 5080 -s 0.0.0.0/0 -j REJECT
iptables -A INPUT -i eth0 -p udp --dport 5080 -s 0.0.0.0/0 -j REJECT
iptables -I INPUT -p udp --dport 5060 -s 64.2.142.33 -j ACCEPT

With these rules, you won't get spammed by bots scanning for SIP endpoints and trying to connect.

It's also important to note that, alongside the PIN requirement, there are basic dialplan-level checks in place to prevent anonymous dial-in callers from joining BigBlueButton audio conferences.

  • Those checks offer minimal protection regarding blocking anonymous SIP participants and should not be considered a comprehensive solution. For production environments requiring stronger security controls, administrators are responsible for implementing additional measures that match the sensitivity of their deployments.
  • If you want to allow anonymous SIP UAs, you need to remove the reject_anonymous extension in /opt/freeswitch/conf/dialplan/default/bbb_conference.xml, then restart FreeSWITCH.

Dial-in with the LiveKit audio bridge (livekit-sip)​

LiveKit is the default audio bridge in BigBlueButton 4.0. For meetings that use the LiveKit audio bridge, telephone dial-in is handled by livekit-sip.

The dial-in flow is: the caller reaches a SIP call gateway (a FreeSWITCH — either BigBlueButton's bundled one or an external one) that answers the call and prompts for the conference PIN; the gateway then bridges the authenticated call into livekit-sip, which joins the LiveKit room as a SIP participant.

LiveKit dial-in is opt-in. Enable the LiveKit SIP controller in /etc/bigbluebutton/bbb-webrtc-sfu/production.yml:

livekit:
rtcAgent:
enabled: true
sip:
enabled: true
requirePin: false # the PIN is enforced by FreeSWITCH, not by livekit-sip
dispatch:
options:
hidePhoneNumber: true

Then set up a SIP call gateway — BigBlueButton's bundled FreeSWITCH, or an external one.

Using the bundled FreeSWITCH as the call gateway​

In this setup the FreeSWITCH that ships with BigBlueButton plays the call-gateway role: it answers the call, prompts for the PIN, and then bridges the call into livekit-sip over a local leg. The PIN is prompted by FreeSWITCH (not by livekit-sip).

DTMF (e.g. to mute) flows caller → FreeSWITCH (a-leg) → the FreeSWITCH-to-livekit-sip bridge (b-leg) → livekit-sip. FreeSWITCH converts the inbound DTMF (RFC 2833 or SIP INFO from the trunk) to RFC 2833 on the bridge leg. livekit-sip accepts DTMF only as RFC 2833.

note

For the DID covered by the dialplan below, this replaces the FreeSWITCH-audio-bridge dial-in path: meetings created with audioBridge=bbb-webrtc-sfu will no longer be reachable through that DID. To support both audio bridges on the same server, use distinct DIDs and gate the dialplan on destination_number (one extension routes to mod_conference, the other bridges to livekit-sip).

  1. Provision the SIP trunk in the bundled FreeSWITCH exactly as for the FreeSWITCH audio bridge — see Add a phone number to the conference bridge. That covers the SIP gateway file under /opt/freeswitch/conf/sip_profiles/external/ and the defaultDialAccessNumber / welcome footer in /etc/bigbluebutton/bbb-web.properties.

  2. livekit-sip listens on port 5062 by default. To change it, set in /etc/bigbluebutton/livekit-sip.yaml, and use the same port in the bridge in step 3:

    sip_port: 5062
    sip_port_listen: 5062
  3. Instead of the FreeSWITCH-bridge dialplan, install a dialplan that bridges to livekit-sip after the PIN prompt. Save it to /opt/freeswitch/conf/dialplan/public/my_provider.xml and replace EXTERNALDID with the DID configured on the SIP gateway:

    <include>
    <extension name="from_my_provider_lk">
    <condition field="destination_number" expression="^EXTERNALDID">
    <action application="start_dtmf"/>
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="play_and_get_digits" data="5 9 3 30000 # conference/conf-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>

    <!-- Optional: phone-number masking, identical to the FreeSWITCH-bridge example above. -->
    <!--
    <action application="set_profile_var" data="caller_id_name=${regex(${caller_id_name}|^.*(.{4})$|xxx-xxx-%1)}"/>
    -->

    <action application="transfer" data="SEND_TO_LIVEKIT_SIP XML public"/>
    </condition>
    </extension>

    <extension name="bbb_lk_sip_bridge">
    <condition field="destination_number" expression="^SEND_TO_LIVEKIT_SIP$">
    <!-- Stop in-band DTMF detection: the trunk's RFC 2833 or SIP INFO digits
    reach livekit-sip without it. For a trunk that sends DTMF only as
    tones, remove this line (see DTMF troubleshooting). -->
    <action application="stop_dtmf"/>
    <!-- Hang up the caller when livekit-sip ends the call; go back to the
    PIN prompt when the bridge fails. -->
    <action application="set" data="hangup_after_bridge=true"/>
    <action application="set" data="continue_on_fail=true"/>
    <!-- Stop waiting for livekit-sip to answer after 15 s (the default is 60 s). -->
    <action application="set" data="call_timeout=15"/>
    <!-- livekit-sip takes DTMF only as RFC 2833, and the BBB external
    profile defaults to dtmf-type=info. dtmf_type applies to the
    bridged leg only, so the trunk leg keeps its own DTMF mode.
    absolute_codec_string keeps the codecs compatible across all legs
    (provider, gateway and livekit-sip). The quotes keep the list in
    one variable. -->
    <action application="bridge" data="{absolute_codec_string='G722,PCMU,PCMA',dtmf_type=rfc2833}sofia/external/sip:${pin}@${local_ip_v4}:5062;transport=udp"/>
    <action application="transfer" data="LK_BAD_PIN XML public"/>
    </condition>
    </extension>

    <extension name="bbb_lk_bad_pin">
    <condition field="destination_number" expression="^LK_BAD_PIN$">
    <action application="answer"/>
    <action application="sleep" data="1000"/>
    <action application="play_and_get_digits" data="5 9 3 30000 # conference/conf-bad-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>
    <action application="transfer" data="SEND_TO_LIVEKIT_SIP XML public"/>
    </condition>
    </extension>
    </include>
  4. Restart BigBlueButton:

    sudo bbb-conf --restart
  5. Verify the components are running, then place a test call:

    sudo bbb-conf --status
    sudo systemctl status freeswitch livekit-sip bbb-webrtc-sfu

    The caller should hear the BigBlueButton PIN prompt; after entering the meeting's voice bridge, the call should appear in the LiveKit room as a SIP participant. * or 0 toggles mute.

Using an external call gateway​

In this setup an external FreeSWITCH acts as the call gateway (the same role it plays in, for example, a Scalelite dial-in deployment), and livekit-sip takes over the SIP port that the bundled FreeSWITCH would otherwise use.

warning

The steps below move the bundled FreeSWITCH off port 5060 and therefore break FreeSWITCH-based dial-in (audioBridge=bbb-webrtc-sfu) for the whole server. To serve both bridges, the call gateway must be aware of the audio bridge in use — for example, keep the bundled FreeSWITCH on 5060 and livekit-sip on 5062, and have your load balancer build the gateway's dialplan to route to the right port (5060 for audioBridge=bbb-webrtc-sfu, 5062 for audioBridge=livekit). If you take that approach, adjust the ports below accordingly.

  1. Configure the external call gateway as you would today (see the Scalelite dial-in guide).

  2. Move the bundled FreeSWITCH's SIP bind port off 5060 (to avoid colliding with livekit-sip). In /opt/freeswitch/conf/vars.xml:

    <X-PRE-PROCESS cmd="set" data="external_sip_port=5063"/>
  3. Point livekit-sip at 5060, and give it an RTP port range with connectivity to the call gateway. In /etc/bigbluebutton/livekit-sip.yaml:

    sip_port: 5060
    sip_port_listen: 5060
    rtp_port: <START>-<END>

    Note: By default livekit-sip shares 16384-32768 with the other media servers, and bbb-conf --set-port-range moves them all, overwriting rtp_port. The call gateway needs UDP access to the range in use (see Configure the firewall).

  4. Restart BigBlueButton:

    sudo bbb-conf --restart
  5. Verify all components are running:

    sudo bbb-conf --status
    sudo systemctl status livekit-sip
DTMF troubleshooting​

If DTMF passes through to FreeSWITCH during the PIN prompt but does not reach livekit-sip after the bridge:

  • Confirm that liberal-dtmf=true is set on the external SIP profile (it is BigBlueButton's default; rtp_liberal_dtmf=true is set globally in vars.xml).
  • If the trunk sends DTMF only as in-band tones, remove stop_dtmf from the bbb_lk_sip_bridge extension. FreeSWITCH then turns the tones into RFC 2833 events.
Limitations​
  • The guest lobby is bypassed for SIP dial-in callers.

Turn on the "comfort noise" when no one is speaking​

FreeSWITCH has the ability to add a "comfort noise" that is a slight background hiss to let users know they are still in a voice conference even when no one is talking (otherwise, they may forget they are connected to the conference bridge and say something unintended for others).

If you want to enable, edit /opt/freeswitch/conf/autoload_configs/conference.conf.xml, look for the block <profile name="cdquality">, and change the value for comfort-noise. You can specify a level of noise, such as 0 (no noise), 350, 1400, etc. Try different values to get the level you desire.

<param name="comfort-noise" value="1400"/>

You need to restart BigBlueButton between each change. For more information, see mod_conference in the FreeSWITCH documentation.

$ sudo bbb-conf --restart

Presentation​

Change the default presentation​

When a new meeting starts, BigBlueButton displays a default presentation. The file for the default presentation is located in /var/www/bigbluebutton-default/assets/default.pdf. You can replace the contents of this file with your presentation. Whenever a meeting is created, BigBlueButton will automatically load, convert, and display this presentation for all users. Note that this file may be overwritten when BigBlueButton is upgraded.

Alternatively, you can change the global default by adding an overwriting rule in /etc/bigbluebutton/bbb-web.properties specifying the URL for beans.presentationService.defaultUploadedPresentation.

# Default Uploaded presentation file
beans.presentationService.defaultUploadedPresentation=${bigbluebutton.web.serverURL}/default.pdf

Please use the file name "default.pdf" if you would not like BigBlueButton to generate thumbnails from this file. The thumbnails will be used in some frontend apps, such as Greenlight.

You'll need to restart BigBlueButton after the change with sudo bbb-conf --restart.

If you want to specify the default presentation for a given meeting, you can also pass a URL to the presentation as part of the create meeting API call.

Increase the 200 page limit for uploads​

BigBlueButton, by default, restricts uploads to 200 pages. To increase this value, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties and set the maxNumPages value:

#----------------------------------------------------
# Maximum number of pages allowed for an uploaded presentation (default 200).
maxNumPages=200

After you save the changes to /etc/bigbluebutton/bbb-web.properties, restart the BigBlueButton server with

$ sudo bbb-conf --restart

Tune parallel downloads of pre-uploaded presentations​

Presentations pre-uploaded through the create or insertDocument API calls are downloaded and processed in the background, on a bounded thread pool, so the API response is not delayed. By default up to 5 documents are downloaded in parallel per server; additional documents wait in a bounded queue. If the server is under sustained overload and that queue is full, further presentation tasks are rejected (and logged) instead of being queued without limit, which protects the server from running out of memory. A rejected presentation is not uploaded into the meeting, and — like a download or conversion failure — this is not reflected in the create/insertDocument API response (which has already returned); it is only visible in the server log. To change the parallelism, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties and set the numPresentationDownloadThreads value (values below 1 are treated as 1):

numPresentationDownloadThreads=5

After you save the changes to /etc/bigbluebutton/bbb-web.properties, restart the BigBlueButton server with

sudo bbb-conf --restart

Rasterize slides whose SVG contains mask tags​

Some PDFs produce slides whose generated SVG contains <mask> elements (used for soft-masked/alpha images). On systems where those mask values are rendered incorrectly, the affected slides can show visual artifacts. To work around this, bbb-web can fall back to full-slide rasterization (the same fallback used by imageTagThreshold and useTagThreshold: the page is rendered to a PNG image with pdftoppm and embedded in the slide) for any slide whose SVG contains a configurable number of <mask> tags.

The check is disabled by default (maskTagThreshold=0), because masks are common in ordinary PDFs and the pdftocairo shipped with Ubuntu 24.04 (poppler 24.02.0) generates correct mask values. To rasterize only mask-heavy slides, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties:

maskTagThreshold=100

A slide is rasterized when its SVG contains at least maskTagThreshold mask tags (a value of 1 would rasterize any slide containing a mask). After you save the changes, restart the BigBlueButton server with sudo bbb-conf --restart.

Verify slides with soft masks​

Soft masks (images with transparency, drop shadows, blurred or faded edges) are common in PDFs and mostly convert to a correct SVG. Some do not: pdftocairo, which generates the slide SVG, drops the content behind certain soft masks (for example the ones written by macOS), so the image, or the whole slide, shows up blank (#23953).

pdftocairo emits <filter> tags whenever a page has soft masks, so bbb-web verifies every slide whose SVG contains at least filterTagThreshold <filter> tags. It renders the page at low resolution with both pdftocairo and pdftoppm, and rasterizes the slide only when the two renders noticeably differ. The check is enabled by default (filterTagThreshold=1) and costs a fraction of a second per verified slide. Slides that are verified and match keep their vector SVG. If the comparison cannot be made, or the rasterized slide is too large to embed, the vector SVG is kept as well.

To turn the check off, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties:

filterTagThreshold=0

With the check off, affected slides may show up blank or with missing images again. To rasterize every slide with soft masks without verifying it first, use maskTagThreshold=1 instead (see above). After you save the changes, restart the BigBlueButton server with sudo bbb-conf --restart.

Increase the file size for an uploaded presentation​

The default maximum file upload size for an uploaded presentation is 30 MB. The limit is enforced by bbb-web and by the HTML5 client; nginx (/usr/share/bigbluebutton/nginx/web.nginx) already accepts uploads of up to 1000 MB, so it does not need to change for limits below that.

Change the restriction in bbb-web. Add an overwrite rule in /etc/bigbluebutton/bbb-web.properties and set the value maxFileSizeUpload.

# Maximum file size for an uploaded presentation (default 30MB).
maxFileSizeUpload=30000000

You will have to additionally increase the size for the HTML5 client, edit /usr/share/bigbluebutton/html5-client/private/config/settings.yml or /etc/bigbluebutton/bbb-html5.yml (recommended) and modify uploadSizeMax.

Restart BigBlueButton with sudo bbb-conf --restart. You should now be able to upload larger presentations within the new limit.

Limit the number of presentations per API request​

By default, BigBlueButton processes at most 10 presentations per create or insertDocument API call. If a single request references more presentations than this limit, BigBlueButton processes the first maxPresentationsPerRequest presentations (in the order they appear in the request) and ignores the rest, logging a warning for each request that exceeds the limit. The API response still has the returncode SUCCESS, and adds the messageKey documentsDropped, with a message saying how many presentations were accepted.

To change this limit, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties and set the maxPresentationsPerRequest value:

#----------------------------------------------------
# Maximum number of presentations processed per create/insertDocument API call (default 10).
maxPresentationsPerRequest=10

Set the value to 0 to disable the limit entirely.

After you save the changes to /etc/bigbluebutton/bbb-web.properties, restart the BigBlueButton server with

$ sudo bbb-conf --restart

Rate limit presentation uploads​

BigBlueButton has several independent controls over presentation uploads. They protect different things, so it is worth knowing which one to reach for. Set any of the *MaxRequests settings, or presentationMaxPerPod, to 0 to disable that limit entirely.

Limit conversion load (the main resource control)​

Presentation conversion is the most resource-intensive part of an upload. bbb-web caps how many presentations may enter the conversion pipeline for a single meeting:

  • 20 presentations per meeting within a rolling 60-second window (presentationConversionMaxRequests / presentationConversionRateWindowSec).

This limit is enforced at the single point every upload passes through, so unlike the other limits it covers all the ways a participant or an API caller can request one: the interactive client upload, create with pre-uploaded presentations, insertDocument, and the presentation copied into a new breakout room. An over-limit presentation is discarded and its uploaded file deleted before any conversion work is scheduled, and a warning is logged in bbb-web. The upload toast shows an error to the participant who uploaded the file or, for create and insertDocument documents, to the presenter.

Content the server itself imports when a breakout room ends — captured slides and captured shared notes, which arrive in the parent meeting — is not counted against this limit. That content only exists in the room that produced it and the room is destroyed immediately afterwards, so discarding it would lose it permanently with nothing left to retry from.

Be aware that this means no conversion rate limit applies to captures. apps.presentationMaxPerPod is not a substitute: it caps how many presentations a pod holds, which is meeting state, it is checked in bbb-apps-akka only once conversion has already started, and captures may go past it up to twice its value (see below). Ending a breakout session imports up to two presentations per room (captured slides and captured shared notes are separate uploads, each behind its own setting), all at once, so a session with many rooms produces a corresponding burst of conversion work in the parent meeting.

The limit is keyed by internal meeting ID, so a throttled meeting recovers once the window passes. To change the values, add an overwrite rule in /etc/bigbluebutton/bbb-web.properties:

#----------------------------------------------------
# Rate limit on presentations entering the conversion pipeline, per meeting
# (defaults: 20 per 60s). 0 = disabled.
presentationConversionMaxRequests=20
presentationConversionRateWindowSec=60

When raising or lowering this, note the floor: a single create call may carry up to maxPresentationsPerRequest documents plus the automatically injected default presentation, so a value below that will drop documents from a legitimate create.

Limit how many presentations a pod holds​

bbb-apps-akka caps how many presentations a single presentation pod may contain:

  • 50 presentations per presentation pod (presentationMaxPerPod).

This caps meeting state — how many presentations exist in the pod and appear in the client's presentation list. To bound conversion load, use presentationConversionMaxRequests above.

An over-limit presentation is refused entry to the pod and a warning is logged in bbb-apps-akka.

  • Interactive uploads are refused when the client asks for an upload token, before the file is sent. The presenter sees "Maximum of N presentations reached" in the upload toast. The check counts the presentations already in the pod, not uploads still in progress, so when the presenter selects several files at once, each of them gets a token and is sent. Those that would take the pod past the cap are then refused when their conversion starts, as described for create and insertDocument below. presentationUploadTokenMaxRequests bounds how many files one such selection can send.
  • create and insertDocument documents do not request a token, so the cap is checked when their conversion starts. bbb-apps-akka then tells bbb-web, which schedules no more pages for the presentation and deletes its files once any work already running has finished (after maxPageConversionTime). Office-to-PDF conversion and page counting have run by that point; presentationConversionMaxRequests bounds that work. The presenter sees "Maximum of N presentations reached" in the upload toast.
  • Captured slides and shared notes from an ended breakout room may go past the cap, up to twice its value (100 by default), for the same reason they are exempt from presentationConversionMaxRequests: the room is gone, so refusing them would lose them. Past twice the cap they are refused like any other presentation, and the presenter sees "Maximum of N presentations reached" with N twice the cap. While captures keep a pod above the cap, other uploads are refused until enough presentations are removed to bring it below the cap again.
Limit how fast one presenter can request uploads​

bbb-apps-akka rate limits presentation upload-token requests per user:

  • 20 upload-token requests per user within a rolling 60-second window (presentationUploadTokenMaxRequests / presentationUploadTokenWindowSec).

This covers the interactive client path only, because only the client requests an upload token. It does not apply to create, insertDocument, or breakout-room slide copies.

A refused request is not uploaded, and the upload toast shows "You are uploading too many presentations at once" for each refused file, up to 100 files per user in each window. Further refused files in the window show the notification "The upload could not start. Please wait a moment and try again." instead. Entries from earlier windows are removed as newer refusals arrive. Requests refused by presentationMaxPerPod also count towards this limit, and each of them shows "Maximum of N presentations reached".

To change either bbb-apps-akka limit, add an overwrite rule in /etc/bigbluebutton/bbb-apps-akka.conf under the apps block:

apps {
# Maximum presentation upload-token requests allowed per user within the window below.
# 0 = disabled
presentationUploadTokenMaxRequests = 20
# Length in seconds of the per-user rate-limit window.
presentationUploadTokenWindowSec = 60
# Maximum number of presentations allowed in a single presentation pod.
# 0 = disabled
presentationMaxPerPod = 50
}
Limit insertDocument API calls​

bbb-web rate limits the insertDocument API per meeting:

  • 30 insertDocument calls per meeting within a rolling 60-second window (insertDocumentMaxRequests / insertDocumentRateWindowSec).

When a meeting exceeds this rate the request is rejected with a FAILED response with the messageKey rateLimitExceeded, and a warning is logged in bbb-web. Only calls that would upload documents count: a call rejected for another reason, such as malformed XML, an invalid filename or no documents, does not use up the meeting's allowance. Once the allowance is used up, every call is rejected before its request body is read.

#----------------------------------------------------
# Rate limit for the insertDocument API, applied per meeting (defaults: 30 per 60s).
# 0 = disabled.
insertDocumentMaxRequests=30
insertDocumentRateWindowSec=60

Note how this relates to the conversion limit: insertDocumentMaxRequests bounds API calls, while presentationConversionMaxRequests bounds the presentations those calls carry. With the shipped defaults the conversion limit is the lower of the two, so that is the one to raise if a legitimate integration is being throttled.

Which limit rejected my upload?​
SettingEnforced inLog messageClient error
presentationConversionMaxRequestsbbb-webRejecting presentation conversion: per-meeting rate limit exceeded"Too many presentations were uploaded recently"
insertDocumentMaxRequestsbbb-webRejecting insertDocument: rate limit exceededAPI FAILED response, messageKey rateLimitExceeded
maxPresentationsPerRequestbbb-webPresentation count N exceeds maxPresentationsPerRequestAPI SUCCESS response, messageKey documentsDropped; the excess documents are not uploaded
presentationMaxPerPodbbb-apps-akkaRejecting presentation upload token request: pod presentation limit reached (interactive) or Rejecting presentation: pod presentation limit reached (API)"Maximum of N presentations reached"
presentationUploadTokenMaxRequestsbbb-apps-akkaRejecting presentation upload token request: request rate limit exceeded"You are uploading too many presentations at once"

Restart your server with sudo bbb-conf --restart to apply any of these changes.

Add custom fonts for presentation conversion​

BigBlueButton can use additional fonts when converting presentation files.

On the server where you want the new fonts supported you would want to download the fonts (.ttf) file. For example:

wget https://github.com/bigbluebutton/bigbluebutton/files/6391912/Street.Ruler.zip
unzip Street.Ruler.zip

Then copy the font (.ttf) to /usr/share/fonts/

sudo cp 'Street Ruler.ttf' /usr/share/fonts/

That's all! The font will be available on next presentations.

Change the limit of 300 annotations per page​

There is a cap for how many annotations can be added to a single whiteboard (slide). The default value is 300. The reason for this cap is that a large number of annotations was often the result of a student playing with the multi-user whiteboard, and it had a negative effect on other participants in the session, specifically on devices with limited CPU. In almost all cases this cap is sufficient for the normal run of classes; in very rare instances normal use of the whiteboard hits it.

In order to change the value (on per-server basis) to, say, 500 annotations in your deployment, add the following to /etc/bigbluebutton/bbb-html5.yml

public:
whiteboard:
maxNumberOfAnnotations: 500

and restart BigBlueButton via sudo bbb-conf --restart

Configure S3-based cache for presentation assets​

BigBlueButton can store the outputs (SVGs, PNGs, thumbnails and text) generated from PDFs or document files uploaded as presentations. The processed outputs are cached in an S3-based storage system, keyed by a hash of the presentation file. When the same presentation is uploaded again, the system retrieves the cached outputs, avoiding redundant processing and improving performance.

In order to enable this feature, change the file /etc/bigbluebutton/bbb-web.properties including the following content:

presentationConversionCacheEnabled=true
presentationConversionCacheS3AccessKeyId=AAAAAAAAAAAAAAAAAAAA
presentationConversionCacheS3AccessKeySecret=aaaAAAaaaaaaaaaaaAAAAAAAAAaaaaaaaaaaaaa+aaA
presentationConversionCacheS3BucketName=my-storage-name
presentationConversionCacheS3Region=nyc3
presentationConversionCacheS3EndpointURL=https://nyc3.digitaloceanspaces.com
presentationConversionCacheS3PathStyle=false

This is an example of config for DigitalOcean Spaces S3-Compatible Object Storage.

and restart BigBlueButton via sudo bbb-conf --restart

Support for ClamAV as presentation file scanner​

We have added support for ClamAV to automatically scan every presentation file for viruses before sharing it with the others in the session. To use it you would need to first install ClamAV: The simplest way would be to run it locally as a container.

docker run --name "clamav" -d \
--volume /var/bigbluebutton:/var/bigbluebutton:ro \
--publish 127.0.0.1:3310:3310 \
--memory 4G \
--cpus 1 \
--user "clamav" \
--entrypoint "/init-unprivileged" \
--restart unless-stopped \
clamav/clamav:latest

The above run command may take a minute to start. If you prefer you could run with -d flag to make it detachable.

Now when you check the running containers you should see an entry like this one:

root@test30:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8582c5c195aa clamav/clamav:latest "/init-unprivileged" About an hour ago Up About an hour (healthy) 127.0.0.1:3310->3310/tcp, 7357/tcp clamav

Additionally you will have to enable scanning: Specify scanUploadedPresentationFiles=true in /etc/bigbluebutton/bbb-web.properties and restart BigBlueButton via sudo bbb-conf --restart

When you create a new session and try uploading some presentation files, you should not see anything different if the file was fine. However, if a threat was detected, you will see the message "Upload failed: Virus detected! Please check your file and retry." in the client and the presentation sharing will not proceed. Additionally, in the logs for bbb-web you will see similar log lines:

Oct 09 01:07:18 test30 java[2810929]: 2024-10-09T01:07:18.285Z DEBUG o.b.w.c.PresentationController - processing file upload eicar.com.txt (presId: f7ff3fd7c0ab460f7139541c02df46f24ac90b67-1728436037947)
Oct 09 01:07:18 test30 java[2810929]: 2024-10-09T01:07:18.550Z DEBUG o.b.w.c.PresentationController - file upload success eicar.com.txt
Oct 09 01:07:23 test30 java[2810929]: 2024-10-09T01:07:23.589Z ERROR o.b.p.DocumentConversionServiceImp - Presentation upload failed for meetingId=4814d8e60f2e15576bebfe7cef34367ef5b54539-1728435987030 presId=f7ff3fd7c0ab460f7139541c02df46f24ac90b67-1728436037947
Oct 09 01:07:23 test30 java[2810929]: 2024-10-09T01:07:23.590Z ERROR o.b.p.DocumentConversionServiceImp - Presentation upload failed because a virus was detected in the uploaded file

You can test your setup with one of the files from eicar.org.

Frontends​

Modify the default landing page​

The default HTML landing page is located in

/var/www/bigbluebutton-default/assets/index.html

Change this page to create your own landing page (and keep a back-up copy of it as it will be overwritten during package updates to bbb-config).

Use the Greenlight front-end​

BigBlueButton comes with Greenlight, a front-end application written in Ruby on Rails that makes it easy for users to create meetings, invite others, start meetings, and manage recordings.

greenlight-start

For more information see Installing Greenlight.

Networking​

Setup a firewall​

Configuring IP firewalling is essential for securing your installation. By default, many services are reachable across the network. This allows BigBlueButton operate in clusters and private data center networks -- but if your BigBlueButton server is publicly available on the internet, you need to run a firewall to reduce access to the minimal required ports.

If your server is behind a firewall already -- such as running within your company or on an EC2 instance behind a Amazon Security Group -- and the firewall is enforcing the above restrictions, you don't need a second firewall and can skip this section.

BigBlueButton comes with a UFW based ruleset. It it can be applied on restart and restricts access only to the following needed ports:

  • TCP/IP port 22 for SSH
  • TCP/IP port 80 for HTTP
  • TCP/IP port 443 for HTTPS
  • TCP and UDP port 3478 for the built-in TURN server (opened only if HAProxy is enabled and running when the rules are applied)
  • UDP ports 16384 to 32768 for media connections

Note: if you have configured sshd (the OpenSSH daemon) to use a different port than 22, then before running the commands below, change ufw allow OpenSSH to ufw allow <port>/tcp where <port> is the port in use by sshd. You can see the listening port for sshd using the command ss -tlnp | grep sshd. Here the command shows sshd listening to the standard port 22.

$ sudo ss -tlnp | grep sshd
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1739,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1739,fd=4))

To restrict external access minimal needed ports for BigBlueButton. BigBlueButton supplies a helper function that you can call in /etc/bigbluebutton/bbb-conf/apply-config.sh to setup a minimal firewall (see Setup Firewall).

You can also do it manually with the following commands

$ apt-get install -y ufw
ufw allow OpenSSH
ufw allow "Nginx Full"
ufw allow 3478
ufw allow 16384:32768/udp
ufw --force enable

These ufw firewall rules will be automatically re-applied on server reboot.

Besides IP-based firewalling, you can explore web application firewalls such as ModSecurity that provide additional security by checking requests to various web-based components.

Setup Firewall​

To configure a firewall for your BigBlueButton server (recommended), add enableUFWRules to /etc/bigbluebutton/bbb-conf/apply-config.sh, as in

enableUFWRules

The helper opens port 3478 for the built-in TURN server only if HAProxy is enabled and active when it runs, and removes the rule otherwise; if you enable the TURN server later, run bbb-conf --restart again so the rule is added.

With enableUFWRule added to apply-config.sh, whenever you do bbb-conf with --restart or --setip, you'll see the following output

sudo bbb-conf --restart

Restarting BigBlueButton ..
Stopping BigBlueButton

Applying updates in /etc/bigbluebutton/bbb-conf/apply-config.sh:
- Enable Firewall and opening 22/tcp, 80/tcp, 443/tcp and 16384:32768/udp
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Firewall is active and enabled on system startup

Starting BigBlueButton

Change UDP ports​

By default, BigBlueButton uses the UDP ports 16384-32768, which are used by LiveKit, livekit-sip, FreeSWITCH, mediasoup and bbb-webrtc-recorder to send real-time packets (RTP).

LiveKit (the default media server) uses the whole range 16384 - 32768, which is defined in /usr/share/livekit-server/livekit.yaml; override it in /etc/bigbluebutton/livekit.yaml:

rtc:
port_range_start: 16384
port_range_end: 32768

livekit-sip (the telephone dial-in of the LiveKit audio bridge) uses the same range, which is defined as rtp_port in /usr/share/livekit-server/livekit-sip.yaml; override it in /etc/bigbluebutton/livekit-sip.yaml:

rtp_port: 16384-32768

FreeSWITCH uses the range 16384 - 24576, which is defined in /opt/freeswitch/etc/freeswitch/autoload_configs/switch.conf.xml

<!-- RTP port range -->
<param name="rtp-start-port" value="16384"/>
<param name="rtp-end-port" value="24576"/>

bbb-webrtc-recorder uses the range 24577 - 32768, which is defined in /etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml (default) or /etc/bigbluebutton/bbb-webrtc-recorder.yml (override)

[...]
webrtc:
rtcMinPort: 24577
rtcMaxPort: 32768
[...]

mediasoup also uses 24577 - 32768 by default (defined in /usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml). If it needs to be changed, bbb-webrtc-sfu's override configuration file (located in /etc/bigbluebutton/bbb-webrtc-sfu/production.yml) should be used. For example, setting the range to 50000 - 51999 should be of the following format (YAML syntax, /etc/bigbluebutton/bbb-webrtc-sfu/production.yml):

mediasoup:
worker:
rtcMinPort: 50000
rtcMaxPort: 51999

To move the whole range in one go, sudo bbb-conf --set-port-range <min>-<max> writes the same range into FreeSWITCH, mediasoup, bbb-webrtc-recorder, LiveKit and livekit-sip; restart BigBlueButton afterwards. Remember to open the new range in your firewall. Caveats:

  • switch.conf.xml isn't preserved on bbb-freeswitch-core upgrades, so FreeSWITCH goes back to 16384-24576 - re-run the command after upgrading;
  • if /etc/bigbluebutton/bbb-webrtc-recorder.yml exists, the recorder ignores the file the command writes to - set the range in the override as well.

Apply custom settings for TURN server​

If you always want a specific TURN server configuration, add the following to apply-config.sh and modify aaa.bbb.ccc.ddd and secret with your values.

echo " - Update TURN server configuration turn-stun-servers.xml"
cat <<HERE > /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="stun0" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="stun:aaa.bbb.ccc.ddd"/>
</bean>
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="secret"/>
<constructor-arg index="1" value="turns:aaa.bbb.ccc.ddd:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
<bean id="stunTurnService"
class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun0"/>
</set>
</property>
<property name="turnServers">
<set>
<ref bean="turn0"/>
</set>
</property>
</bean>
</beans>
HERE

To ensure that your modifications are not lost when a new version of the packages is installed, tweak the snippet above to cat the content to /etc/bigbluebutton/turn-stun-servers.xml instead of /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml:

echo " - Update TURN server configuration turn-stun-servers.xml"
cat <<HERE > /etc/bigbluebutton/turn-stun-servers.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="stun0" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="stun:aaa.bbb.ccc.ddd"/>
</bean>
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="secret"/>
<constructor-arg index="1" value="turns:aaa.bbb.ccc.ddd:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
<bean id="stunTurnService"
class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun0"/>
</set>
</property>
<property name="turnServers">
<set>
<ref bean="turn0"/>
</set>
</property>
</bean>
</beans>
HERE

HTML5 client​

Configure when the remaining time banner appears​

By default, the HTML5 client shows the remaining time banner when a meeting has fewer than 6 minutes left. To change the threshold, set public.app.remainingTimeThresholdInMinutes in /etc/bigbluebutton/bbb-html5.yml. For example, the following restores the previous behaviour, where the banner appeared 30 minutes before the end of the meeting:

public:
app:
remainingTimeThresholdInMinutes: 30

Restart bbb-apps-akka with sudo systemctl restart bbb-apps-akka for the change to take effect. The new threshold applies to meetings created after the restart.

Change the default welcome message​

The default welcome message is built from three parameters: two system-wide parameters (see below) and the welcome parameter from the BigBlueButton create API call.

You'll find the two system-wide welcome parameters defaultWelcomeMessage and defaultWelcomeMessageFooter in /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties.

defaultWelcomeMessage=<default welcome message>
defaultWelcomeMessageFooter=<default welcome message footer>

When a front-end creates a BigBlueButton session, it may also pass a welcome parameter in the create API call.

The final welcome message shown to the user (as blue text in the Chat window) is a composite of welcome + defaultWelcomeMessage + defaultWelcomeMessageFooter.

The welcome message is fixed for the duration of a meeting. If you want to see the effect of changing the welcome parameter, you must end the current meeting or wait until the BigBlueButton server removes it from memory (which occurs about two minutes after the last person has left). You can overwrite these values in file /etc/bigbluebutton/bbb-web.properties, just remember to restart BigBlueButton with sudo bbb-conf --restart for the new values to take effect.

Modify localization for the client (override with the latest locale)​

A common use case is to modify a particular string from the locales or to include newer localizations from upstream. For example, if you would like to replace de.json with the version from a specific branch/tag of the repository, you could do the following:

cd /usr/share/bigbluebutton/html5-client/locales/
mv de.json /tmp/de.json.old
wget https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v4.0.x-release/bigbluebutton-html5/public/locales/de.json

No restart is needed: the client loads the locale files from this directory when it starts.

Start a new meeting on the server, switch to German localization in Settings, clear the cache if needed -- frequently locales are cached.

Please use caution when replacing/editing locales. If you followed the steps above you should have a backup copy of de.json (with ".old" appended) in /tmp in case you need to revert. Note that the json files across BigBlueButton versions are not always interchangeable. The workflow described above is only really meant for cases like

  • I would like to tweak a translation for my own use
  • I would like to adopt a change from upstream without having to wait for the official release in a few days
  • This is part of my customization setup and I know what I need to test. I also know how to recover if needed

Change favicon​

First method:

To change the favicon, overwrite the file /var/www/bigbluebutton-default/assets/favicon.ico.

You'll need to update file each time the bbb-config package updates.

Second method:

Create a custom directory under /var/www/bigbluebutton-default/ like /var/www/bigbluebutton-default/site and copy your favicon.ico into this directory. Add a new file favicon.nginx to /etc/bigbluebutton/nginx and add the following lines:

location = /favicon.ico {
alias /var/www/bigbluebutton-default/site/favicon.ico;

After a restart of nginx, your customized favicon.ico will be delivered. This change will affect BigBlueButton and Greenlight and will persist during updates.

Change title in the HTML5 client​

The configuration file for the HTML5 client is located in /usr/share/bigbluebutton/html5-client/private/config/settings.yml. It contains all the settings for the HTML5 client.

We recommend you make any adjustments to these configurations in the override file /etc/bigbluebutton/bbb-html5.yml so they are not lost when updating the system. To change the title, edit bbb-html5.yml and change the entry for public.app.clientTitle

public:
app:
...
clientTitle: BigBlueButton

The following command can be used too.

$ test -s /etc/bigbluebutton/bbb-html5.yml || echo '{}' > /etc/bigbluebutton/bbb-html5.yml
$ yq-go e -i ".public.app.clientTitle = \"New Title\"" /etc/bigbluebutton/bbb-html5.yml

Apply lock settings to restrict webcams​

To enable lock settings for Share webcam by default (viewers are unable to share their webcam), add the following to /etc/bigbluebutton/bbb-web.properties.

# Prevent viewers from sharing webcams
lockSettingsDisableCam=true

After restart, if you open the lock settings you'll see Share webcam lock enabled.

Change the default path for HTML5 client​

The default URL path for the client is /html5client, and it can be changed to match your preferences.

Edit the nginx configuration file /usr/share/bigbluebutton/nginx/bbb-html5.nginx.static (included by bbb-html5.nginx), replacing all instances of /html5client with the new path;

Do the same in /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties in the following lines:

defaultHTML5ClientUrl=${bigbluebutton.web.serverURL}/html5client/

You can overwrite that value in /etc/bigbluebutton/bbb-web.properties (recommended).

In configuration file for the HTML5 client, located in /usr/share/bigbluebutton/html5-client/private/config/settings.yml, change the entry for public.app.basename:

public:
app:
...
basename: '/html5client'

You can overwrite that value in /etc/bigbluebutton/bbb-html5.yml (recommended).

Finally, run the following command to reload configuration:

sudo service nginx reload && sudo bbb-conf --restart

Enable live captions​

BigBlueButton has the ability to use Chrome's built-in speech-to-text API to give users the option to have their audio live captioned for other users in the session. When live captions are enabled on the server, a user can choose their language from the drop-down list when joining audio.

These captions will automatically appear in the recordings. To enable live captions, edit /etc/bigbluebutton/bbb-html5.yml and add the following

public:
app:
# You may have other setting items here
audioCaptions:
enabled: true

Restart BigBlueButton with sudo bbb-conf --restart and you should now see the options for live captions when joining audio.

Where the speech is transcribed is up to the browser. Chrome sends the audio to Google's speech recognition servers, unless the language pack for the chosen language is already installed on the computer, in which case it transcribes on the device.

Where the speech is transcribed​

speechProcessing (added in 4.0) sets where the browser transcribes the speaker's audio:

public:
app:
audioCaptions:
enabled: true
speechProcessing: local
  • cloud (default): the browser decides, as described above. This does not guarantee that the audio goes to a speech recognition service: Chrome transcribes on the device when the language pack is already installed.
  • local: the browser always transcribes on the user's device and never falls back to a speech recognition service.
  • auto: as local, but a language the browser cannot transcribe on the device, or every language in a browser without on-device speech recognition, is transcribed as with cloud. Under the transcription language, a line tells the user that the browser may send the audio to its speech recognition service.

With local and auto:

  • A language must be downloaded to the device before it can be transcribed. When it is not there yet, a short line under the transcription language in the audio settings says that a language pack will be downloaded. The download starts when the user confirms (the join audio button), and the audio settings stay open, showing that it is downloading, until it finishes; if it fails they stay open to try again. Picking "Disabled" joins audio without transcription and without downloading. The download is about 300 MB the first time in Chrome (speech engine plus language pack), then once per language.
  • In the transcription panel, turning transcription on with a language that is not on the device starts its download.
  • If audio is joined some other way (for example with userdata-bbb_skip_check_audio) without the language pack, transcription stays off and the user is told to turn it on in the transcription settings to download it. It starts by itself once the download finishes.
  • With local, only the languages in language.available that the browser can transcribe on the device are offered, and browsers without on-device speech recognition show live captions as unsupported. Chrome has it from version 139, on desktop.

Only the transcribed text is sent to BigBlueButton, as with the default setting.

Configuration of gladia.io​

To use gladia.io for automatic speech-to-text transcriptions, you first need to obtain an API key from gladia.io. You can sign up for free credentials to test the integration. Note: The "Free Trial" plan only allows up to 1 concurrent session

Next, you must be using BigBlueButton 2.7.4+ (pass -v focal-270), BigBlueButton 3.0.0-alpha.7+ (pass -v jammy-300), or BigBlueButton 4.0+ (pass -v noble-400) on a BigBlueButton server with a public IP and hostname.

Once you have BigBlueButton installed, run sudo apt install bbb-transcription-controller to install BigBlueButton's transcription service which supports gladia.io.

Next, run sudo bbb-conf --setip <hostname> where <hostname> is the external hostname of the server (same as was passed to bbb-install.sh). This will update the bbb-transcription-controller configuration.

Next, to enable gladia.io, run the following two commands

sudo test -s /etc/bigbluebutton/bbb-html5.yml || sudo sh -c "echo '{}' > /etc/bigbluebutton/bbb-html5.yml"
sudo yq-go e -i '.public.app.audioCaptions.enabled = true' /etc/bigbluebutton/bbb-html5.yml
sudo yq-go e -i '.public.app.audioCaptions.provider = "gladia"' /etc/bigbluebutton/bbb-html5.yml

Next, set the gladia.io API key using the command below, replacing <gladia_api_key> with a glada.io API key obtained above.

sudo yq-go e -i '.gladia.startMessage = "{\"x_gladia_key\": \"<gladia-api-key>\", \"sample_rate\": 0, \"bit_depth\": 16, \"model_type\": \"fast\", \"endpointing\": 10 }"' /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml

If you are running BigBlueButton version 3.0 or higher, use release version >0.3.x of the bbb-transcription-controller repository, install the Live Transcription plugin https://github.com/bigbluebutton/bbb-plugin-live-transcription and use the following startMessage:

sudo yq-go e -i '.gladia.startMessage = "{\"sample_rate\": 16000, \"bit_depth\": 16, \"endpointing\": 0.01 }"' /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml

Restart the BigBlueButton server with bbb-conf --restart. You will now be able to select a speech-to-text option when joining audio (including auto translate). When one or more users have selected the option, a CC button will appear at the bottom and a Transcript panel will also be available.

If you are using LiveKit as audio gateway, use bbb-livekit-stt instead of bbb-transcription-controller as gladia proxy.

Advanced Filtering (WASM audio processing)​

BigBlueButton 4.0 ships with an optional WASM-based audio processor that runs on top of the microphone stream. It is exposed to users as the "Advanced Filtering" option in the Settings > Audio tab, and offers an alternative to the browser's built-in audio processing ("Standard Filtering"), isolating the speaker's voice and eliminating background noise. Users who want no processing at all — for example when sharing music, where noise suppression and automatic gain control would be undesirable — can select "Original Audio" in the same tab.

It is disabled by default. To make it available to users, set enabled: true under public.media.audio.audioWasmProcessing in /etc/bigbluebutton/bbb-html5.yml:

public:
media:
audio:
# audioWasmProcessing: audio input processing through WASM
# enabled: whether advanced/WASM processing should be exposed to users.
# If false, the browser's built-in audio processing is used instead.
# provider: which WASM backend runs the processing - 'bbba' or
# 'workadventureDtln'. Defaults to 'bbba' if unset/unrecognized.
# constraints: browser-level audio constraints applied ON TOP of WASM processing.
# Providers can force their own value for a given constraint,
# overriding whatever is configured here.
audioWasmProcessing:
enabled: true
provider: bbba
constraints:
echoCancellation: true
autoGainControl: true
noiseSuppression: true

The audio-processing mode pre-selected for new users is controlled by public.app.defaultSettings.audio.processingMode (advanced selects the WASM processor; the client falls back to standard when WASM processing is disabled or the browser does not support it). Restart BigBlueButton with sudo bbb-conf --restart after changing the configuration.

Configure guest policy​

The policy for guest management on the server is is set in the properties file for bbb-web, which is located at /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties. You can overwrite the default guest policy in /etc/bigbluebutton/bbb-web.properties. Just add the value you prefer, save the file and restart BigBlueButton.

# Default Guest Policy
# Valid values are ALWAYS_ACCEPT, ALWAYS_DENY, ASK_MODERATOR
#
defaultGuestPolicy=ALWAYS_ACCEPT

Configure guest lobby queue position​

When the guest policy makes users wait for moderator approval, the HTML5 client shows each guest their position in the waiting queue by default. To hide this position, set public.app.showGuestLobbyWaitingQueuePosition to false in /etc/bigbluebutton/bbb-html5.yml.

public:
app:
showGuestLobbyWaitingQueuePosition: false

Restart BigBlueButton with sudo bbb-conf --restart for the change to take effect.

Show a custom logo on the client​

Ensure that the parameter displayBrandingArea is set to true in bbb-html5's configuration, restart BigBlueButton server with sudo bbb-conf --restart and pass logo=<image-url> in Custom parameters when creating the meeting.

To update the default logo, navigate to the images folder located at /var/www/bigbluebutton-default/assets/images/, and replace the logo.png file with your new logo.

Other meeting configs available​

These configs can be set in /etc/bigbluebutton/bbb-web.properties. The table is synced with bigbluebutton.properties; items marked overwritable can be replaced per meeting through the matching /create parameter.

ParameterDescriptionOptionsDefault value
defaultMeetingLayoutDefault meeting layoutUNIFIED_LAYOUT, CAMERAS_ONLY, PRESENTATION_ONLY, PARTICIPANTS_AND_CHAT_ONLY, MEDIA_ONLYUNIFIED_LAYOUT overwritable (via meetingLayout)
defaultMaxUsersMaximum number of users a meeting can haveInteger (0=disable)0 overwritable (via maxParticipants)
maxUserConcurrentAccessesMaximum number of sessions a single user (extId) can open simultaneously in the same meeting; oldest session is ended when exceeded.Integer (0=disable)3
defaultMeetingDurationDefault duration of the meeting in minutesInteger (0=disable)0 overwritable (via duration)
defaultGuestPolicyDefault guest policy applied to meetingsALWAYS_ACCEPT, ALWAYS_DENY, ASK_MODERATORALWAYS_ACCEPT overwritable (via guestPolicy)
authenticatedGuestEnable authenticated guest modetrue/falsetrue
defaultAllowPromoteGuestToModeratorAllows moderators to promote guests to moderators when authenticatedGuest is enabledtrue/falsefalse overwritable (via allowPromoteGuestToModerator)
meetingExpireIfNoUserJoinedInMinutesEnd meeting if no user joined within a period of time after meeting createdInteger5 overwritable
meetingExpireWhenLastUserLeftInMinutesNumber of minutes to end meeting when the last user leftInteger (0=end as soon as the last user left)1 overwritable
endWhenNoModeratorEnd meeting when there are no moderators after a certain period of timetrue/falsefalse overwritable
endWhenNoModeratorDelayInMinutesNumber of minutes to wait for moderator rejoin before end meetingInteger1 overwritable
userInactivityInspectTimerInMinutesUser inactivity audit timer intervalInteger (0=disable)0
userInactivityThresholdInMinutesNumber of minutes to consider a user inactiveInteger30
userActivitySignResponseDelayInMinutesNumber of minutes for user to respond to inactivity warning before being logged outInteger5
usersTimeoutTimeout (millis) to remove a joined user after they left without a rejoinInteger60000 (60s)
waitingGuestUsersTimeoutTimeout (millis) to remove guest users that stopped fetching for their statusInteger30000 (30s)
defaultHttpSessionTimeoutTimeout (seconds) to invalidate inactive HTTP sessionsInteger14400 (4h)
sessionsCleanupDelayInMinutesMinutes to wait before removing user sessions after a meeting has ended; during this delay the "Meeting has ended" screen is still reachableInteger (0=keep indefinitely)60
webcamsOnlyForModeratorAllow webcams streaming reception only to and from moderatorstrue/falsefalse overwritable
meetingCameraCapPer meeting camera share limitInteger (0=disable)0 overwritable
userCameraCapPer user camera share limitInteger (0=disable)3 overwritable
maxPinnedCamerasMaximum number of cameras pinned simultaneouslyInteger (0=disable)3
muteOnStartMicrophone is muted by default when users start sharingtrue/falsetrue overwritable
allowModsToUnmuteUsersGives moderators permission to unmute other userstrue/falsefalse overwritable
requireUserConsentBeforeUnmutingAllows participants to accept or decline when a moderator asks them to unmute.true/falsefalse overwritable
allowModsToEjectCamerasGives moderators permission to close other users' webcamstrue/falsefalse overwritable
cameraBridgeMedia bridge used for camera streamslivekit, bbb-webrtc-sfulivekit
screenShareBridgeMedia bridge used for screen share streamslivekit, bbb-webrtc-sfulivekit
audioBridgeMedia bridge used for audio streamslivekit, bbb-webrtc-sfulivekit
disableRecordingDefaultWhen true, do not record even if the /create call sets record=truetrue/falsefalse
autoStartRecordingStart recording when the first user joins the meetingtrue/falsefalse overwritable
allowStartStopRecordingAllow users to start/stop recording during the sessiontrue/falsetrue overwritable
defaultKeepEventsSave meeting events even if the meeting is not recordedtrue/falsefalse overwritable (via meetingKeepEvents)
allowFetchAllRecordingsWhen true, getRecordings with no meetingID returns every recording on the server (potentially large response)true/falsetrue
recordFullDurationMediaWhether media (audio, cameras, screen sharing) is captured on its full duration when record=true, ignoring the meeting's current paused/running recording statetrue/falsefalse overwritable
notifyRecordingIsOnNotify users that recording is ontrue/falsefalse overwritable
lockSettingsDisableCamDefault lock setting: disable webcamstrue/falsefalse overwritable
lockSettingsDisableMicDefault lock setting: disable microphonestrue/falsefalse overwritable
lockSettingsDisablePrivateChatDefault lock setting: disable private chattrue/falsefalse overwritable
lockSettingsDisablePublicChatDefault lock setting: disable public chattrue/falsefalse overwritable
lockSettingsDisableNotesDefault lock setting: disable shared notestrue/falsefalse overwritable
lockSettingsHideUserListDefault lock setting: hide the user list from non-moderatorstrue/falsefalse overwritable
lockSettingsLockOnJoinDefault lock setting: apply lock settings to all users on jointrue/falsetrue overwritable
lockSettingsLockOnJoinConfigurableAllow the lock-on-join flag to be configured per meetingtrue/falsefalse overwritable
lockSettingsHideViewersCursorDefault lock setting: hide viewers' cursors from each othertrue/falsefalse overwritable
lockSettingsHideViewersAnnotationDefault lock setting: hide viewers' annotations from each othertrue/falsefalse overwritable
lockSettingsPresenterPolicyDefault lock setting: controls who can take over as presenterrequireApproval, moderatorOnly, freeForAllrequireApproval overwritable
breakoutRoomsRecordEnable recordings in breakout roomstrue/falsefalse overwritable
breakoutRoomsPrivateChatEnabledEnable private chat in breakout roomstrue/falsetrue overwritable
breakoutRoomsMultiUserWhiteboardDefaultOnEnable multi-user whiteboard by default in breakout roomstrue/falsetrue
learningDashboardCleanupDelayInMinutesMinutes the Learning Dashboard remains available after the meeting ends. For a breakout room's dashboard, the countdown starts when the parent meeting endsInteger (0=keep permanently)2 overwritable
disabledFeaturesComma-separated list of features to disable (see /create docs for the full list of feature names)csv(empty) overwritable
maxSharedNotesInitialContentUrlPayloadSizeMaximum size (in KiB) of the response fetched when seeding shared-notes initial content from sharedNotesInitialContentJsonUrl / sharedNotesInitialContentMarkdownUrlInteger (KiB)1024
allowOverrideClientSettingsOnCreateCallAllow the clientSettingsOverride POST module on /create. Does not apply to the clientSettingsOverrideJsonUrl parameter, which is always accepted (see /create docs)true/falsefalse
clientSettingsOverrideStrictValidationWhen true, reject the /create call (bbb-web) and refuse bbb-apps-akka boot if a client settings override has unknown or malformed keys. Intended for test/staging (see Validating client settings overrides)true/falsefalse
clientSettingsFilePathPath to the settings.yml catalog used as the schema for the strict client-settings override validation abovepath/usr/share/bigbluebutton/html5-client/private/config/settings.yml
pluginManifestsList of plugin manifests as a JSON array, e.g. [{"url": "https://example.com/manifest.json"}]JSON array(empty) overwritable
pluginManifestCacheEnabledCache plugin manifests on disk to speed up /create callstrue/falsefalse
pluginManifestCacheDirectoryBase directory for cached plugin manifest files. The directory is wiped every time bbb-web starts; entries idle for over a week are also evicted automatically by the periodic refresh taskpath/var/bigbluebutton/plugin-manifests-cache/
pluginManifestCacheRefreshIntervalMinutesHow often (in minutes) the plugin manifest cache refresh task runsInteger60
allowRequestsWithoutSessionAllow requests without JSESSIONID to be handled (reduces security; only enable for trusted integrations like iframes)true/falsefalse overwritable
supportedChecksumAlgorithmsHash algorithms accepted when validating API checksums (comma-separated)sha1, sha256, sha384, sha512sha1,sha256,sha384,sha512
pageTokenSecretSecret used to generate per-page presentation access tokens (HMAC-SHA256). Override for additional security separation between presentation tokens and the rest of bbb-webString(defaults to ${securitySalt})
beans.presentationService.pageTokenSecretGrails bean wiring that injects pageTokenSecret into the presentation service. Override only if the presentation service should use a different secret than pageTokenSecretString(defaults to ${pageTokenSecret})
allowRevealOfBBBVersionAllow the getMeetings endpoint to reveal the current BigBlueButton versiontrue/falsefalse
  • overwritable: The default is replaced when the matching parameter is present on an API /create request. Where the create-side name differs from the property name, it is shown in parentheses (e.g., defaultMeetingLayout → meetingLayout).

/create parameters without a bigbluebutton.properties counterpart​

Some /create parameters set per-meeting state but have no default in bigbluebutton.properties. Examples include name, meetingID, parentMeetingID/sequence/freeJoin/isBreakout (breakout-only), bannerText/bannerColor, moderatorOnlyMessage, notifyRecordingAppend, meta_* metadata, logo, multiUserWhiteboardEnabled, presentation-upload parameters (preUploadedPresentation*, presentationUploadExternalUrl, presentationUploadExternalDescription), sharedNotesInitialContentJsonUrl, disabledFeaturesExclude, clientSettingsOverride / clientSettingsOverrideJsonUrl, and pluginManifestsFetchUrl. See Create API parameters for the complete list and descriptions.

Passing user metadata to the client on join​

The join API call accepts userdata-bbb_* parameters that change the look and default behaviour of the HTML5 client for the user who joins: automatic audio join, skipping the echo test or the webcam preview, locale, initial layout, hidden navigation and action bars, whiteboard tools, recording permission, custom CSS and more. They are documented with the API call, in User metadata parameters, together with the settings.yml default each one overrides.

Changing the background color of the HTML client​

You can change the background color of the HTML5 client with the following stylesheet, passed through the userdata-bbb_custom_style_url or userdata-bbb_custom_style parameter:

:root {
--loader-bg: #000;
}

body {
background-color: #000 !important;
}

You can add this code to a hosted .css file and pass userdata-bbb_custom_style_url=https://someservice.com/customStyles.css

Alternatively (for simple changes) you can achieve the same without hosted file.

You can try this in API-MATE - you need the non-encoded version of the CSS

userdata-bbb_custom_style=:root{--loader-bg:#000;}body{background-color:#000!important;}

If you are adding this to a join-url you need to URL encode the string:

%3Aroot%7B--loader-bg%3A%23000%3B%7Dbody%7Bbackground-color%3A%23000!important%3B%7D
Static CSS classes for client elements​

The class names the client generates for its components change from build to build, so a stylesheet that relies on them breaks with the next update. Key components also carry fixed class names with a bbb- prefix, which custom styles and theme plugins can select instead. They follow a BEM-like scheme:

  • bbb-<block> names a component, for example bbb-navigation, bbb-avatar or bbb-actions-bar;
  • bbb-<block>__<element> names a part of it, for example bbb-navigation__item or bbb-chat-message__time;
  • bbb-<block>--<state> marks a state, for example bbb-avatar--presenter, bbb-navigation__item--active or bbb-mute-toggle--muted.

The classes cover the avatars, the navigation sidebar and its items, the sidebar panels and their headers, the chat and its messages, the user list, buttons, the actions bar, the microphone and camera buttons, the nav bar and its items, the talking indicator, the presentation and its toolbar, webcams, the timer indicator and the notifications bar. For example, to highlight the open item of the navigation sidebar and to turn the microphone button red while the user is muted:

.bbb-navigation__item--active {
background-color: #fff3cd !important;
}

.bbb-mute-toggle--muted .bbb-button__icon {
background-color: #d93025 !important;
}

Pass the stylesheet with userdata-bbb_custom_style_url or userdata-bbb_custom_style as above, or set public.app.customStyleUrl in /etc/bigbluebutton/bbb-html5.yml to load it for every user (a userdata-bbb_custom_style_url on the join URL replaces it for that user).

Send client logs to the server​

Step-by-step instructions for how to configure logs from clients to be logged in a server log file are located in Administration -> Configuration Files

Other configuration changes​

Extract the shared secret​

Any front-end to BigBlueButton needs two pieces of information: the hostname for the BigBlueButton server and its shared secret (for authenticating API calls). To print out the hostname and shared secret for you BigBlueButton server, enter the command bbb-conf --secret:

$ bbb-conf --secret

URL: https://bigbluebutton.example.com/bigbluebutton/
Secret: 577fd5f05280c10fb475553d200f3322

Link to the API-Mate:
https://bigbluebutton.github.io/api-mate/#server=https://10.0.3.132/bigbluebutton/&sharedSecret=577fd5f05280c10fb475553d200f3322

The last line gives a link API-Mate, an excellent tool provided by Mconf Technologies (a company that has made many contributions to the BigBlueButton project over the years) that makes it easy to create API calls.

Change the shared secret​

To validate incoming API calls, all external applications making API calls must checksum their API call using the same secret as configured in the BigBlueButton server.

You’ll find the shared secret in /etc/bigbluebutton/bbb-web.properties

securitySalt=<value_of_salt>

To change the shared secret, do the following:

  1. Generate a new Universal Unique ID (UUID) from a UUID generator such as at http://www.somacon.com/p113.php. This will give a long string of random numbers that will be impossible to reverse engineer.
  2. Run the command sudo bbb-conf --setsecret new_secret.

Note: If you have created you own front-end or are using a third-party plug-in to connect to BigBlueButton, its shared secret; otherwise, if the shared secrets do not match, the checksum for the incoming API calls will not match and the BigBlueButton server will reject the API call with an error.

Install callback for events (webhooks)​

Want to receive callbacks to your application when an event occurs in BigBlueButton? BigBlueButton provides an optional web hooks package that installs a node.js application listens for all events on BigBlueButton and sends POST requests with details about these events to hooks registered via an API. A hook can be any external URL that can receive HTTP POST requests.

To install bbb-webhooks

$ sudo apt-get install bbb-webhooks

For information on configuring bbb-webhooks, see bbb-webhooks.

Scalability​

Number of Hasura instances​

BigBlueButton comes in with one instance of Hasura (bbb-graphql-server), whose responsibility is to handle GraphQL queries and subscriptions from clients and once there is a subscription to continually update whenever new data is available. This works fine for server load of under couple of hundred users (depending on their activities). Afterwards queries tend to take longer to be completed. Enabling more than one instance of Hasura addresses this problem.

How to enable additional Hasura instances?​

Edit /etc/nginx/sites-available/hasura-loadbalancer.conf and add to the list inside of the hasura block. Adding one more instance listening at port 8086 looks like this:

upstream hasura {
least_conn;
server 127.0.0.1:8085;
server 127.0.0.1:8086;
}

After saving the file use systemctl to enable this new instance via:

systemctl enable --now bbb-graphql-server@8086

Finally, restart BigBlueButton

bbb-conf --restart

You may want to double check that both instances are running fine via systemctl status bbb-graphql-server* which should list the services on both ports as "running".

How many Hasura instances should I run?​

We recommend keeping the default (single instance) unless you expect that your BigBlueButton server will be handling hundreds of simultaneous users. A second instance would prove beneficial for those aiming to support a larger number (several hundreds users), especially on hardware which is multiple times more performant than what we outline in the minimum server requirements. We have not yet noticed visible difference with more than two instances of Hasura, because at this level of usage, there are other aspects of BigBlueButton which will also begin showing signs of slowing down.