µStreamer est un serveur léger et très rapide pour diffuser des vidéos MJPEG depuis n'importe quel appareil V4L2 vers le net. Tous les nouveaux navigateurs prennent en charge nativement ce format vidéo, ainsi que la plupart des lecteurs vidéo tels que mplayer, VLC, etc. µStreamer fait partie du projet PiKVM conçu pour diffuser des données matérielles de screencast VGA et HDMI avec la plus haute résolution et FPS possibles.
µStreamer est très similaire à mjpg-streamer avec les plugins input_uvc.so
et output_http.so
, cependant, il existe quelques différences majeures. Les principaux sont :
Fonctionnalité | µStreamer | mjpg-streamer |
---|---|---|
Encodage JPEG multithread | ✔ | ✘ |
Encodage d'image matériel sur Raspberry Pi | ✔ | ✘ |
Comportement lorsque l'appareil est déconnecté pendant la diffusion | ✔ Affiche un écran noirNO SIGNAL dessusjusqu'à ce qu'il soit reconnecté | ✘ Arrête le streaming 1 |
Prise en charge des timings DV - la possibilité de changer la résolution à la volée par signal source | ✔ | ☹ Partiellement oui 1 |
Option pour sauter des images lors de la diffusion images statiques par HTTP pour économiser le trafic | ✔ 2 | ✘ |
Streaming via socket de domaine UNIX | ✔ | ✘ |
Activation du socket système | ✔ | ✘ |
Journaux de débogage sans recompilation, journal des statistiques de performances, accès aux paramètres de streaming HTTP | ✔ | ✘ |
Option pour servir des fichiers avec un serveur HTTP intégré | ✔ | ☹ Fichiers réguliers uniquement |
Signalisation sur l'état du flux sur GPIO en utilisant libgpiod | ✔ | ✘ |
Accès aux commandes de la webcam (focus, servos) et des paramètres tels que la luminosité via HTTP | ✘ | ✔ |
Compatibilité avec l'API de mjpg-streamer | ✔ | :) |
Notes de bas de page :
1
Bien avant µStreamer, j'ai créé un patch pour ajouter la prise en charge des timings DV à mjpg-streamer et l'empêcher de raccrocher lors de la déconnexion de l'appareil. Hélas, le patch est loin d'être parfait et je ne peux pas garantir qu'il fonctionnera à chaque fois - le code source de mjpg-streamer est très compliqué et sa structure est difficile à comprendre. Dans cet esprit, et en plus d'avoir besoin du multithreading et de l'accélération matérielle JPEG à l'avenir, j'ai décidé de créer mon propre serveur de flux à partir de zéro au lieu de prendre en charge le code existant.
2
Cette fonctionnalité permet de réduire de plusieurs fois le trafic sortant lors du streaming HDMI, mais elle augmente un peu l'utilisation du processeur. L'idée est que HDMI est une interface entièrement numérique et que chaque image capturée peut être identique à la précédente en termes d'octets. Il n'est pas nécessaire de diffuser la même image sur le net plusieurs fois par seconde. Avec l'option --drop-same-frames=20
activée, µStreamer supprimera toutes les images correspondantes (avec une limite de 20 d'affilée). Chaque nouvelle image est mise en correspondance avec la précédente d'abord par sa longueur, puis en utilisant memcmp()
.
Si vous souhaitez diffuser en direct depuis la webcam de votre jardin et que vous devez la contrôler, utilisez mjpg-streamer. Si vous avez besoin d'une image de haute qualité avec un FPS élevé - µStreamer pour gagner.
Vous devez télécharger le µStreamer sur votre système et le construire à partir des sources.
Vous aurez besoin make
, gcc
, libevent
avec le support pthreads
, libjpeg9
/ libjpeg-turbo
et libbsd
(uniquement pour Linux).
sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd
.sudo apt install libevent-dev libjpeg62-turbo libbsd-dev
. Ajoutez libgpiod-dev
pour WITH_GPIO=1
et libsystemd-dev
pour WITH_SYSTEMD=1
et libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev
pour WITH_JANUS=1
.libjpeg62-turbo
par libjpeg62-turbo-dev
.sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev
.sudo apk add libevent-dev libbsd-dev libjpeg-turbo-dev musl-dev
. Construisez avec WITH_PTHREAD_NP=0
. Pour activer la prise en charge GPIO, installez libgpiod et transmettez l'option WITH_GPIO=1
. Si le compilateur signale une fonction manquante pthread_get_name_np()
(ou similaire), ajoutez l'option WITH_PTHREAD_NP=0
(elle est activée par défaut). Pour une erreur similaire avec setproctitle()
ajoutez l'option WITH_SETPROCTITLE=0
.
Le processus le plus pratique consiste à cloner le référentiel µStreamer Git sur votre système. Si Git n'est pas installé et que vous ne souhaitez pas l'installer non plus, vous pouvez télécharger et décompresser les sources de GitHub en utilisant wget https://github.com/pikvm/ustreamer/archive/refs/heads/master.zip
.
$ git clone --depth=1 https://github.com/pikvm/ustreamer
$ cd ustreamer
$ make
$ ./ustreamer --help
En supposant que vous disposez d'un clone de µStreamer comme indiqué ci-dessus, vous pouvez mettre à jour µStreamer comme suit.
$ cd ustreamer
$ git pull
$ make clean
$ make
Pour l’encodage matériel M2M sur Raspberry Pi, vous avez besoin d’au moins le noyau 5.15.32. La prise en charge d'OpenMAX et MMAL sur les anciens noyaux est obsolète et supprimée.
Sans arguments, ustreamer
tentera d'ouvrir /dev/video0
avec une résolution de 640x480 et démarrera la diffusion sur http://127.0.0.1:8080
. Vous pouvez remplacer ce comportement en utilisant les paramètres --device
, --host
et --port
. Par exemple, pour diffuser dans le monde entier, exécutez :
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
❗ Veuillez noter que depuis µStreamer v2.0, les requêtes inter-domaines ont été désactivées par défaut pour des raisons de sécurité. Pour activer l'ancien comportement, utilisez l'option --allow-origin=*
.
La méthode recommandée pour exécuter µStreamer avec un périphérique de capture basé sur TC358743 sur 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
❗ Veuillez noter que pour utiliser --drop-same-frames
pour différents navigateurs, vous devez utiliser certains paramètres URL /stream
spécifiques (voir URL /
pour plus de détails).
Vous pouvez toujours consulter la liste complète des options avec ustreamer --help
.
Ajoutez les lignes suivantes à /boot/firmware/usercfg.txt :
gpu_mem=128
dtoverlay=tc358743
Vérifiez la taille de la RMR :
$ 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)
S'il est inférieur à 128 Mo, ajoutez ce qui suit à /boot/firmware/cmdline.txt :
cma=128M
Enregistrez les modifications et redémarrez.
Démarrer le conteneur :
$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest
Accédez ensuite à l'interface Web sur le port 8080 (par exemple http://raspberrypi.local:8080).
$ docker run --rm pikvm/ustreamer:latest
--format=uyvy
--workers=3
--persistent
--dv-timings
--drop-same-frames=30
Ajoutez -e EDID=1
pour définir HDMI EDID avant de démarrer ustreamer. À utiliser avec -e EDID_HEX=xx
pour spécifier des données EDID personnalisées.
Exemple d'utilisation pour la caméra Raspberry Pi v3 ( libcamerify
requis qui se trouve dans libcamera-tools
et libcamera-v4l2
(installer les deux) sur Raspbian) :
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
Pour la caméra v2, vous pouvez utiliser la même astuce avec libcamerify
mais activer le mode caméra hérité dans raspi-config
.
Exemple d'utilisation pour la caméra Raspberry Pi v1 :
$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944
❗ Veuillez noter que les modèles de caméras les plus récents ont une résolution maximale différente. Vous pouvez voir les résolutions prises en charge dans la documentation PiCamera.
❗ Si vous obtenez un framerate faible, il se peut que l'appareil photo passe en mode photo, ce qui produit un framerate faible (mais une image de meilleure qualité). En effet, bcm2835-v4l2
passe en mode photo à des résolutions supérieures à 1280x720
. Pour contourner ce problème, transmettez les paramètres de module max_video_width
et max_video_height
comme ceci :
$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer prend en charge le streaming économe en bande passante grâce à la compression H.264 et au serveur Janus WebRTC. Consultez le guide d'intégration Janus pour plus de détails.
Lorsque uStreamer se trouve derrière un proxy Nginx, son comportement de mise en mémoire tampon introduit une latence dans le flux vidéo. Il est possible de désactiver le buffering de Nginx pour éliminer la latence supplémentaire :
location /stream {
postpone_output 0;
proxy_buffering off ;
proxy_ignore_headers X-Accel-Buffering;
proxy_pass http://ustreamer;
}
Les utilitaires v4l2 fournissent les outils nécessaires pour gérer les paramètres et les informations de la webcam USB. Les scripts peuvent être utilisés pour effectuer des ajustements et exécutés manuellement ou avec cron. Exécuter cron par exemple pour modifier les paramètres d'exposition à certaines heures de la journée. Le package est disponible dans toutes les distributions Linux et est généralement appelé 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
. Ici vous pouvez trouver plus d’exemples. La documentation est disponible dans man v4l2-ctl
.
Copyright (C) 2018-2024 par Maxim Devaev [email protected]
Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le modifier selon les termes de la licence publique générale GNU telle que publiée par la Free Software Foundation, soit la version 3 de la licence, soit (à votre choix) toute version ultérieure.
Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de QUALITÉ MARCHANDE ou d’ADAPTATION À UN USAGE PARTICULIER. Voir la licence publique générale GNU pour plus de détails.
Vous devriez avoir reçu une copie de la licence publique générale GNU avec ce programme. Sinon, consultez https://www.gnu.org/licenses/.