Transmisión de video cómo su Raspberry Pi dependía de ella

Fernando Román
Fernando Román

La Raspberry Pi es una plataforma informática increíblemente versátil, especialmente cuando se trata de programas integrados. Se utilizan en todo tipo de proyectos de seguridad y control para realizar tomas fijas a lo largo del tiempo o para grabar videos para su posterior revisión. Es muy fácil y hay una amplia variedad de herramientas disponibles para realizar el trabajo.

Sin embargo, si necesita un video en vivo con la menor latencia posible, las cosas se ponen más difíciles. Construí un vehículo a control remoto que usa la red de datos celulares para comunicarse. Minimizar la latencia fue clave para facilitar el vehículo. Así que conduje hasta el motor de búsqueda más cercano y comencé a investigar mi problema.

Mi primer acercamiento al desafío fue el venerable VLC Media Player. Desafortunadamente, los experimentos iniciales estuvieron plagados de problemas. Lograr que la aplicación reconociera la cámara web conectada a mi Pi Zero se prolongó para siempre, y cuando finalmente comencé la transmisión, fue demasiado lento para ser útil. Transmitir a través de WiFi y estrechar mis manos frente a la cámara mostró que tengo un retraso de al menos dos o tres segundos. Si bien podría optimizarlo aún más, decidí seguir adelante e intentar encontrar algo un poco más ligero.

Transmisión nativa MJPEG: si su red es rápida

La siguiente herramienta de transmisión a la que recurrí fue Microsoft Lifecam VX-2000, que ofrece de forma nativa una salida MJPEG con una resolución de hasta 640 × 480. Esto me llevó a una herramienta conocida como MJPEGStreamer. Al utilizar una herramienta dedicada a la transmisión en ese formato, evitaría cualquier transcodificación del video de la cámara web que requiera mucho tiempo y que podría introducir latencia en la transmisión. Al principio parecía que esta podría ser una solución perfecta a mis problemas. Una vez instalado en Raspberry Pi, se puede acceder a MJPEGstreamer de forma remota a través de una interfaz de Internet en la que presenta la transmisión.

Para medir la latencia, descargué un programa de cronómetro en mi teléfono. Sostuve el teléfono junto a la pantalla que muestra la transmisión de video a través de WiFi. Luego, filmando el teléfono y la transmisión con otra cámara, pude verificar la grabación y ver la diferencia entre la hora en el cronómetro y la hora que se muestra en la transmisión.

La latencia fue inferior a 500 ms, lo que consideré aceptable. Sin embargo, hubo un problema. MJPEGstreamer no manejaba bien las conexiones de baja velocidad. El software insistió en enviar cada fotograma, por lo que si la conexión llegaba a un punto difícil, MJPEGstreamer esperaría hasta que se enviaran los fotogramas. Esto significaba que, si bien la latencia inicial era de 500 ms, explotaría durante unos segundos en solo unos minutos de ejecución de la transmisión. Esto simplemente no funcionaría, así que reanudé mi búsqueda.

Gstreamer es la navaja suiza del webcasting

Finalmente encontré un beneficio llamado Gstreamer. Es una verdadera navaja suiza de herramientas de transmisión de video, envuelta en un servidor de línea de comandos arcano. Gstreamer se configura mediante “pipelines”, que son una serie de comandos que especifican dónde obtener un video, cómo procesarlo y codificarlo, y luego dónde enviarlo. Para comprender cómo funciona esto, echemos un vistazo a las canalizaciones que usé en mi programa de baja latencia a continuación.

Veamos primero el aspecto de Raspberry Pi. Aquí está el comando GStreamer que utilicé:

gst-launch -v v4l2src ! "image/jpeg,width=160,height=120,framerate=30/1" ! rtpjpegpay ! udpsink host=192.168.2.3 port=5001

Dividamos esto en secciones. “Gst-launch” se refiere al gstreamer en ejecución. La “-v” habilita un modo de varias palabras que le dice a Gstreamer que nos diga absolutamente todo lo que está sucediendo. Es útil cuando intenta resolver una secuencia que no funciona. “V4l2src” le dice a Gstreamer que queremos que capture un video de una fuente de captura de video, en nuestro caso, una cámara web usando los controladores Video4Linux2. La siguiente sección indica que queremos capturar los fotogramas JPEG directamente desde la cámara a una resolución de 160 × 120, con 30 fotogramas por segundo. “Rtpjpegpay” codifica los fotogramas JPEG en paquetes RTP. RTP significa “Protocolo de transporte en tiempo real” y es un estándar para transmitir audio y video a través de redes IP. Finalmente, el comando “udpsink” indica que queremos enviar el flujo RTP a través de la conexión UDP al host en 192.168.2.3 en el puerto 5001.

