From fbb8a2dbfec1304f78231fa8d9bc8a4275eda497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 13 Jun 2022 22:45:02 +0200 Subject: [PATCH] jibri: switch to PulseAudio Using PulseAudio means no longer needing to mount /dev/snd/ which should make deploying Jibri much easier. Credits: https://github.com/openfun/jibri-pulseaudio https://community.jitsi.org/t/tip-pulseaudio-support-for-jibri/65780 https://github.com/kpeiruza/jitsi-images --- jibri.yml | 7 -- jibri/Dockerfile | 5 +- jibri/rootfs/defaults/jibri.conf | 8 +-- jibri/rootfs/defaults/logging.properties | 10 ++- jibri/rootfs/etc/cont-init.d/10-config | 18 +---- jibri/rootfs/etc/fix-attrs.d/10-jibri | 2 + jibri/rootfs/etc/pulse/default.pa | 69 +++++++++++++++++++ jibri/rootfs/etc/services.d/30-pulse/run | 4 ++ .../services.d/{30-jibri => 40-jibri}/finish | 0 .../etc/services.d/{30-jibri => 40-jibri}/run | 0 .../home/jibri/.config/pulse/client.conf | 1 + .../home/jibri/.config/pulse/daemon.conf | 9 +++ .../home/jibri/.config/pulse/default.pa | 8 +++ 13 files changed, 103 insertions(+), 38 deletions(-) create mode 100644 jibri/rootfs/etc/fix-attrs.d/10-jibri create mode 100644 jibri/rootfs/etc/pulse/default.pa create mode 100644 jibri/rootfs/etc/services.d/30-pulse/run rename jibri/rootfs/etc/services.d/{30-jibri => 40-jibri}/finish (100%) rename jibri/rootfs/etc/services.d/{30-jibri => 40-jibri}/run (100%) create mode 100644 jibri/rootfs/home/jibri/.config/pulse/client.conf create mode 100644 jibri/rootfs/home/jibri/.config/pulse/daemon.conf create mode 100644 jibri/rootfs/home/jibri/.config/pulse/default.pa diff --git a/jibri.yml b/jibri.yml index e417979..7379e3e 100644 --- a/jibri.yml +++ b/jibri.yml @@ -9,15 +9,10 @@ services: - /dev/shm:/dev/shm cap_add: - SYS_ADMIN - - NET_BIND_SERVICE - devices: - - /dev/snd:/dev/snd environment: - CHROMIUM_FLAGS - DISPLAY=:0 - ENABLE_STATS_D - - JIBRI_FFMPEG_AUDIO_SOURCE - - JIBRI_FFMPEG_AUDIO_DEVICE - JIBRI_HTTP_API_EXTERNAL_PORT - JIBRI_HTTP_API_INTERNAL_PORT - JIBRI_RECORDING_RESOLUTION @@ -30,7 +25,6 @@ services: - JIBRI_RECORDING_DIR - JIBRI_FINALIZE_RECORDING_SCRIPT_PATH - JIBRI_STRIP_DOMAIN_JID - - JIBRI_LOGS_DIR - PUBLIC_URL - TZ - XMPP_AUTH_DOMAIN @@ -45,4 +39,3 @@ services: - jicofo networks: meet.jitsi: - diff --git a/jibri/Dockerfile b/jibri/Dockerfile index e5926ec..af39897 100644 --- a/jibri/Dockerfile +++ b/jibri/Dockerfile @@ -18,8 +18,9 @@ ARG CHROMEDRIVER_MAJOR_RELEASE=102 COPY rootfs/ / RUN apt-dpkg-wrap apt-get update && \ - apt-dpkg-wrap apt-get install -y jibri libgl1-mesa-dri procps jitsi-upload-integrations jq && \ + apt-dpkg-wrap apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" jibri libgl1-mesa-dri procps jitsi-upload-integrations jq pulseaudio dbus dbus-x11 rtkit && \ /usr/bin/install-chrome.sh && \ - apt-cleanup + apt-cleanup && \ + adduser jibri rtkit VOLUME /config diff --git a/jibri/rootfs/defaults/jibri.conf b/jibri/rootfs/defaults/jibri.conf index 9ae5e56..017468d 100644 --- a/jibri/rootfs/defaults/jibri.conf +++ b/jibri/rootfs/defaults/jibri.conf @@ -103,14 +103,10 @@ jibri { ffmpeg { resolution = "{{ $JIBRI_RECORDING_RESOLUTION }}" - {{ if .Env.JIBRI_FFMPEG_AUDIO_SOURCE -}} // The audio source that will be used to capture audio on Linux - audio-source = "{{ .Env.JIBRI_FFMPEG_AUDIO_SOURCE }}" - {{ end -}} - {{ if .Env.JIBRI_FFMPEG_AUDIO_DEVICE -}} + audio-source = "pulse" // The audio device that will be used to capture audio on Linux - audio-device = "{{ .Env.JIBRI_FFMPEG_AUDIO_DEVICE }}" - {{ end -}} + audio-device = "default" } {{ if .Env.CHROMIUM_FLAGS -}} diff --git a/jibri/rootfs/defaults/logging.properties b/jibri/rootfs/defaults/logging.properties index 3789322..ffb40ab 100644 --- a/jibri/rootfs/defaults/logging.properties +++ b/jibri/rootfs/defaults/logging.properties @@ -1,29 +1,27 @@ -{{ $JIBRI_LOGS_DIR := .Env.JIBRI_LOGS_DIR | default "/config/logs" -}} - handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler org.jitsi.utils.logging2.JitsiLogFormatter.programname=Jibri java.util.logging.FileHandler.level = FINE -java.util.logging.FileHandler.pattern = {{ $JIBRI_LOGS_DIR }}/log.%g.txt +java.util.logging.FileHandler.pattern = /config/logs/log.%g.txt java.util.logging.FileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter java.util.logging.FileHandler.count = 10 java.util.logging.FileHandler.limit = 10000000 org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.level = FINE -org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = {{ $JIBRI_LOGS_DIR }}/ffmpeg.%g.txt +org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = /config/logs/ffmpeg.%g.txt org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.count = 10 org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.limit = 10000000 org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.level = FINE -org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = {{ $JIBRI_LOGS_DIR }}/pjsua.%g.txt +org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = /config/logs/pjsua.%g.txt org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.count = 10 org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.limit = 10000000 org.jitsi.jibri.selenium.util.BrowserFileHandler.level = FINE -org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = {{ $JIBRI_LOGS_DIR }}/browser.%g.txt +org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = /config/logs/browser.%g.txt org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter org.jitsi.jibri.selenium.util.BrowserFileHandler.count = 10 org.jitsi.jibri.selenium.util.BrowserFileHandler.limit = 10000000 diff --git a/jibri/rootfs/etc/cont-init.d/10-config b/jibri/rootfs/etc/cont-init.d/10-config index 524db05..2cf1522 100644 --- a/jibri/rootfs/etc/cont-init.d/10-config +++ b/jibri/rootfs/etc/cont-init.d/10-config @@ -21,22 +21,6 @@ fi [ -z "${DISPLAY}" ] \ && ( echo -e "\e[31mERROR: Please set DISPLAY variable.\e[39m"; kill 1; exit 1 ) -# check loaded snd_aloop module and exit if is not loaded on the host -[ -z "$(lsmod | grep -om1 snd_aloop)" ] \ -&& ( echo -e "\e[31mERROR: Please load snd-aloop module on the docker host.\e[39m"; kill 1; exit 1 ) - -# get host's audio group id -host_audio_group="$(stat -c %g /dev/snd/pcmC0D0p 2>/dev/null)" - -# audio group is not found. Has it been run without jibri.yml? -[ -z "${host_audio_group}" ] \ -&& ( echo -e "\e[31mERROR: Binding /dev/snd is not found. Please check that you run docker-compose with -f jibri.yml.\e[39m"; kill 1; exit 1 ) - -# try to create group with this id. If group with the id already exists, just skip -groupadd -g ${host_audio_group} jibri-audio >/dev/null 2>&1 -# include user to the group by id -usermod -aG ${host_audio_group} jibri - # script for finalizing must have executing bit. [ ! -z "${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}" ] \ && [ -f "${JIBRI_FINALIZE_RECORDING_SCRIPT_PATH}" ] \ @@ -57,6 +41,6 @@ mkdir -p ${JIBRI_RECORDING_DIR} chown -R jibri ${JIBRI_RECORDING_DIR} # make logs dir -[ -z "${JIBRI_LOGS_DIR}" ] && export JIBRI_LOGS_DIR=/config/logs +JIBRI_LOGS_DIR=/config/logs mkdir -p ${JIBRI_LOGS_DIR} chown -R jibri ${JIBRI_LOGS_DIR} diff --git a/jibri/rootfs/etc/fix-attrs.d/10-jibri b/jibri/rootfs/etc/fix-attrs.d/10-jibri new file mode 100644 index 0000000..fff5860 --- /dev/null +++ b/jibri/rootfs/etc/fix-attrs.d/10-jibri @@ -0,0 +1,2 @@ +/home/jibri/.config true jibri 0640 0750 +/home/jibri false jibri 0640 0750 diff --git a/jibri/rootfs/etc/pulse/default.pa b/jibri/rootfs/etc/pulse/default.pa new file mode 100644 index 0000000..8966833 --- /dev/null +++ b/jibri/rootfs/etc/pulse/default.pa @@ -0,0 +1,69 @@ +#!/usr/bin/pulseaudio -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +# This startup script is used only if PulseAudio is started per-user +# (i.e. not in system mode) + +# Customized for Jibri + +.fail + +### Automatically restore the volume of streams and devices +load-module module-device-restore +load-module module-stream-restore +load-module module-card-restore + +### Automatically augment property information from .desktop files +### stored in /usr/share/application +load-module module-augment-properties + +### Should be after module-*-restore but before module-*-detect +load-module module-switch-on-port-available + +### Load several protocols +load-module module-native-protocol-unix + +### Automatically restore the default sink/source when changed by the user +### during runtime +### NOTE: This should be loaded as early as possible so that subsequent modules +### that look up the default sink/source get the right value +load-module module-default-device-restore + +### Automatically move streams to the default sink if the sink they are +### connected to dies, similar for sources +load-module module-rescue-streams + +### Make sure we always have a sink around, even if it is a null sink. +load-module module-always-sink + +### Honour intended role device property +load-module module-intended-roles + +### Automatically suspend sinks/sources that become idle for too long +load-module module-suspend-on-idle + +### If autoexit on idle is enabled we want to make sure we only quit +### when no local session needs us anymore. +#.ifexists module-console-kit.so +#load-module module-console-kit +#.endif +#.ifexists module-systemd-login.so +#load-module module-systemd-login +#.endif + +### Enable positioned event sounds +load-module module-position-event-sounds diff --git a/jibri/rootfs/etc/services.d/30-pulse/run b/jibri/rootfs/etc/services.d/30-pulse/run new file mode 100644 index 0000000..f6e131c --- /dev/null +++ b/jibri/rootfs/etc/services.d/30-pulse/run @@ -0,0 +1,4 @@ +#!/usr/bin/with-contenv bash + +HOME=/home/jibri +exec s6-setuidgid jibri /bin/bash -c "exec /usr/bin/pulseaudio" diff --git a/jibri/rootfs/etc/services.d/30-jibri/finish b/jibri/rootfs/etc/services.d/40-jibri/finish similarity index 100% rename from jibri/rootfs/etc/services.d/30-jibri/finish rename to jibri/rootfs/etc/services.d/40-jibri/finish diff --git a/jibri/rootfs/etc/services.d/30-jibri/run b/jibri/rootfs/etc/services.d/40-jibri/run similarity index 100% rename from jibri/rootfs/etc/services.d/30-jibri/run rename to jibri/rootfs/etc/services.d/40-jibri/run diff --git a/jibri/rootfs/home/jibri/.config/pulse/client.conf b/jibri/rootfs/home/jibri/.config/pulse/client.conf new file mode 100644 index 0000000..207e152 --- /dev/null +++ b/jibri/rootfs/home/jibri/.config/pulse/client.conf @@ -0,0 +1 @@ +autospawn = no diff --git a/jibri/rootfs/home/jibri/.config/pulse/daemon.conf b/jibri/rootfs/home/jibri/.config/pulse/daemon.conf new file mode 100644 index 0000000..cf3fdd5 --- /dev/null +++ b/jibri/rootfs/home/jibri/.config/pulse/daemon.conf @@ -0,0 +1,9 @@ +daemonize = no +high-priority = no +realtime-scheduling = yes +realtime-priority = 5 +exit-idle-time = -1 +flat-volumes = no +deferred-volume-safety-margin-usec = 1 +log-level = info +log-target = file:/config/logs/pulse.log diff --git a/jibri/rootfs/home/jibri/.config/pulse/default.pa b/jibri/rootfs/home/jibri/.config/pulse/default.pa new file mode 100644 index 0000000..0ac59a7 --- /dev/null +++ b/jibri/rootfs/home/jibri/.config/pulse/default.pa @@ -0,0 +1,8 @@ +.include /etc/pulse/default.pa + +# Load the virtual sink and set it as default +load-module module-virtual-sink sink_name=jibri-loop +set-default-sink jibri-loop + +# set the monitor of the jibri-loop sink to be the default source +set-default-source jibri-loop.monitor