µStreamer es un servidor ligero y muy rápido para transmitir vídeo MJPEG desde cualquier dispositivo V4L2 a la red. Todos los navegadores nuevos tienen soporte nativo para este formato de video, así como la mayoría de los reproductores de video como mplayer, VLC, etc. µStreamer es parte del proyecto PiKVM diseñado para transmitir datos de hardware de screencast VGA y HDMI con la mayor resolución y FPS posibles.
µStreamer es muy similar a mjpg-streamer con los complementos input_uvc.so
y output_http.so
, sin embargo, existen algunas diferencias importantes. Los claves son:
Característica | µserpentina | serpentina-mjpg |
---|---|---|
Codificación JPEG multiproceso | ✔ | ✘ |
Codificación de imágenes por hardware en frambuesa pi | ✔ | ✘ |
Comportamiento cuando el dispositivo está desconectado durante la transmisión | ✔ Muestra una pantalla negraNO SIGNAL hasta que se vuelva a conectar | ✘ Detiene la transmisión 1 |
Soporte de tiempos DV - la capacidad de cambiar la resolución sobre la marcha por señal fuente | ✔ | ☹ Parcialmente sí 1 |
Opción para omitir fotogramas durante la transmisión Imágenes estáticas por HTTP para ahorrar tráfico. | ✔2 | ✘ |
Transmisión a través del socket de dominio UNIX | ✔ | ✘ |
Activación del socket systemd | ✔ | ✘ |
Depurar registros sin recompilar, registro de estadísticas de rendimiento, acceso a los parámetros de transmisión HTTP | ✔ | ✘ |
Opción para servir archivos con un servidor HTTP incorporado | ✔ | ☹ Solo archivos normales |
Señalización sobre el estado de la corriente. en GPIO usando libgpiod | ✔ | ✘ |
Acceso a los controles de la cámara web (enfoque, servos) y configuraciones como el brillo a través de HTTP | ✘ | ✔ |
Compatibilidad con la API de mjpg-streamer | ✔ | :) |
Notas a pie de página:
1
Mucho antes de µStreamer, hice un parche para agregar compatibilidad con tiempos DV a mjpg-streamer y evitar que se cuelgue al desconectar el dispositivo. Lamentablemente, el parche está lejos de ser perfecto y no puedo garantizar que funcione siempre: el código fuente de mjpg-streamer es muy complicado y su estructura es difícil de entender. Con esto en mente, además de necesitar subprocesos múltiples y aceleración de hardware JPEG en el futuro, decidí crear mi propio servidor de transmisión desde cero en lugar de admitir código heredado.
2
Esta característica permite reducir varias veces el tráfico saliente cuando se transmite HDMI, pero aumenta un poco el uso de la CPU. La idea es que HDMI sea una interfaz totalmente digital y cada cuadro capturado pueda ser idéntico al anterior en bytes. No es necesario transmitir la misma imagen a través de la red varias veces por segundo. Con la opción --drop-same-frames=20
habilitada, µStreamer eliminará todos los fotogramas coincidentes (con un límite de 20 seguidos). Cada nuevo cuadro se compara con el anterior primero por longitud y luego usando memcmp()
.
Si vas a transmitir en vivo desde la cámara web de tu patio trasero y necesitas controlarla, usa mjpg-streamer. Si necesita una imagen de alta calidad con FPS alto, gane µStreamer.
Debe descargar µStreamer en su sistema y compilarlo a partir de las fuentes.
Necesitará make
, gcc
, libevent
con soporte pthreads
, libjpeg9
/ libjpeg-turbo
y libbsd
(solo para Linux).
sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd
.sudo apt install libevent-dev libjpeg62-turbo libbsd-dev
. Agregue libgpiod-dev
para WITH_GPIO=1
y libsystemd-dev
para WITH_SYSTEMD=1
y libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev
para WITH_JANUS=1
.libjpeg62-turbo
por 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
. Construir con WITH_PTHREAD_NP=0
. Para habilitar la compatibilidad con GPIO, instale libgpiod y pase la opción WITH_GPIO=1
. Si el compilador informa que falta una función pthread_get_name_np()
(o similar), agregue la opción WITH_PTHREAD_NP=0
(está habilitada de forma predeterminada). Para un error similar con setproctitle()
agregue la opción WITH_SETPROCTITLE=0
.
El proceso más conveniente es clonar el repositorio µStreamer Git en su sistema. Si no tienes Git instalado y tampoco quieres instalarlo, puedes descargar y descomprimir las fuentes de GitHub usando 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
Suponiendo que tiene un clon de µStreamer como se mencionó anteriormente, puede actualizar µStreamer de la siguiente manera.
$ cd ustreamer
$ git pull
$ make clean
$ make
Para la codificación de hardware M2M en Raspberry Pi, necesita al menos el kernel 5.15.32. La compatibilidad con OpenMAX y MMAL en kernels más antiguos está obsoleta y eliminada.
Sin argumentos, ustreamer
intentará abrir /dev/video0
con una resolución de 640x480 y comenzará a transmitir en http://127.0.0.1:8080
. Puede anular este comportamiento utilizando los parámetros --device
, --host
y --port
. Por ejemplo, para transmitir al mundo, ejecute:
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
❗ Tenga en cuenta que desde µStreamer v2.0 las solicitudes entre dominios estaban deshabilitadas de forma predeterminada por razones de seguridad. Para habilitar el comportamiento anterior, use la opción --allow-origin=*
.
La forma recomendada de ejecutar µStreamer con un dispositivo de captura basado en TC358743 en 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
❗ Tenga en cuenta que para usar --drop-same-frames
para diferentes navegadores necesita usar algunos parámetros de URL /stream
específicos (consulte URL /
para obtener más detalles).
Siempre puedes ver la lista completa de opciones con ustreamer --help
.
Agregue las siguientes líneas a /boot/firmware/usercfg.txt:
gpu_mem=128
dtoverlay=tc358743
Verifique el tamaño de 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)
Si es menor que 128 M, agregue lo siguiente a /boot/firmware/cmdline.txt:
cma=128M
Guarde los cambios y reinicie.
Contenedor de inicio:
$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest
Luego acceda a la interfaz web en el puerto 8080 (por ejemplo, http://raspberrypi.local:8080).
$ docker run --rm pikvm/ustreamer:latest
--format=uyvy
--workers=3
--persistent
--dv-timings
--drop-same-frames=30
Agregue -e EDID=1
para configurar HDMI EDID antes de iniciar ustreamer. Úselo junto con -e EDID_HEX=xx
para especificar datos EDID personalizados.
Ejemplo de uso para la cámara Raspberry Pi v3 (se requiere libcamerify
que se encuentra en libcamera-tools
y libcamera-v4l2
(instale ambos) en Raspbian):
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
Para la cámara v2, puede usar el mismo truco con libcamerify
pero habilitar el modo de cámara heredado en raspi-config
.
Ejemplo de uso de la cámara Raspberry Pi v1:
$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944
❗ Tenga en cuenta que los modelos de cámaras más nuevos tienen una resolución máxima diferente. Puede ver las resoluciones admitidas en la documentación de PiCamera.
❗ Si obtiene una velocidad de fotogramas baja, es posible que la cámara esté cambiada al modo de fotografía, lo que produce una velocidad de fotogramas baja (pero una imagen de mayor calidad). Esto se debe a que bcm2835-v4l2
cambia al modo fotografía en resoluciones superiores a 1280x720
. Para solucionar esto, pase los parámetros del módulo max_video_width
y max_video_height
de esta manera:
$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer admite transmisión con ancho de banda eficiente mediante compresión H.264 y el servidor Janus WebRTC. Consulte la guía de integración de Janus para obtener todos los detalles.
Cuando uStreamer está detrás de un proxy Nginx, su comportamiento de almacenamiento en búfer introduce latencia en la transmisión de video. Es posible desactivar el almacenamiento en búfer de Nginx para eliminar la latencia adicional:
location /stream {
postpone_output 0;
proxy_buffering off ;
proxy_ignore_headers X-Accel-Buffering;
proxy_pass http://ustreamer;
}
Las utilidades v4l2 proporcionan las herramientas para administrar la configuración y la información de la cámara web USB. Los scripts se pueden utilizar para realizar ajustes y ejecutarlos manualmente o con cron. Ejecutar cron, por ejemplo, para cambiar la configuración de exposición en ciertos momentos del día. El paquete está disponible en todas las distribuciones de Linux y normalmente se llama 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
. Aquí puedes encontrar más ejemplos. La documentación está disponible en man v4l2-ctl
.
Copyright (C) 2018-2024 de Maxim Devaev [email protected]
Este programa es software libre: puede redistribuirlo y/o modificarlo según los términos de la Licencia Pública General GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia o (a su elección) cualquier versión posterior.
Este programa se distribuye con la esperanza de que sea de utilidad, pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la Licencia pública general de GNU para obtener más detalles.
Debería haber recibido una copia de la Licencia Pública General GNU junto con este programa. De lo contrario, consulte https://www.gnu.org/licenses/.