Ahora veamos el final aceptable de las cosas. Para ver la transmisión, utilicé una computadora portátil con Windows 10 y la prueba inicial se realizó a través de WiFi. Aquí está la tubería:

gst-launch-1.0.exe -e -v udpsrc port=5001 ! application/x-rtp, encoding-name=JPEG, payload=26 ! rtpjpegdepay ! jpegdec ! autovideosink

gst-launch-1.0.exe se refiere al ejecutable, y el modificador “-v” funciona de manera similar aquí. “-E” le dice a la máquina remota que deje de enviar un video cuando dejamos de ver la transmisión. Esta vez usamos “udpsrc” porque queremos tomar el flujo RTP que viene en el puerto 5001. Tenemos que decirle a Gstreamer que está viendo el flujo RTP en formato JPEG, que es el nombre de la codificación del programa, y ​​los comandos de carga útil lo hacen. “Rtpjpegdepay” luego descomprime el flujo RTP en cuadros JPEG individuales, que luego se descifran con “jpegdec” y se envían a la pantalla a través de “autovideosink”.

Esto puede parecer simple, pero se necesita mucha experimentación para iniciar una canalización en ambos extremos. A menudo puede resultar muy confuso averiguar si algo se está enviando o recibiendo. Algo tan simple como usar una computadora receptora con una tarjeta gráfica diferente puede detener por completo el funcionamiento de una tubería y se necesitarán varios complementos o videos. Tuve este problema cuando mi computadora portátil cambió entre sus tarjetas gráficas Intel y NVIDIA. Afortunadamente, los complementos como “videotestsrc” y “testsink” pueden usarse para solucionar problemas.

Gstreamer en la práctica

En general, el rendimiento es excelente. La latencia medida fue constantemente inferior a 300 ms, incluso al cambiar a una conexión de datos móviles 4G. En un buen día, puedo usar la transmisión cómodamente con una resolución de hasta 320 × 240 sin ningún problema. Sospecho que el envío de cuadros JPEG es muy ineficaz y, en su lugar, me gustaría intentar enviar el flujo H264.

La resolución de la transmisión es muy baja, pero muy útil para pilotaje remoto, pero requiere una resolución mejorada.

Si bien algunas Raspberry Pis tienen codificación de dispositivo H264 a bordo, preferiría comenzar con una transmisión nativa para obtener el máximo rendimiento. Pedí una cámara 1080P que usa la interfaz de la cámara Pi y no puedo esperar para comenzar a experimentar.

Básicamente, Gstreamer ha demostrado ser la herramienta adecuada para el trabajo por muchas razones. Primero, es de código abierto y se basa en una arquitectura complementaria muy flexible. En segundo lugar, es liviano y deja caer cuadros fácilmente, por lo que el receptor siempre muestra la imagen más reciente. Es difícil comprenderlo, pero cuando funciona, funciona.

Para obtener un tutorial más detallado sobre cómo configurar Gstreamer con varios diseños, puedo recomendar este artículo de Einar Sundgren, quien me enseñó mucho sobre lo que necesitaba saber. A continuación adjunto un video de mis vehículos lejanos, cortesía del Pi Zero, Gstreamer y largas noches codificadas con unas cervezas frías.

