# Video-Livestream

Hier wird beschrieben, mit welcher Ausstattung (Hard- und Software) der Gottesdienst in unserer Gemeinde live übertragen wird. Die Übertragung erfolgt bei uns nicht öffentlich, sondern ist für Gemeindemitglieder und Freunde gedacht, die aus verschiedenen Gründen den Gottesdienst nicht besuche können, aber mit unserer Gemeinde verbunden sind. Voraussetzung dafür ist (neben der hier beschriebenen Austattung) ein eigener bzw. gemieteter Internet Server. Die Vorgehensweise lässt sich jedoch an verschiedene Anwendungsbereiche (also z.B. auch öffentlicher Livestream) anpassen.

![unser Gemeinde](bilder/saal.jpg)

> In der aktuellen Situation (Corona-Kriese 2020) erfolgt die Übertragung der Gottesdienste ausschliesslich online und wir bekommen sehr positives Feedback, dass so eine Verbundenheit miteinander bestehen bleibt.
>

Diese Dokumentation darf gemäss der [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/de/) Lizenz verwendet und bearbeitet werden.

## Ausstattung

### Hardware

- [Kamera](#kamera)
- [HDMI Audio Inserter](#hdmi-audio-inserter)
- [Encoder](#encoder)
- [Audio-Mischpult](#audio-mischpult)
- [PC](#pc)
- [Server](#server)

### Software

- [OBS-Studio](#obs-studio)
- [MistServer](#mistserver)

-----

### Kamera

Als Kamera nutzen wir eine Canon LEGRIA HF R77. Das ist ein "normaler" Camcorder aus dem Heimvideo-Bereich. Wichtig ist hier ein HDMI-Ausgang, der das Live-Bild ausgibt und die Möglichkeit, den Camcorder auch ohne Aufnahme im Dauerbetrieb laufen zu lassen. Einige Camcorder schalten nach einer gewissen Zeit im Leerlauf ab. In diesem Fall könnte man aber auch einfach die Aufnahme aktivieren, sofern das Live-Bild trotzdem über den HDMI-Ausgang gesendet wird.

![Kamera](bilder/kamera.jpg)

*[^ zum Anfang](#ausstattung)*

### HDMI-Audio-Inserter

Der HDMI-Ausgang der Kamera ist zunächst mit einem sogenannten "HDMI-Audio-Inserter" verbunden. Wir verwenden das Modell HM-CV032K von SPEAKA. Wie der Name schon sagt, ist der Zweck dieses kleinen Kastens, ein externes Audiosignal in den HDMI-Datenstrom der Kamera einzufügen bzw. den Originalton der Kamera zu ersetzen. Natürlich könnte man auch den Ton der Kamera verwenden, wobei die Qualität dann aber deutlich geringer sein dürfte, als bei einem direkt vom Audiomischpult abgegriffenen Signal.

![HDMI Audio Inserter](bilder/hdmi_audio_insert.jpg)

Wenn man den Ton der Kamera nicht verwenden möchte, ist auf jedan Fall das Einfügen des Audiosignals **vor** dem Encoder notwendig, um die Syncronität von Bild und Ton beizubehalten. Softwareseitig (im OBS-Studio) könnte man auch noch Tonspuren einfügen, die würden dann aber im fertigen Stream zeitversetzt vor dem Bild laufen, weil der Encoder den HDMI-Datenstrom leicht verzögert ausgibt.

> Neuere Encoder haben die Audio-Insert-Funktion bereits integriert und man kann das Audiosignal direkt in den Encoder einspeisen. Das von uns verwendete Modell ist eine Vorgängerversion der aktuellen Serie und besitzt keinen Audio-Eingang.

*[^ zum Anfang](#ausstattung)*

### Encoder

Obwohl man mit Hilfe eines HDMI-Grabbers (HDMI-Capture) den HDMI-Datenstrom direkt in den Computer übertragen, und dort im OBS-Studio den Ton dazu mischen könnte, haben wir uns aus verschiedenen Gründen für eine externe Lösung in Form eines IPTV-Encoders entschieden:

* Ein externes Gerät entlastet den Computer. In unserem Fall läuft darauf neben dem OBS-Studio auch noch [OpenLP](https://openlp.org) damit das Beamer-Bild in den Video-Stream integriert werden kann
* Der von uns verwendete Encoder [IRENIS ADE-264](https://www.blankom.de/ip-encoder-en/iptv-streamer-encoder-hdmi-cvbs-input-irenis-ade-264/) kann 2 Streams mit unterschiedlichen Auflösungen und Kompressionsraten erzeugen. Wir nutzen das, um einen Stream mit höherer Auflösung an einen Monitor in unserem Eltern-Kind-Raum zu senden. Der zweite Stream wird über das OBS-Studio an unseren Internet-Server geschickt.

![Encoder](bilder/encoder.jpg)

*[^ zum Anfang](#ausstattung)*

### Audio-Mischpult

Die Einstellungen des Audio-Mixers, der für die Beschallung unserer Gottesdienste verwendet wird, entsprechen in den meisten Fällen nicht denen, die für eine Aufnahme bzw. Übertragung notwendig sind. Da reicht von unterschiedlichen Lautstärkeverhältnissen zwischen Musik und Sprache bis zu den Klang- und Dynamikeinstellungen der einzelnen Kanäle. Neuere und größere Digital-Mischpulte, wie das von und verwendete [Soundcraft Si Impact](https://www.soundcraft.com/products/si-impact) bieten die Möglichkeit, einen Sub-Mix zu erstellen und an seperate Ausgänge zu legen. Weil das ziemlich komplexe Einstellungen sind und unerfahrene Techniker schnell an ihre Grenzen bringt, verwenden wir ein zusätzliches kleines Digital-Mischpult für den Video-Ton. 

![Mixer](bilder/mixer.jpg)

Das [Soundcraft Ui12](https://www.soundcraft.com/en-US/products/ui12) ist sehr kompakt und wird über eine Netzwerkverbindung mit dem Internet-Browser bedient. Das hat natürlich auch den Vorteil, dass man die Einstellungen z.B. vom Eltern-Kind Übertragungsraum aus vornehmen kann und so eine direkte Kontrolle des Ergebnisses hat. In der aktuellen Einstellung wird das Summen-Signal vom "großen Bruder" und zusätzlich noch einmal der Mikrofonkanal vom Rednerpult eingespeist. Die Lautstärke des Mikrofonkanals wird mit Hilfe der Dynamik-Effekte (Kompressor/Limiter/Gate) angepasst. Als weitere "Ausbaustufe" wären z.B. zusätzliche Raum-Mikrofone denkbar, die das Live-Empfinden der Zuschauer verbessern, da die ganze Raumakustik (Gemeindegesang,...) mit eingefangen wird.

*[^ zum Anfang](#ausstattung)*


### PC

Als PC verwenden wir einen handelsüblichen Büro-Computer mit [Ubuntu](https://ubuntu.com/) als Betriebssysthem. Wichtig ist hier, dass der Computer über ausreichend Leistung verfügt, um Lieder und Multimedia-Inhalte mit [OpenLP](https://openlp.org) am Beamer anzuzeigen und gleichzeitig den Video-Stream mit [OBS-Studio](https://obsproject.com/) an den Server zu senden. Das Video-Signal wird hierbei teilweise mit dem Beamer-Bild überlagert und muss demzufolge noch einmal neu encodiert werden (ein Intel i3 mit 8GB Ram ist hier bereits ausreichend).

*[^ zum Anfang](#ausstattung)*


### Server

Für die bereitstellung des Video-Live-Streams über das Internet verwenden wir einen gemieteten root-Server. Die detailierte Beschreibung der Einrichtung des Servers würde hier zu weit führen. Wer einen eigenen Server betreibt, sollte auf jeden Fall über ausreichende Kenntnisse in diesem Bereich verfügen. Die erforderliche Leistung des Servers hängt von der Anzahl der gleichzeitigen Zuschauer des Live-Streams ab. Neben der reinen Prozessorleistung bzw. Arbeitsspeichergröße, ist dabei auch die Netzwerk-Last zu beachten. In unserer ersten Installation hatte ein root-Server mit 2 Kernen und 8GB Ram bei 48 Clients etwa 35% CPU-Last. Im Downstream (Server zu Clients) lagen ca. 80 MBit/s an. Vereinzelt haben Zuschauer von stockendem Bild und Ton berichtet, wobei für uns nicht eindeutig klar ist, ob das Problem beim Server oder bei den Clients lag.

*[^ zum Anfang](#ausstattung)*

### OBS-Studio

*[^ zum Anfang](#ausstattung)*

### MistServer

Der [MistServer](https://mistserver.org/) ist eine OpenSource Software, mit deren Hilfe man sehr einfach und komfortabel einen Video-Stream im Internet zur Verfügung stellen kann. Die Installation der OpenSource-Version ist unter [https://mistserver.org/download](https://mistserver.org/download) beschrieben und mit einer Zeile auf der Linux-Konsole erledigt:

> Die Versionsnummer in dem Befehl kann zu einem anderen Zeitpungt natürlich anders sein

```
curl -o - https://releases.mistserver.org/is/mistserver_64V2.17.tar.gz 2>/dev/null | sh
```

> Achtung! Nach dem Ausführen des Befehls startet der MistServer automatisch und ist ungesichert über den Port 4242 erreichbar (wenn keine Firewall aktiv ist)!

Der MistServer ist über folgende Ports erreichbar, die gegebenenfalls in der Firewall zugelassen werden müssen.

- TCP 1935 - RTMP-Port für Upload von OBS-Studio bzw. Download über entsprechende Programme
- TCP 4242 - Management-Interface
- TCP 8080 - HTTP-Port für Streaming-Clients
- TCP 4433 - HTTPS-Port für Streaming-Clients

Die Ports 4242 und 8080 müssen nicht freigegeben werden, wenn vor dem MistServer noch ein anderer Wabserver (wie z.B. Apache) als ReverseProxy eingerichtet ist.

Wir nutzen den Apache-Webserver mit folgenden Einstellungen (Servernamen als Beispiel):

```
<VirtualHost *:80>

    ServerName video.domain.tld

    DocumentRoot /var/www/html/

    SSLEngine off
    
    RewriteEngine on
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

</VirtualHost>

<VirtualHost *:443>
	
    ServerName video.domain.tld
    
    DocumentRoot /var/www/html/

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/domain.tld/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld/privkey.pem
    
    ProxyRequests off
    ProxyPreserveHost On
    SetOutputFilter proxy-html

    <Location "/">
    
        RewriteEngine on
        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule .* ws://localhost:8080%{REQUEST_URI} [P]

        ProxyPass http://localhost:8080/
        ProxyPassReverse http://localhost:8080/
        ProxyHTMLURLMap http://localhost:8080 /
        
    </Location>
    
    <Location "/admin">
    
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/.video-admin
        Require valid-user
    
        RewriteEngine on
        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule .* ws://localhost:4242%{REQUEST_URI} [P]

        ProxyPass http://localhost:4242/
        ProxyPassReverse http://localhost:4242/
        ProxyHTMLURLMap http://localhost:4242/
        
    </Location>

    CustomLog /var/log/apache2/video.domain.tld.log combined
    ErrorLog /var/log/apache2/video.domain.tld.error.log

</VirtualHost>
```

> Leider ist das Management-Interface in der OpenSource-Version nur unverschlüsselt über `http` erreichbar. Wenn man Port 4242 in der Firewall sperrt und einen den Webserver als ReverseProxy konfiguriert, funktioniert auch `https`. Wir haben aber festgestellt, dass dann das Management-Interface nach erstmaligem Login ohne Anmeldung auch von anderen Clients aus erreichbar war (trotz erfolgreicher Abmeldung). Entweder ist die Proxy-Einstellung noch unvollständig, oder die Abmeldung funktioniert nicht ordnungsgemäß). Aus diesem Grund haben wir in der Webserver-Konfiguration eine zusätzliche Authentifizierung eingerichtet.

Die Datei `/etc/apache2/.video-admin` kann wie folgt erstellt werden:

```
apt install apache2-utils
htpasswd -c /etc/apache2/.video-admin <admin-benutzername>
New password: <admin-passwort>
Re-type new password: <admin-passwort>
```

Mit diesen Einstellungen ist das Management-Interface vom MistServer nur noch über `https://video.domain.tld/admin` erreichbar und die Video-Streams unter `http://video.domain.tld/<Streamnummer>.html`. RTMP läuft weiterhin über Port 1935 und mit einem entsprechenden Programm (wie z.B. VLC-Player) können die Streams auch unter `rtmp://video.domain.tld:1935/play/<Streamnummer>` angesehen werden.

*[^ zum Anfang](#ausstattung)*

#### MistServer konfigurieren

Wenn man nach der Installation des MistServers das erste mal die Webseite des Management-Interfacees startet, wird man aufgefordert, einen Benutzernamen und ein Passwort zu vergeben.

![MistServer LogIn](bilder/ms_login.jpg)

Im nächsten Schritt werden alle Standard-Protokolle aktiviert.

![MistServer Protokolle](bilder/ms_protokolle.jpg)

Soll der Stream über eine verschlüsselte Verbindung abgerufen werden, muss noch das https-Protokoll manuell aktiviert werden.

![MistServer LogIn](bilder/ms_protokoll_neu.jpg)

![MistServer LogIn](bilder/ms_protokoll_https.jpg)

Jetzt kann der Stream angelegt werden.

![MistServer LogIn](bilder/ms_streams.jpg)

Für die Einrichtung des Live-Streams sind im MistServer nur zwei Einträge notwendig: der Streamname und die Quelle. Da es in der OpenSource-Version keine Möglichkeit gibt, den Stream mit einem Passwort zu schützen, hat man nur die Möglichkeit, den Streamnamen so zu wählen, dass er nicht zu erraten ist. Mit dem folgenden Befehl kann man auf der Linux-Konsole eine zufällige Zeichenfolge generieren, die dann als Streamname verwendet wird:

```
< /dev/urandom tr -dc _a-z-0-9 | head -c${1:-32};echo;
```

In diesem Fall wird eine 32-stellige Zeichenfolge gebildet. Die Adresse für den Live-Stream wäre dann `https://video.domain.tld/vdtj0hu5n8o_29iyrzyh0lysvkrg9a2z.html` und damit nahezu unmöglich für nicht authorisierte Zuschauer erreichbar. Natürlich muss diese Adresse dann allen authorisierten Zuschauern zugänglich gemacht werden (E-Mail, Messanger,...).

![MistServer LogIn](bilder/ms_stream_neu.jpg)