Linux - IPcam als virtuelle Webcam

Unter Linux kann man relativ einfach eine IP-Kamera als Webcam nutzen. Möglich wird dies mit durch die Video-Aufnahme-Schnittstelle Video4Linux2 (kurz v4l2). Neben der direkten Unterstützung von etlichen USB Webcams, TV-Karten und ähnlichen Geräten werden auch RTSP-Streams (Real-Time Streaming Protocol) von IP-Kameras unterstützt.

Videochat- und Konferenz-Softwaretools wie Skype, Zoom etc. können mit RTSP-Streams nichts anfangen, sie benötigen einen Geräteeintrag im Betriebssystem. V4L2 bietet die Möglichkeit sog. Loopback-Devices anzulegen. Mithilfe dieser virtuellen Geräte gaukelt man Skype und Co. vor, dass eine Videokamera direkt am Computer angeschlossen sei.

Nachfolgend eine kurze Beschreibung zur Einbindung eines RTSP-Streams als virtuelle Kamera unter Ubuntu LTS 20.04.1 (Kernel 5.8). Das Beispiel hat keinen Anspruch auf Vollständigkeit und dient mir nur als Proof of Concept. Für den produktiven Einsatz empfand ich persönlich die Latenz des Videobildes als nicht akzeptabel. Die Latenz hängt aber u.a. entscheidend von der eingesetzten IP-Kamera und der eingesetzten Netzanbindung der Kamera ab.

 

1. Installation der benötigten Software

Sämtliche benötigte Software findet man in der Standard-Archiven von Ubuntu/Debian. Daher kann direkt aus der Kommandozeile heraus mit der Installation begonnen werden. Notwendig sind die folgenden Pakete:

  • v4l2-loopback
    • Kernel-Modul, welches es erlaubt virtuelle Geräte anzulegen
  • v4l2-ctl
    • Dienstprogramm zur Steuerung der video4linux Treiber
    • Das Dienstprogramm ist im Paket v4l-utils enthalten
  • ffmpeg
    • Ein Kommandozeilenprogramm aus dem FFmpeg-Projekt, welches Video-, Audio- und Bildformate konvertieren, aufnehmen und streamen kann.

Zur Installation öffnet man ein Terminal-Fenster und installiert die folgenden Pakete mit Administratorrechten (sudo):

> sudo apt install v4l2loopback-dkms

> sudo apt install v4l-utils

> sudo apt install ffmpeg

Erlauben Sie bei Nachfragen des Paketmanagers die Installation auf der lokalen Platte sowie die Installation weiterer Pakete. Wer sich genauer mit dem Loopback-Modul beschäftigen möchte, der findet die Quellen auf Github unter https://github.com/umlaeute/v4l2loopback.

 

2. Einbindung des Kernel-Treibers

Durch die Nutzung von DKMS (Dynamic Kernel Module Support) bei der Installation des Loopback-Treibers überwacht DKMS die Installation dieses manuellen Kernel-Moduls. Ein wesentlicher Vorteil ist, dass bei der Installation neuer Linux-Kernel sich DKMS automatisch um die Aktualisierung des manuellen Kernel-Moduls (hier v4l2loopback) kümmert.

Zum Laden des Kernel-Treibers nutzen wir den Befehl modprobe. Auftretende Abhängigkeiten von anderen Modulen löst modprobe dabei automatisch selbst auf, sofern die Abhängigkeiten richtig im System hinterlegt sind (Stichtwort depmod).

> sudo modprobe v4l2loopback 

Um nachzusehen, ob das Modul geladen wurde, wird lsmod verwendet:

> lsmod | grep "v4l2loopback"

v4l2loopback           40960  1
videodev              237568  2 v4l2loopback

Sollten Sie mehrere virtuelle Geräte anlegen wollen, dann fügen Sie über den Parameter device=x die entsprechende Anzahl hinzu. Für drei Geräte könnte der Befehl wie folgt aussehen:

> sudo modprobe v4l2loopback devices=3

Die virtuellen Geräte finden Sie unter /dev/videoXY. Eine einfache Auflistung ermöglicht das Tool v4l2-ctl:

> v4l2-ctl --list-devices

Dummy video device (0x0000) (platform:v4l2loopback-000):
    /dev/video0