Por último, también me encantaría saber de la comunidad en general: ¿cuál es su forma favorita de ejecutar una transmisión de cámara web con poca latencia con la Raspberry Pi? ¡Cuéntanos en los comentarios a continuación!

  • ALINOME el A dice:

    Es este pequeño proyecto llamado Wifibroadcast que usa Pi con su cámara y transmite a través de WiFi en modo monitor …
    Pude alcanzar los 200 ms cuando estaba mirando con una computadora portátil y es aún más rápido si el otro extremo es otro Pi y la pantalla no almacena la imagen en búfer, la decodificación / codificación GPU HW ofrece una latencia muy baja …

    • ALINOME el A dice:

      Tu imagen es fea no por la resolución, sino por la fea óptica.
      Si compras una cámara Pi, obtén la que tiene lentes grandes (tienen un delicado hilo M12, las cámaras de seguridad usan estas lentes), la pequeña tiene una luz terriblemente tenue.

      • Alex dice:

        ¿Está apuntando a cámaras Pi específicas o cámaras USB en general? ¿Algún enlace sugerido?

        • Simón dice:

          Espero que AKA-la-A signifique uno de estos clones de módulos de cámara pi con la montura m12 y una lente medio decente (esto es NoIR):

          https://www.aliexpress.com/item/RPI-2camera-Raspberry-Pi-2-lens-Fisheye-Lens-5-megapixel-OV5647-sensor-1080p-camera-module-compatible/32422488470.html

  • Jon dice:

    ¿Qué es una “frambuesa”? 😉

    • Ostraco dice:

      Computadora con ritmo.

    • Pixel_K dice:

      Es un dispositivo compatible con RunDMC

      • Elliot Williams dice:

        También es un error tipográfico fijo.

        (Pero debido al hilo, continúe como si la columna todavía estuviera leyendo “Rapberry”, estamos disfrutando los chistes).

    • dustin evans (@dl_evans) dice:

      En el sur de Gales nació en la escuela secundaria
      En las elecciones es donde pasó sus primeros días
      Ahora está en manos de niños muy amplios
      Conectado a robots con cámaras web, no se esconde en ningún lugar

  • CRImier dice:

    Recomiendo encarecidamente usar las cámaras Raspberry Pi para esto, debido a la codificación acelerada por hardware, los complementos disponibles para las herramientas de video más populares y su principio “simplemente funciona” en general. Aparte de eso, las cámaras Logitech generalmente también “simplemente funcionan” para mí, y si necesito un micrófono incorporado, este suele ser el camino a seguir.

    Por cierto, eche un vistazo a v4l2-ctl, es una herramienta de línea de comandos que le permite configurar los parámetros internos de su cámara (exposición, brillo, compensación de potencia, enfoque si no es automático y cosas similares). A veces realmente puede marcar la diferencia =)

    • Tago Lewin dice:

      ¡Gracias por el consejo! Tuve un poco de tintineo con v4l2-ctl, porque cuando conecté mi cámara por primera vez, no funcionó, mostrando solo una imagen plana en blanco. ¡Solo después de arrancarme el cabello me di cuenta de que estaba demasiado expuesto!

  • anfitrión local dice:

    También necesitaba una línea de vida para un automóvil controlado a distancia, pero tenía que ser multiplataforma y fácil de configurar (por lo que no había programas / herramientas para instalar y configurar), y terminé modificando un proyecto que encontré en Github. Utiliza HTML5, bolsas web para la transmisión en tiempo real y un decodificador de video compilado por asm.js (el elemento de video HTML5 es demasiado lento).
    Enlace al proyecto original para todos los interesados: https://github.com/131/h264-live-player

    • Tago Lewin dice:

      Iiiiiiiiinteresa. Me encantaría jugar con eso y ver cómo maneja los videos en 4G.

  • jeanleflambeur dice:

    “Mientras que algunas Raspberry Pis tienen codificación de hardware H264 a bordo”
    Todos los modelos de Raspberry Pi tienen un código duro H.264 integrado. Es una de las cosas que la convierte en la plataforma preferida para la transmisión de videos.

    • Tago Lewin dice:

      Estaba seguro de que la serie principal fue un éxito, pero no pude imaginarlo para Zero. Gracias por la info!

  • jl dice:

    FFMPEG viene a mi cabeza. No lo usé para transmitir, pero recuerda leer sobre él.

  • Athar dice:

    ¡Una buena comparación de varios protocolos de flujo que me confundieron! Entonces Gstreamer es el ganador.

    Ahora, si realmente quieres comprar barato, ¿qué tal si usas $ 5/9 Omega2 / + (64/128 MB de RAM y 16/32 MB de almacenamiento con OpenWrt, sin costo SD) con $ 7 PS3Eye (de Amazon) que solo genera YUV pero no marcos Mjpeg, como el dispositivo de origen que se transmite a través de WiFi a RPi u otro capaz dispositivo.

    Primero, Omega2 tendrá que codificar YUV a h264 / jpeg para la transmisión, lo que requiere que su CPU MIPS de 580Mhz trabaje duro. Siguiente Gstreamer hará que la transmisión RTP / UDP a través de su WiFi habilitado. Omega2 tiene pines D + / D para la conexión USB al PS3EYE. Ambos pueden compartir una fuente de alimentación con $ 3.3V para Omega2.

    ¿Es posible arriba? ¿Qué enrutamiento WiFi se necesita con qué salidas aproximadas?

    ¿Cuáles son la velocidad de fotogramas y la resolución posibles, por ejemplo? 240x 120 o más?

    • CRImier dice:

      Incluso MJPEG en una CPU de este tipo está comenzando a ser doloroso, desafortunadamente, al menos la última vez que lo probé. Pero tengo que decir: ¡adelante, pruébalo! Elegiría algo como una placa de desarrollo basada en procesadores de cámaras de seguridad, pero no creo que tengan tanto soporte para las funciones de codificación de sus dispositivos, al menos no como controladores de código abierto (a diferencia de los blobs binarios, creo que de esos)

  • Concordia dice:

    Cuando construí mi sistema HD FPV para mi helicóptero hexadecimal, usé el RPI con su cámara a través de wifi. Tengo una latencia de aproximadamente 70 ms usando raspivid sobre netcat para mplayer. No está mal solo para volar haciendo fotografías, pero sigue siendo demasiado rápido para volar rápido. Rompí una locomotora UBNT M5 (5Ghz) para alimentar mi estación terrestre, que ejecuta Linux en una computadora portátil. De mis notas:

    Laptop Prime:
    Raspivid -vs -n -w 1024 -h 576 -t 0 -b 5000000 -o – | nc.tradicia 192.168.1.145 5000 y

    Luego de RPI (FPV):
    Nc.traditional -l -p 5000 | mplayer -noautosub -noass -nosound -framedrop -nocorrect-pts -nocache -fps 60 -demuxer h264es –

    Por supuesto, ingrese su IP apropiada. Mi última pieza del rompecabezas después de hacer esto con scripts y python / perl fue reescribir la red para conectarse automáticamente, porque primero tenía que ingresar los comandos portátiles para ingresar al modo de monitor, luego conectarse desde RPI. Siempre se burló de mí que no pudieras revertir la conexión en netcat.

    Luego compré DJI Maviko, y bueno … Ese proyecto se detuvo. jajaja

  • Dave dice:

    Una cámara CCTV IP sería un punto de partida mucho mejor.
    wifi está disponible.
    Mejor óptica
    Dirigido a baja latencia en transmisión en vivo
    Codificación de hardware h264 o h265
    Puertos de E / S
    algunos incluso tienen una salida de telemetría en 485/232, así que ya sabes, podrías controlar algo en 3 ejes con un joystick …

    Armado con un RPi, todo parece un clavo. O algo así.

    • Tago Lewin dice:

      La razón por la que uso la Raspberry Pi para esto es porque también maneja la conducción del automóvil: se hace cargo de los comandos a través de la conexión de datos 4G, dispara el motor y controla el servicio de conducción.

    • Tago Lewin dice:

      ¿Las cámaras de CCTV están optimizadas para la latencia? No puedo imaginar que al usuario medio de cámaras de seguridad le importe si sus imágenes se retrasan entre 200 y 500 ms.

  • dmac dice:

    así que también hago algo así con un vehículo de investigación, usando un joystick para controlarlo.
    Aquí están mis configuraciones de transmisión que parecen funcionar bien:
    remitente:
    rasposo -n -t 0 -w 640 -h 480 -fps 10 -b 1000000 -o – | gst-launch-1.0 -e -vvvv fdsrc! h264parse! rtph264pay pt = 96 rango de configuración = 5! udpsink host = 192.168.1.16 puerto = 9000
    receptor:
    e: gstreamer 1.0 x86_64 bin gst-launch-1.0.exe udpsrc-port = 9000! application / x-rtp, codename = H264, payload = 96! rtph264depay! avdec_h264! ¡convertir vídeo! autovideosink

    Tengo el código del concepto de prueba aquí https://github.com/Neodymium60/piborg-mqtt
    Aún quedan muchas cosas por hacer

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *