µStreamer ist ein leichter und sehr schneller Server zum Streamen von MJPEG-Videos von jedem V4L2-Gerät ins Internet. Alle neuen Browser unterstützen dieses Videoformat nativ, ebenso wie die meisten Videoplayer wie mplayer, VLC usw. µStreamer ist Teil des PiKVM-Projekts, das darauf ausgelegt ist, VGA- und HDMI-Screencast-Hardwaredaten mit der höchstmöglichen Auflösung und FPS zu streamen.
µStreamer ist dem mjpg-streamer mit den Plugins input_uvc.so
und output_http.so
sehr ähnlich, es gibt jedoch einige wesentliche Unterschiede. Die wichtigsten sind:
Besonderheit | µStreamer | mjpg-Streamer |
---|---|---|
Multithread-JPEG-Kodierung | ✔ | ✘ |
Hardware-Bildkodierung auf Raspberry Pi | ✔ | ✘ |
Verhalten, wenn das Gerät wird während des Streamings getrennt | ✔ Zeigt einen schwarzen Bildschirm anNO SIGNAL draufbis zur erneuten Verbindung | ✘ Stoppt das Streaming 1 |
Unterstützung für DV-Timings - die Möglichkeit, die Auflösung zu ändern im laufenden Betrieb nach Quellsignal | ✔ | ☹ Teilweise ja 1 |
Option zum Überspringen von Frames beim Streaming statische Bilder über HTTP, um den Datenverkehr zu sparen | ✔ 2 | ✘ |
Streaming über UNIX-Domain-Socket | ✔ | ✘ |
Aktivierung des Systemd-Sockets | ✔ | ✘ |
Debug-Protokolle ohne Neukompilierung, Leistungsstatistikprotokoll, Zugriff auf HTTP-Streaming-Parameter | ✔ | ✘ |
Option zum Bereitstellen von Dateien mit integriertem HTTP-Server | ✔ | ☹ Nur reguläre Dateien |
Signalisierung über den Stream-Status auf GPIO mit libgpiod | ✔ | ✘ |
Zugriff auf Webcam-Steuerungen (Fokus, Servos) und Einstellungen wie Helligkeit über HTTP | ✘ | ✔ |
Kompatibilität mit der API von mjpg-streamer | ✔ | :) :) |
Fußnoten:
1
Lange vor µStreamer habe ich einen Patch erstellt, um DV-Timings-Unterstützung für mjpg-streamer hinzuzufügen und zu verhindern, dass er beim Trennen der Geräteverbindung hängen bleibt. Leider ist der Patch alles andere als perfekt und ich kann nicht garantieren, dass er jedes Mal funktioniert – der Quellcode von mjpg-streamer ist sehr kompliziert und seine Struktur ist schwer zu verstehen. Vor diesem Hintergrund und angesichts der Notwendigkeit, in Zukunft Multithreading und JPEG-Hardwarebeschleunigung zu benötigen, habe ich beschlossen, meinen eigenen Stream-Server von Grund auf zu erstellen, anstatt alten Code zu unterstützen.
2
Diese Funktion ermöglicht es, den ausgehenden Datenverkehr beim HDMI-Streaming um ein Vielfaches zu reduzieren, erhöht jedoch die CPU-Auslastung ein wenig. Die Idee dahinter ist, dass HDMI eine vollständig digitale Schnittstelle ist und jedes erfasste Bild byteweise mit dem vorherigen identisch sein kann. Es ist nicht nötig, dasselbe Bild mehrmals pro Sekunde über das Internet zu streamen. Wenn die Option --drop-same-frames=20
aktiviert ist, verwirft µStreamer alle passenden Frames (mit einem Limit von 20 hintereinander). Jeder neue Frame wird zuerst nach Länge und dann mit memcmp()
mit dem vorherigen abgeglichen.
Wenn Sie von Ihrer Hinterhof-Webcam aus live streamen und diese steuern müssen, verwenden Sie mjpg-streamer. Wenn Sie ein qualitativ hochwertiges Bild mit hohen FPS benötigen – µStreamer für den Sieg.
Sie müssen den µStreamer auf Ihr System herunterladen und ihn aus den Quellen erstellen.
Sie benötigen make
, gcc
, libevent
mit pthreads
Unterstützung, libjpeg9
/ libjpeg-turbo
und libbsd
(nur für Linux).
sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd
.sudo apt install libevent-dev libjpeg62-turbo libbsd-dev
. Fügen Sie libgpiod-dev
für WITH_GPIO=1
und libsystemd-dev
für WITH_SYSTEMD=1
und libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev
für WITH_JANUS=1
hinzu.libjpeg62-turbo
durch libjpeg62-turbo-dev
ersetzen.sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev
.sudo apk add libevent-dev libbsd-dev libjpeg-turbo-dev musl-dev
. Erstellen Sie mit WITH_PTHREAD_NP=0
. Um die GPIO-Unterstützung zu aktivieren, installieren Sie libgpiod und übergeben Sie die Option WITH_GPIO=1
. Wenn der Compiler eine fehlende Funktion pthread_get_name_np()
(oder ähnliches) meldet, fügen Sie die Option WITH_PTHREAD_NP=0
hinzu (standardmäßig aktiviert). Für den ähnlichen Fehler mit setproctitle()
fügen Sie die Option WITH_SETPROCTITLE=0
hinzu.
Am bequemsten ist es, das µStreamer-Git-Repository auf Ihr System zu klonen. Wenn Sie Git nicht installiert haben und es auch nicht installieren möchten, können Sie die Quellen von GitHub mit wget https://github.com/pikvm/ustreamer/archive/refs/heads/master.zip
herunterladen und entpacken .
$ git clone --depth=1 https://github.com/pikvm/ustreamer
$ cd ustreamer
$ make
$ ./ustreamer --help
Vorausgesetzt, Sie haben einen µStreamer-Klon wie oben beschrieben, können Sie µStreamer wie folgt aktualisieren.
$ cd ustreamer
$ git pull
$ make clean
$ make
Für die M2M-Hardwarekodierung auf dem Raspberry Pi benötigen Sie mindestens den Kernel 5.15.32. Die Unterstützung von OpenMAX und MMAL auf älteren Kerneln ist veraltet und wurde entfernt.
Ohne Argumente versucht ustreamer
, /dev/video0
mit einer Auflösung von 640 x 480 zu öffnen und das Streaming auf http://127.0.0.1:8080
zu starten. Sie können dieses Verhalten mit den Parametern --device
, --host
und --port
außer Kraft setzen. Um beispielsweise in die Welt zu streamen, führen Sie Folgendes aus:
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
❗ Bitte beachten Sie, dass seit µStreamer v2.0 domänenübergreifende Anfragen aus Sicherheitsgründen standardmäßig deaktiviert sind. Um das alte Verhalten zu aktivieren, verwenden Sie die Option --allow-origin=*
.
Die empfohlene Methode zum Ausführen von µStreamer mit einem TC358743-basierten Erfassungsgerät auf Raspberry Pi:
$ ./ustreamer
--format=uyvy # Device input format
--encoder=m2m-image # Hardware encoding on V4L2 M2M driver
--workers=3 # Workers number
--persistent # Suppress repetitive signal source errors (for example when HDMI cable was disconnected)
--dv-timings # Use DV-timings
--drop-same-frames=30 # Save the traffic
❗ Bitte beachten Sie, dass Sie zur Verwendung --drop-same-frames
für verschiedene Browser einige spezifische URL- /stream
Parameter verwenden müssen (siehe URL /
für Details).
Sie können die vollständige Liste der Optionen jederzeit mit ustreamer --help
anzeigen.
Fügen Sie die folgenden Zeilen zu /boot/firmware/usercfg.txt hinzu:
gpu_mem=128
dtoverlay=tc358743
Überprüfen Sie die Größe des CMA:
$ dmesg | grep cma-reserved
[ 0.000000] Memory: 7700524K/8244224K available (11772K kernel code, 1278K rwdata, 4320K rodata, 4096K init, 1077K bss, 281556K reserved, 262144K cma-reserved)
Wenn es kleiner als 128 MB ist, fügen Sie Folgendes zu /boot/firmware/cmdline.txt hinzu:
cma=128M
Änderungen speichern und neu starten.
Startcontainer:
$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest
Greifen Sie dann auf das Webinterface über Port 8080 zu (z. B. http://raspberrypi.local:8080).
$ docker run --rm pikvm/ustreamer:latest
--format=uyvy
--workers=3
--persistent
--dv-timings
--drop-same-frames=30
Fügen Sie -e EDID=1
hinzu, um HDMI EDID festzulegen, bevor Sie ustreamer starten. Verwenden Sie es zusammen mit -e EDID_HEX=xx
um benutzerdefinierte EDID-Daten anzugeben.
Beispielverwendung für die Raspberry Pi v3-Kamera (erforderliches libcamerify
, das sich in libcamera-tools
und libcamera-v4l2
(beide installieren) auf Raspbian befindet):
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
Für v2-Kameras können Sie den gleichen Trick mit libcamerify
verwenden, aber den Legacy-Kameramodus in raspi-config
aktivieren.
Beispielanwendung für die Raspberry Pi v1-Kamera:
$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944
❗ Bitte beachten Sie, dass neuere Kameramodelle eine andere maximale Auflösung haben. Die unterstützten Auflösungen können Sie der PiCamera-Dokumentation entnehmen.
❗ Wenn Sie eine schlechte Bildrate erhalten, kann es sein, dass die Kamera in den Fotomodus wechselt, der eine niedrige Bildrate (aber ein Bild mit höherer Qualität) erzeugt. Dies liegt daran, dass bcm2835-v4l2
bei Auflösungen über 1280x720
in den Fotomodus wechselt. Um dies zu umgehen, übergeben Sie die Modulparameter max_video_width
und max_video_height
wie folgt:
$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer unterstützt bandbreiteneffizientes Streaming mithilfe der H.264-Komprimierung und des Janus WebRTC-Servers. Ausführliche Informationen finden Sie im Janus-Integrationsleitfaden.
Wenn sich uStreamer hinter einem Nginx-Proxy befindet, führt sein Pufferverhalten zu Latenz im Videostream. Es ist möglich, die Pufferung von Nginx zu deaktivieren, um die zusätzliche Latenz zu vermeiden:
location /stream {
postpone_output 0;
proxy_buffering off ;
proxy_ignore_headers X-Accel-Buffering;
proxy_pass http://ustreamer;
}
v4l2-Dienstprogramme stellen die Tools zum Verwalten der USB-Webcam-Einstellungen und -Informationen bereit. Mithilfe von Skripten können Anpassungen vorgenommen und manuell oder mit cron ausgeführt werden. Laufen Sie in Cron, um beispielsweise die Belichtungseinstellungen zu bestimmten Tageszeiten zu ändern. Das Paket ist in allen Linux-Distributionen verfügbar und heißt normalerweise v4l-utils
.
v4l2-ctl --list-devices
.v4l2-ctl -d /dev/video0 --list-ctrls
.v4l2-ctl -d /dev/video0 --list-formats-ext
.v4l2-ctl -d /dev/video0 --get-ctrl=exposure_auto
.v4l2-ctl -d /dev/video0 --set-ctrl=exposure_auto=1
. Hier finden Sie weitere Beispiele. Die Dokumentation ist in man v4l2-ctl
verfügbar.
Copyright (C) 2018-2024 von Maxim Devaev [email protected]
Dieses Programm ist freie Software: Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, entweder Version 3 der Lizenz oder (nach Ihrer Wahl) einer späteren Version weiterverbreiten und/oder ändern.
Dieses Programm wird in der Hoffnung verbreitet, dass es nützlich ist, jedoch OHNE JEGLICHE GARANTIE; ohne die stillschweigende Garantie der MARKTGÄNGIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK. Weitere Einzelheiten finden Sie in der GNU General Public License.
Sie sollten zusammen mit diesem Programm eine Kopie der GNU General Public License erhalten haben. Wenn nicht, siehe https://www.gnu.org/licenses/.