Sollte das virtuelle Geräte nicht in der Auflistung erscheinen, dann ist bei der Einbindung des Kernel-Treiber etwas schief gelaufen und die Fehlerursache muss erforscht werden.

 

3. RTSP-Videostrom zur virtuellen Webcam streamen

Zum Streamen des Videobildes der IP-Kamera an das virtuelle Videogerät /dev/video0 nutzen wir nun das Programm ffmpeg. FFmpeg ist sehr mächtig und verfügt über viele Parameter zum Modifizieren und Tunen der Bild-/Videoausgabe.

Das Beispiel geht davon aus, dass die IP-Kamera die IP-Adresse 192.168.80.100 besitzt, auf dem Port 554 den Videostrom via RTSP - ohne Angabe einer Authentifizierung - zur Verfügung stellt und der Hauptvideo-Strom genutzt wird, im Beispiel durch das Anhängen von /11 an die IP-Adresse und den Port der Kamera.

> ffmpeg -rtsp_transport tcp -i rtsp://192.168.80.100:554/11 -pix_fmt yuv420p -f v4l2 /dev/video0

Exemplarische Ausgabe:

Input #0, rtsp, from 'rtsp://192.168.80.100:554/11':
  Metadata:
    title           : \11
  Duration: N/A, start: 0.066589, bitrate: N/A
    Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1280x720, 15 tbr, 90k tbn, 180k tbc
    Stream #0:1: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, video4linux2,v4l2, to '/dev/video0':
  Metadata:
    title           : \11
    encoder         : Lavf58.29.100
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1280x720, q=2-31, 165888 kb/s, 15 fps, 15 tbn, 15 tbc
    Metadata:
      encoder         : Lavc58.54.100 rawvideo
frame=  172 fps= 29 q=-0.0 Lsize=N/A time=00:00:11.46 bitrate=N/A speed=1.91x

Der Pfad für den RTSP-String ist entsprechend dem verwendeten Kamera-Modell anzupassen. Außerdem lassen sich einige Parameter von ffmpeg sicherlich noch tunen. Als Proof of Concept erachte ich das Ergebnis jedoch als ausreichend.

 

4. Test der virtuellen Webcam

Bisher haben wir noch kein Bild der virtuellen Webcam gesehen. Dazu verwende ich das Tool ffplay, welches auf die ffmpeg Biblioteken zurückgreift.

> ffplay /dev/video0

Es öffnet sich ein graphisches Fenster mit dem Videostream des virtuellen Geräts /dev/video0. Wenn das Video etwas träge erscheint, dann bietet ffplay einige Parameter zum Tuning. Probieren Sie den nachfolgenden Befehl:

> ffplay /dev/video0 -fflags nobuffer -flags low_delay -framedrop

Kurze Erläuterung der verwendeten Parameter:

  • nobuffer: Reduziert die durch die Pufferung entstehende Latenz während der ersten Analyse des Eingangsstromes
  • low_delay: erzwingt niedrige Verzögerung
  • framedrop: verwirft Videobilder, wenn das Video nicht synkron ist.


 

5. Autostart via systemd

Aktuell verwirft das System das Streaming der IP-Kamera mit dem Beenden von ffmpeg. Nach einem Neustart muss das Kernel-Modul v4l2loopback neu geladen werden. Damit dies nicht via manueller Eingabe erfolgen muss, verwende ich folgende systemd-Startskripte, welche ich unter /etc/systemd/system ablege.

/etc/systemd/system/v4l2.service
[Unit]
Description=Create_loopback_device

[Service]
ExecStart=modprobe v4l2loopback
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

 

/etc/systemd/system/ipcam.service
[Unit]
Description=Stream_IPcam_to_virtual_webcam
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=ffmpeg -rtsp_transport tcp -i rtsp://192.168.80.100:554/11 -pix_fmt yuv420p -f v4l2 /dev/video0
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Wichtig ist beim Skript ipcam.service das Warten auf eine vorhandene Netzwerkverbindung (siehe auch unter Unit network-online.target).

Zur Aktivierung der Skripte gebe ich im Terminal die folgenden Befehle ein:

> sudo systemctl daemon-reload
> sudo systemctl enable v4l2.service
> sudo systemctl enable ipcam.service

Nach einem Neustart ist die IP-Kamera automatisch als virtuelle Webcam /dev/video0 aktiv.