diff --git a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml index 0c2140f30b..d080734bd9 100644 --- a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml +++ b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml @@ -13,6 +13,7 @@ services: - ${CONFIG}/web/letsencrypt:/etc/letsencrypt - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts - ${DEFAULTS}/web/nginx/meet.conf:/defaults/meet.conf + - ${DEFAULTS}/web/settings-config.js:/defaults/settings-config.js environment: - ENABLE_AUTH - ENABLE_GUESTS diff --git a/playbooks/roles/jitsi-meet/files/settings-config.js b/playbooks/roles/jitsi-meet/files/settings-config.js new file mode 100644 index 0000000000..a005330fce --- /dev/null +++ b/playbooks/roles/jitsi-meet/files/settings-config.js @@ -0,0 +1,309 @@ +{{ $DEPLOYMENTINFO_USERREGION := .Env.DEPLOYMENTINFO_USERREGION | default "" -}} +{{ $BRIDGE_CHANNEL := .Env.BRIDGE_CHANNEL | default "websocket" -}} +{{ $ENABLE_AUDIO_PROCESSING := .Env.ENABLE_AUDIO_PROCESSING | default "true" | toBool -}} +{{ $ENABLE_CALENDAR := .Env.ENABLE_CALENDAR | default "false" | toBool -}} +{{ $ENABLE_FILE_RECORDING_SERVICE := .Env.ENABLE_FILE_RECORDING_SERVICE | default "false" | toBool -}} +{{ $ENABLE_FILE_RECORDING_SERVICE_SHARING := .Env.ENABLE_FILE_RECORDING_SERVICE_SHARING | default "false" | toBool -}} +{{ $ENABLE_IPV6 := .Env.ENABLE_IPV6 | default "true" | toBool -}} +{{ $ENABLE_LIPSYNC := .Env.ENABLE_LIPSYNC | default "false" | toBool -}} +{{ $ENABLE_NO_AUDIO_DETECTION := .Env.ENABLE_NO_AUDIO_DETECTION | default "false" | toBool -}} +{{ $ENABLE_P2P := .Env.ENABLE_P2P | default "true" | toBool -}} +{{ $ENABLE_PREJOIN_PAGE := .Env.ENABLE_PREJOIN_PAGE | default "false" | toBool -}} +{{ $ENABLE_WELCOME_PAGE := .Env.ENABLE_WELCOME_PAGE | default "true" | toBool -}} +{{ $ENABLE_CLOSE_PAGE := .Env.ENABLE_CLOSE_PAGE | default "false" | toBool -}} +{{ $ENABLE_RECORDING := .Env.ENABLE_RECORDING | default "false" | toBool -}} +{{ $ENABLE_REMB := .Env.ENABLE_REMB | default "true" | toBool -}} +{{ $ENABLE_REQUIRE_DISPLAY_NAME := .Env.ENABLE_REQUIRE_DISPLAY_NAME | default "false" | toBool -}} +{{ $ENABLE_SIMULCAST := .Env.ENABLE_SIMULCAST | default "true" | toBool -}} +{{ $ENABLE_STATS_ID := .Env.ENABLE_STATS_ID | default "false" | toBool -}} +{{ $ENABLE_STEREO := .Env.ENABLE_STEREO | default "false" | toBool -}} +{{ $ENABLE_TALK_WHILE_MUTED := .Env.ENABLE_TALK_WHILE_MUTED | default "false" | toBool -}} +{{ $ENABLE_TCC := .Env.ENABLE_TCC | default "true" | toBool -}} +{{ $ENABLE_TRANSCRIPTIONS := .Env.ENABLE_TRANSCRIPTIONS | default "false" | toBool -}} +{{ $RESOLUTION := .Env.RESOLUTION | default "720" -}} +{{ $RESOLUTION_MIN := .Env.RESOLUTION_MIN | default "180" -}} +{{ $RESOLUTION_WIDTH := .Env.RESOLUTION_WIDTH | default "1280" -}} +{{ $RESOLUTION_WIDTH_MIN := .Env.RESOLUTION_WIDTH_MIN | default "320" -}} +{{ $START_AUDIO_ONLY := .Env.START_AUDIO_ONLY | default "false" | toBool -}} +{{ $START_AUDIO_MUTED := .Env.START_AUDIO_MUTED | default 10 -}} +{{ $DISABLE_AUDIO_LEVELS := .Env.DISABLE_AUDIO_LEVELS | default "false" | toBool -}} +{{ $ENABLE_NOISY_MIC_DETECTION := .Env.ENABLE_NOISY_MIC_DETECTION | default "true" | toBool -}} +{{ $START_VIDEO_MUTED := .Env.START_VIDEO_MUTED | default 10 -}} +{{ $DESKTOP_SHARING_FRAMERATE_MIN := .Env.DESKTOP_SHARING_FRAMERATE_MIN | default 5 -}} +{{ $DESKTOP_SHARING_FRAMERATE_MAX := .Env.DESKTOP_SHARING_FRAMERATE_MAX | default 5 -}} +{{ $TESTING_OCTO_PROBABILITY := .Env.TESTING_OCTO_PROBABILITY | default "0" -}} +{{ $TESTING_CAP_SCREENSHARE_BITRATE := .Env.TESTING_CAP_SCREENSHARE_BITRATE | default "1" -}} +{{ $XMPP_DOMAIN := .Env.XMPP_DOMAIN -}} +{{ $XMPP_RECORDER_DOMAIN := .Env.XMPP_RECORDER_DOMAIN -}} + + +// Video configuration. +// + +if (!config.hasOwnProperty('constraints')) config.constraints = {}; +if (!config.constraints.hasOwnProperty('video')) config.constraints.video = {}; + +config.resolution = {{ $RESOLUTION }}; +config.constraints.video.height = { ideal: {{ $RESOLUTION }}, max: {{ $RESOLUTION }}, min: {{ $RESOLUTION_MIN }} }; +config.constraints.video.width = { ideal: {{ $RESOLUTION_WIDTH }}, max: {{ $RESOLUTION_WIDTH }}, min: {{ $RESOLUTION_WIDTH_MIN }}}; +config.disableSimulcast = {{ not $ENABLE_SIMULCAST }}; +config.startVideoMuted = {{ $START_VIDEO_MUTED }}; + +{{ if .Env.START_BITRATE -}} +config.startBitrate = '{{ .Env.START_BITRATE }}'; +{{ end -}} + +// ScreenShare Configuration. +// +config.desktopSharingFrameRate = { min: {{ $DESKTOP_SHARING_FRAMERATE_MIN }}, max: {{ $DESKTOP_SHARING_FRAMERATE_MAX }} }; + +// Audio configuration. +// + +config.enableNoAudioDetection = {{ $ENABLE_NO_AUDIO_DETECTION }}; +config.enableTalkWhileMuted = {{ $ENABLE_TALK_WHILE_MUTED }}; +config.disableAP = {{ not $ENABLE_AUDIO_PROCESSING }}; +config.stereo = {{ $ENABLE_STEREO }}; +config.startAudioOnly = {{ $START_AUDIO_ONLY }}; +config.startAudioMuted = {{ $START_AUDIO_MUTED }}; +config.disableAudioLevels = {{ $DISABLE_AUDIO_LEVELS }}; +config.enableNoisyMicDetection = {{ $ENABLE_NOISY_MIC_DETECTION }}; + + +// Peer-to-Peer options. +// + +if (!config.hasOwnProperty('p2p')) config.p2p = {}; + +config.p2p.enabled = {{ $ENABLE_P2P }}; + + +// Etherpad +// + +{{ if .Env.ETHERPAD_PUBLIC_URL -}} +config.etherpad_base = '{{ .Env.ETHERPAD_PUBLIC_URL }}'; +{{ else if .Env.ETHERPAD_URL_BASE -}} +config.etherpad_base = '{{.Env.PUBLIC_URL}}/etherpad/p/'; +{{ end -}} + +config.useRoomAsSharedDocumentName: true; +config.openSharedDocumentOnJoin: true; + + +// Recording. +// + +{{ if $ENABLE_RECORDING -}} + +config.hiddenDomain = '{{ $XMPP_RECORDER_DOMAIN }}'; + +// Whether to enable file recording or not +config.fileRecordingsEnabled = true; + +// Whether to enable live streaming or not. +config.liveStreamingEnabled = true; + +{{ if .Env.DROPBOX_APPKEY -}} +// Enable the dropbox integration. +if (!config.hasOwnProperty('dropbox')) config.dropbox = {}; +config.dropbox.appKey = '{{ .Env.DROPBOX_APPKEY }}'; +{{ if .Env.DROPBOX_REDIRECT_URI -}} +// A URL to redirect the user to, after authenticating +// by default uses: +// 'https://jitsi-meet.example.com/static/oauth.html' +config.dropbox.redirectURI = '{{ .Env.DROPBOX_REDIRECT_URI }}'; +{{ end -}} +{{ end -}} + +{{ if $ENABLE_FILE_RECORDING_SERVICE -}} +// When integrations like dropbox are enabled only that will be shown, +// by enabling fileRecordingsServiceEnabled, we show both the integrations +// and the generic recording service (its configuration and storage type +// depends on jibri configuration) +config.fileRecordingsServiceEnabled = true; +{{ end -}} +{{ if $ENABLE_FILE_RECORDING_SERVICE_SHARING -}} +// Whether to show the possibility to share file recording with other people +// (e.g. meeting participants), based on the actual implementation +// on the backend. +config.fileRecordingsServiceSharingEnabled = true; +{{ end -}} +{{ end -}} + + +// Analytics. +// + +if (!config.hasOwnProperty('analytics')) config.analytics = {}; + +{{ if .Env.AMPLITUDE_ID -}} +// The Amplitude APP Key: +config.analytics.amplitudeAPPKey = '{{ .Env.AMPLITUDE_ID }}'; +{{ end -}} + +{{ if .Env.GOOGLE_ANALYTICS_ID -}} +// The Google Analytics Tracking ID: +config.analytics.googleAnalyticsTrackingId = '{{ .Env.GOOGLE_ANALYTICS_ID }}'; +{{ end -}} + +{{ if .Env.MATOMO_ENDPOINT -}} +// Matomo endpoint: +config.analytics.matomoEndpoint = '{{ .Env.MATOMO_ENDPOINT }}'; +{{ end -}} + +{{ if .Env.MATOMO_SITE_ID -}} +// Matomo site ID: +config.analytics.matomoSiteID = '{{ .Env.MATOMO_SITE_ID }}'; +{{ end -}} + +{{ if .Env.ANALYTICS_SCRIPT_URLS -}} +// Array of script URLs to load as lib-jitsi-meet "analytics handlers". +config.analytics.scriptURLs = [ '{{ join "','" (splitList "," .Env.ANALYTICS_SCRIPT_URLS) }}' ]; +{{ end -}} + +{{ if .Env.ANALYTICS_WHITELISTED_EVENTS -}} +config.analytics.whiteListedEvents = [ '{{ join "','" (splitList "," .Env.ANALYTICS_WHITELISTED_EVENTS) }}' ]; +{{ end -}} + +{{ if .Env.CALLSTATS_CUSTOM_SCRIPT_URL -}} +config.callStatsCustomScriptUrl = '{{ .Env.CALLSTATS_CUSTOM_SCRIPT_URL }}'; +{{ end -}} + +{{ if .Env.CALLSTATS_ID -}} +// To enable sending statistics to callstats.io you must provide the +// Application ID and Secret. +config.callStatsID = '{{ .Env.CALLSTATS_ID }}'; +{{ end -}} + +{{ if .Env.CALLSTATS_ID -}} +config.callStatsSecret = '{{ .Env.CALLSTATS_SECRET }}'; +{{ end -}} + +// Enables callstatsUsername to be reported as statsId and used +// by callstats as repoted remote id. +config.enableStatsID = {{ $ENABLE_STATS_ID }}; + + +// Dial in/out services. +// + +{{ if .Env.CONFCODE_URL -}} +config.dialInConfCodeUrl = '{{ .Env.CONFCODE_URL }}'; +{{ end -}} + +{{ if .Env.DIALIN_NUMBERS_URL -}} +config.dialInNumbersUrl = '{{ .Env.DIALIN_NUMBERS_URL }}'; +{{ end -}} + +{{ if .Env.DIALOUT_AUTH_URL -}} +config.dialOutAuthUrl = '{{ .Env.DIALOUT_AUTH_URL }}'; +{{ end -}} + +{{ if .Env.DIALOUT_CODES_URL -}} +config.dialOutCodesUrl = '{{ .Env.DIALOUT_CODES_URL }}'; +{{ end -}} + + +// Calendar service integration. +// + +config.enableCalendarIntegration = {{ $ENABLE_CALENDAR }}; + +{{ if .Env.GOOGLE_API_APP_CLIENT_ID -}} +config.googleApiApplicationClientID = '{{ .Env.GOOGLE_API_APP_CLIENT_ID }}'; +{{ end -}} + +{{ if .Env.MICROSOFT_API_APP_CLIENT_ID -}} +config.microsoftApiApplicationClientID = '{{ .Env.MICROSOFT_API_APP_CLIENT_ID }}'; +{{ end -}} + + +// Invitation service. +// + +{{ if .Env.INVITE_SERVICE_URL -}} +config.inviteServiceUrl = '{{ .Env.INVITE_SERVICE_URL }}'; +{{ end -}} + +{{ if .Env.PEOPLE_SEARCH_URL -}} +config.peopleSearchUrl = '{{ .Env.PEOPLE_SEARCH_URL }}'; +config.peopleSearchQueryTypes = ['user','conferenceRooms']; +{{ end -}} + + +// Miscellaneous. +// + +// Prejoin page. +config.prejoinPageEnabled = {{ $ENABLE_PREJOIN_PAGE }}; + +// Welcome page. +config.enableWelcomePage = {{ $ENABLE_WELCOME_PAGE }}; + +// Close page. +config.enableClosePage = {{ $ENABLE_CLOSE_PAGE }}; + +// Require users to always specify a display name. +config.requireDisplayName = {{ $ENABLE_REQUIRE_DISPLAY_NAME }}; + +// Chrome extension banner. +{{ if .Env.CHROME_EXTENSION_BANNER_JSON -}} +config.chromeExtensionBanner = {{ .Env.CHROME_EXTENSION_BANNER_JSON }}; +{{ end -}} + + +// Advanced. +// + +// Lipsync hack in jicofo, may not be safe. +config.enableLipSync = {{ $ENABLE_LIPSYNC }}; + +config.enableRemb = {{ $ENABLE_REMB }}; +config.enableTcc = {{ $ENABLE_TCC }}; + +config.openBridgeChannel = '{{ $BRIDGE_CHANNEL }}'; + +// Enable IPv6 support. +config.useIPv6 = {{ $ENABLE_IPV6 }}; + +// Transcriptions (subtitles and buttons can be configured in interface_config) +config.transcribingEnabled = {{ $ENABLE_TRANSCRIPTIONS }}; + +{{ if .Env.DYNAMIC_BRANDING_URL -}} +// External API url used to receive branding specific information. +config.dynamicBrandingUrl = '{{ .Env.DYNAMIC_BRANDING_URL }}'; +{{ end -}} + +{{ if .Env.TOKEN_AUTH_URL -}} +// Authenticate using external service or just focus external auth window if there is one already. +config.tokenAuthUrl = '{{ .Env.TOKEN_AUTH_URL }}'; +{{ end -}} + + +// Deployment information. +// + +if (!config.hasOwnProperty('deploymentInfo')) config.deploymentInfo = {}; + +{{ if .Env.DEPLOYMENTINFO_ENVIRONMENT -}} +config.deploymentInfo.environment = '{{ .Env.DEPLOYMENTINFO_ENVIRONMENT }}'; +{{ end -}} + +{{ if .Env.DEPLOYMENTINFO_ENVIRONMENT_TYPE -}} +config.deploymentInfo.envType = '{{ .Env.DEPLOYMENTINFO_ENVIRONMENT_TYPE }}'; +{{ end -}} + +{{ if $DEPLOYMENTINFO_USERREGION -}} +config.deploymentInfo.userRegion = '{{ $DEPLOYMENTINFO_USERREGION }}'; +{{ end -}} + + +// Testing +// + +if (!config.hasOwnProperty('testing')) config.testing = {}; +if (!config.testing.hasOwnProperty('octo')) config.testing.octo = {}; + +config.testing.capScreenshareBitrate = {{ $TESTING_CAP_SCREENSHARE_BITRATE }}; +config.testing.octo.probability = {{ $TESTING_OCTO_PROBABILITY }}; diff --git a/playbooks/roles/jitsi-meet/tasks/main.yaml b/playbooks/roles/jitsi-meet/tasks/main.yaml index 4cfa599570..d8d4d48e11 100644 --- a/playbooks/roles/jitsi-meet/tasks/main.yaml +++ b/playbooks/roles/jitsi-meet/tasks/main.yaml @@ -31,14 +31,6 @@ # TODO files managed here seem to be completely ignored by the containers # we should clean them up. And if necessary replace them with templates # below like meet.conf. -- name: Write web config - copy: - src: config.js - dest: /var/jitsi-meet/web/config.js -- name: Write interface config - copy: - src: interface_config.js - dest: /var/jitsi-meet/web/interface_config.js - name: Write nginx site config copy: src: default.conf @@ -52,6 +44,17 @@ copy: src: meet.conf dest: /var/jitsi-meet/defaults/web/nginx/meet.conf +- name: Write settings-config.js config template + copy: + src: settings-config.js + dest: /var/jitsi-meet/defaults/web/settings-config.js + +# This file appears to be consumed as is by the jitsi meet web process. +# No funny templating or replacement. +- name: Write interface config + copy: + src: interface_config.js + dest: /var/jitsi-meet/web/interface_config.js - name: Run docker-compose pull shell: