Seite wählen

NETWAYS Blog

Jitsi Meetings mit Jibri aufzeichen

Trotz scheinbar eintretender Entspannung bei der aktuellen Corona-Krise ist Videoconferencing nicht mehr wegzudenken. Sei es durch das Umdenken bei den Arbeitgebern zu Homeofficeregeleungen oder bei international gewachsenen Teams. Alle müssen irgendwie miteinander kommunizieren. Wir von NETWAYS setzen ja schon seit Beginn der Krise auf Jitsi und konnten damit auch viele Kunden überzeugen, datenschutzkonforme Videokonferenzlösungen einzusetzen.

Neben unserer Jitsi-App (JaaS), welche sich übrigens 30 Tage kostenfrei testen lässt und darüber hinaus auch schon Branding nach eigenen Bedürfnissen anbietet, bauen wir auch Jitsi-Lösungen nach Kundenwunsch. Seien es spezielle Anforderungen an besonders viele gleichzeitige Nutzer, ein komplett eigenes Branding, JWT-Auth, Telefoneinwahl oder Datenschutz-Pop-Up’s.

Inzwischen erreichen uns auch immer öfter Anfragen, die den Wunsch äußern, solche Meetings aufzuzeichnen. Also haben wir uns hier auf die Suche gemacht und Jibri gefunden. Nachfolgend beschreibe ich in aller Kürze, wie man seinen Jitsi-Server dazu bringt Videos aufzuzeichnen. Als Basis hierzu dient ein Ubuntu 20.04 LTS-Server mit bereits eingerichtetem Jitsi.

Alle nachfolgenden Schritte werden als root auf dem Jitsi-Meet Server ausgeführt, hingegen zur offiziellen Dokumentation gibt es ein paar Stolpersteine, welche ich euch gern erspare.

Vorbereitung

Zu Beginn installieren wir die erforderlichen Kernel-Module:

apt install linux-modules-extra-$(uname -r)
apt install linux-generic
reboot
echo "snd-aloop" >> /etc/modules 
modprobe snd-aloop

Nun machen wir den Server mittels Chrome Stable als Client fit:

curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add echo "deb [arch=amd64]  stable main" > /etc/apt/sources.list.d/google-chrome.list apt-get -y update apt-get -y install google-chrome-stable

Im nächsten Schritt kommen die Chrome managed-policies dazu:

mkdir -p /etc/opt/chrome/policies/managed
echo ‘{ “CommandLineFlagSecurityWarningsEnabled”: false }’ >>/etc/opt/chrome/policies/managed/managed_policies.json

Der Chrome-Treiber darf natürlich auch nicht fehlen, daher führen wir nun aus:

CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` wget -N  -P ~/ unzip ~/chromedriver_linux64.zip -d ~/ rm ~/chromedriver_linux64.zip sudo mv -f ~/chromedriver /usr/local/bin/chromedriver sudo chown root:root /usr/local/bin/chromedriver sudo chmod 0755 /usr/local/bin/chromedriver

Noch weitere benötigte Pakete:

apt install ffmpeg curl alsa-utils icewm xdotool xserver-xorg-input-void xserver-xorg-video-dummy

Installation Jibri

Die eigentliche Jibri-Installation machen wir über apt:

apt install jibri

Ohne Rechte geht natürlich nichts, daher kommen diese auch noch dazu:

usermod -aG adm,audio,video,plugdev jibri

In den nächsten Schritten kommt noch das erforderliche Java hinzu:

wget -O - https://adoptium.net/en-GB/blog/2023/07/adoptopenjdk-jfrog-io-has-been-deprecated/ | sudo apt-key add -
add-apt-repository https://adoptium.net/en-GB/blog/2023/07/adoptopenjdk-jfrog-io-has-been-deprecated/
apt-get -y update
apt-get install adoptopenjdk-8-hotspot

Wir müssen Java8 als default setzen, dazu ändern wir die nachfolgende Datei:

vim /opt/jitsi/jibri/launch.sh

Hier ändern wir das Wort „java“ in den folgenden String „/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/bin/java“. Danach speichern und schließen wir Datei schon wieder.

Prosody benötigt auch noch eine kleine Änderung. Also kommt das nun direkt (Achtung, Pfad weicht auf die eigene Domain am Ende ab):

vim /etc/prosody/conf.avail/your.domain.com.cfg.lua

Dort hängen wir am Ende einfach an (your.domain.com wieder durch eigene Jitsi-Adresse ersetzen):

-- internal muc component, meant to enable pools of jibri and jigasi clients
Component "internal.auth.your.domain.com" "muc"
modules_enabled = {
"ping";
}
storage = "memory"
muc_room_cache_size = 1000

VirtualHost "recorder.your.domain.com"
modules_enabled = {
"ping";
}
authentication = "internal_plain"

Danach speichern und schließen wir die Datei wieder
Nun bekommt Prosody noch 2 neue Nutzer, die Passwörter „JPwd“ und „RPwd“ ersetzt man durch eigene, sichere Passwörter und notiert diese für später:

prosodyctl register jibri auth.your.domain.com JPwd
prosodyctl register recorder recorder.your.domain.com RPwd

Jicofo will auch noch eine Änderung, diese beginnen wir durch öffnen des Config-Files:

vim /etc/jitsi/jicofo/sip-communicator.properties

Dort fügen wir die Zeilen ein (Achtung, Domainname anpassen):

org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.your.domain.com 
org.jitsi.jicofo.jibri.PENDING_TIMEOUT=90

Jetzt bringen wir Jitsi selbst wirklich noch bei, eine Aufnahme zu starten (!Domainname):

vim /etc/jitsi/meet/your.domain.com-config.js

hier prüfen wir, ob die folgenden Optionen so gesetzt sind, bzw. fügen den Code ein (!Domain):

fileRecordingsEnabled: true, 
liveStreamingEnabled: true, 
hiddenDomain: 'recorder.your.domain.com',

Der Dateispeicherort bekommt nun auch noch die Rechte, die er braucht, um von Jibri beschrieben zu werden:

mkdir /srv/recordings
chown jibri:jibri /srv/recordings

Zu guter Letzt, muss Jibri noch konfiguriert werden. Nachfolgend ein Beispiel hierfür. Man achte bitte auf das Ersetzen mit dem eigenen, korrekten Domainnamen und die korrekt vergebenen Passwörter:

vim /etc/jitsi/jibri/jibri.conf

jibri {
// A unique identifier for this Jibri
// TODO: eventually this will be required with no default
id = ""
// Whether or not Jibri should return to idle state after handling
// (successfully or unsuccessfully) a request. A value of 'true'
// here means that a Jibri will NOT return back to the IDLE state
// and will need to be restarted in order to be used again.
single-use-mode = false
api {
http {
external-api-port = 2222
internal-api-port = 3333
}
xmpp {
// See example_xmpp_envs.conf for an example of what is expected here
environments = [
{
name = "prod environment"
xmpp-server-hosts = ["your.domain.com"]
xmpp-domain = "your.domain.com"

control-muc {
domain = "internal.auth.your.domain.com"
room-name = "JibriBrewery"
nickname = "jibri-nickname"
}

control-login {
domain = "auth.your.domain.com"
username = "jibri"
password = "JPwd"
}

call-login {
domain = "recorder.your.domain.com"
username = "recorder"
password = "RPwd"
}

strip-from-room-domain = "conference."
usage-timeout = 0
trust-all-xmpp-certs = true
}]
}
}
recording {
recordings-directory = "/srv/recordings"
# TODO: make this an optional param and remove the default
finalize-script = "/path/to/finalize_recording.sh"
}
streaming {
// A list of regex patterns for allowed RTMP URLs. The RTMP URL used
// when starting a stream must match at least one of the patterns in
// this list.
rtmp-allow-list = [
// By default, all services are allowed
".*"
]
}
chrome {
// The flags which will be passed to chromium when launching
flags = [
"--use-fake-ui-for-media-stream",
"--start-maximized",
"--kiosk",
"--enabled",
"--disable-infobars",
"--autoplay-policy=no-user-gesture-required"
]
}
stats {
enable-stats-d = true
}
webhook {
// A list of subscribers interested in receiving webhook events
subscribers = []
}
jwt-info {
// The path to a .pem file which will be used to sign JWT tokens used in webhook
// requests. If not set, no JWT will be added to webhook requests.
# signing-key-path = "/path/to/key.pem"

// The kid to use as part of the JWT
# kid = "key-id"

// The issuer of the JWT
# issuer = "issuer"

// The audience of the JWT
# audience = "audience"

// The TTL of each generated JWT. Can't be less than 10 minutes.
# ttl = 1 hour
}
call-status-checks {
// If all clients have their audio and video muted and if Jibri does not
// detect any data stream (audio or video) comming in, it will stop
// recording after NO_MEDIA_TIMEOUT expires.
no-media-timeout = 30 seconds

// If all clients have their audio and video muted, Jibri consideres this
// as an empty call and stops the recording after ALL_MUTED_TIMEOUT expires.
all-muted-timeout = 10 minutes

// When detecting if a call is empty, Jibri takes into consideration for how
// long the call has been empty already. If it has been empty for more than
// DEFAULT_CALL_EMPTY_TIMEOUT, it will consider it empty and stop the recording.
default-call-empty-timeout = 30 seconds
}
}

Das wars, nun startet man die betroffenen Dienste noch neu und der Aufnahme-Button im Meeting zeigt nun auch die gewünschte Funktion:

systemctl restart jitsi-videobridge2 prosody jicofo
systemctl enable --now jibri

Die Aufnahmen sind nun in /srv/recordings zu finden. Sollte hier noch kein Bild und Ton sichtbar sein, hat final folgende Änderung in der Datei /etc/jitsi/jicofo/jicofo.conf noch Abhilfe geschafft

Man suche sich die Zeile:

trusted-domains: recorder.your.domain.com

und passt sie an, auf:

trusted-domains: [recorder.your.domain.com]

Nach einem letzten Dienstneustart läuft nun alles wie gewünscht.

Schlusswort

Bedenken sollte man, dass Videos gespeichert werden und entsprechend viel Platz verbrauchen. Dies sollte man beim Sizing des Systems beachten. Die Daten sind auch nicht einfach für jeden Teilnehmer herunterladbar, sondern liegen auf dem Jitsi-Server unter /srv/recordings.

Alles in Allem ist dies aber eine wunderbare Lösung, um Workshops mit Kollegen aufzuzeichnen und diese später an neue Kollegen weiter zu geben.

Sobald die Aufzeichnung ausgelöst wird, wird dies allen Teilnehmern auch via Text2Speech mitgeteilt. Im Meeting ist oben neben dem Meetingnamen auch ein Recording-Symbol zu sehen.

Wer ein solches Jitsi haben will, sich aber nicht gern selbst darum kümmert, wäre bei uns genau richtig und sollte den Kontakt zu unseren freundlichen Vertriebskollegen suchen. Unsere Server stehen in Nürnberg und ermöglichen so eine vollständig datenschutzkonforme Videokonferenzlösung.

Music Home-Recording unter Linux

Heute möchte ich ein Thema aufgreifen, das für alle diejenigen ist, die ein Instrument spielen und Musik machen. Meine Wenigkeit spielt E-Gitarre (Heavy Metal) und wie oft kommt es vor, man spielt mit dem Drumcomputer mit und plötzlich hat man eine super klasse Akkord-Folge (Riff-Folge) die man in Schleife spielt. Man denkt sich, Mensch die muss ich aufnehmen, aber wie?

Falls man sich mit der Thematik „Home-Recording“ unter Linux noch nicht beschäftigt hat, steht man da jetzt wie der „Ochs vorm Berg“. Da das Thema riesengroß ist, werde ich nur etwas den Einstieg beleuchten, wie ABNAHME, LATENZ, SOFTWARE.

Abnahme Instrument

Hiermit ist gemeint, wie ich das Instrument z.B. E-Gitarre mit meinen Computer verbinde und was brauche ich dazu. Am einfachsten man besorgt sich ein sogenanntes Audio-USB-Interface, das normalerweise Eingänge für Klinkenstecker oder Mikrofon hat, um das Instrument anzuschließen. Der Vorteil von dem Interface ist, das man das Eingangssignal einstellen (auspegeln) kann und je nach Ausstattung einen Kopfhörer-Ausgang beziehungsweise weitere Features hat. Ich kann für Linux-User folgendes Interface empfehlen, welches ich auch verwende: Behringer U-Phoria UMC204HD. Dieses Gerät wird per USB an den Computer angeschlossen und sollte vom Linux-Kernel erkannt werden.

Bei Instrumenten die nicht per Kabel direkt ans Interface angesteckt werden können, müssen per Mikrofon abgenommen und das ans Interface angeschlossen werden z.B. Saxophon.

Früher hatte ich auch Verstärker-Preamp-Out direkt mit dem Mic-Eingang der Soundkarte verbunden, was aber nicht sehr flexibel ist, da ich das Eingangsignal immer im Computer anpassen musste und man eine gute Soundkarte braucht, die speziell für Audio-Aufnahmen sein sollte, was diese nicht war.

Bei mir:

  • Audio-USB-Interface via USB am Computer
  • Preamp-Out Verstärker per Klinken-Kabel mit dem Eingang Audio-USB-Interface verbunden
  • Alternative E-Gitarre direkt ins Audio-USB-Interface und auf Instrument schalten sonst ist es Line-In.

Latenz

Um es simpel zu beschreiben, ist die Verzögerungszeit vom praktisch gespielten Ton (Instrument) bis zum hörbaren Ton aus dem Computer-Lautsprecher. Der Computer muß das In -und Output-Signal verarbeiten und das am besten in Realtime. Dafür braucht man unter Linux einen Realtime-Kernel, der bei manchen Linux-Distributionen (z.B. openSUSE-Leap, Ubuntu-Studio) bereits als RT-Kernel Paket zum installieren in den Repositories vorhanden ist. Was auch noch wichtig ist, das die Desktop-Oberfläche schlank ist und nicht wertvollen Arbeitsspeicher im Betrieb verbraucht (z.B. XFCE, LXDE, Enlightenment)

Diese Latenz lässt sich mit der Software JACK (JACK Audio Connection Kit) einstellen um das gewünschte Ergebnis zur erhalten, dazu könnte man schon alleine einen Blogbeitrag füllen. Die Standard-Einstellung sollte für die ersten Versuche ausreichend sein.

Software

Mittlerweile gibt es einiges an Open Source Software unter Linux, die auch von diversen Distributionen über Repositories installiert werden kann, hier mal eine kleine Auswahl:

Für Einsteiger würde ich die ALL-in-One Lösung Qtractor wählen, da diese einfacher und verständlicher zu bedienen ist, JACK braucht jeder um die Eingänge und Ausgänge zu steuern. Wer jetzt schon mit MIDI herum experimentiert, kann sich Rosegarden anschauen, Nachteil Audiospuren editieren, hier muss eine passende Software in den Einstellungen wie z.B.  Audacity mit verknüpft werden.

Je nachdem was man jetzt für eine Software zum Recording verwendet, braucht man eine gewisse Zeit bis man sich in diese eingearbeitet hat und da gehen schon Stunden ins Land. Deswegen würde ich jetzt nicht ins Detail gehen das würde hier den Rahmen sprengen, aber im Netz findet man jede Menge HowTo’s zu der jeweiligen Software, die die tiefere Anwendung beschreiben.

So jetzt wünsche ich jedem viel Erfolg bei seiner ersten Aufnahme und falls diese Schrott wird, keine Bange ich weiß schon gar nicht mehr wie viel Schrott ich am Anfang produziert habe, hier gilt die Devise, einfach weitermachen, es ist noch kein Meister vom Himmel gefallen.:-)

Johannes Carraro
Johannes Carraro
Senior Systems Engineer

Bevor Johannes bei NETWAYS anheuerte war er knapp drei Jahre als Systemadministrator in Ansbach tätig. Seit Februar 2016 verstärkt er nun unser Team Operations als Senior Systems Engineer. In seiner Freizeit spielt Johannes E-Gitarre, bastelt an Linux Systemen zuhause herum und ertüchtigt sich beim Tischtennisspielen im Verein, bzw. Mountainbiken, Inlinern und nicht zuletzt Skifahren.

Hollywood auf der Bash

In diesem Blogpost möchte ich euch zeigen wie Ihr relativ einfach und ohne großen Aufwand auf der Shell eigene Kassenschlager à la Hollywood produzieren könnt. Dafür benötigte Tools stehen auf den gängigen Linux-Distributionen bereits über die Standard Utilities (util-linux bzw. util-linux-ng) zur Verfügung.
Den Großteil der Zeit eines Filmregisseurs beansprucht natürlich die aufwändige und oft kräftezehrende Produktion der einzelnen Filmszenen, wir benutzen hierzu unsere virtuelle Kamera namens script.
Script steht eigentlich für Typescript und lässt sich z.B. mit „maschinengeschriebenes Schriftstück“ übersetzen. Genau das produzieren wir jetzt! Script möchte von uns dazu lediglich den Namen der Zieldatei haben, also:

# script recordfile
Script wurde gestartet, die Datei ist recordfile

oder alternativ:

# script -f recordfile
Script wurde gestartet, die Datei ist recordfile

Nun kann die wilde Bash-Show starten und wenn wirklich keine neuen Ideen mehr nachkommen lässt sich die Aufnahme mit [Strg] + [d] beenden, es erscheint folgende Ausgabe:

# exit
Script wurde beendet, die Datei ist recordfile

Die Wiedergabe der Datei recordfile kann nun beispielsweise mit dem altbekannten cat erfolgen. Da uns diese Methode vermutlich nicht allzu viele begeisterte Zuseher einbringen wird, erweitern wir die Aufnahme um einen sog. Timingaufruf, das könnte so aussehen:

# script -t 2> time.file record.file

Natürlich muss auch hier die „virtuelle Kamera“ am Ende wieder mit  [Strg] + [d] beendet werden. Bei der Wiedergabe unterstützt uns nun scriptreplay, das die Sequenzen deutlich massentauglicher darstellt:

# scriptreplay time.file record.file

Zugegeben – unsere Zuschauerzahlen werden sich wohl noch nicht (gleich) mit denen der großen Hollywood-Blockbuster vergleichen lassen, aber was nicht ist kann ja noch werden. In diesem Sinne: Klappe… und Action!

Markus Waldmüller
Markus Waldmüller
Head of Strategic Projects

Markus war bereits mehrere Jahre als Sysadmin in Neumarkt i.d.OPf. und Regensburg tätig. Nach Technikerschule und Selbständigkeit ist er nun Anfang 2013 bei NETWAYS als Senior Manager Services gelandet. Seit September 2023 kümmert er sich bei der NETWAYS Gruppe um strategische Projekte. Wenn er nicht gerade die Welt bereist, ist der sportbegeisterte Neumarkter mit an Sicherheit grenzender Wahrscheinlichkeit auf dem Mountainbike oder am Baggersee zu finden.