VideoWall de vigilancia con OpenVidu (parte 1)

Hoy hablamos de un proyecto que conceptualmente era bueno y «sencillo», pero que una vez en producción nos supone varios retos.

Si disponemos de un montón de cámaras de vigilancia IP en una ciudad, sabemos su localización GPS es en principio «fácil» desarrollar una aplicación web que nos muestre las N cámaras más cercanas a una posición GPS. Pero cuando hablamos de media delivery siempre hay pequeños detalles que pueden complicarnos la vida. 

Las camaras

Este proyecto se basa en un pool de más de mil cámaras IP desplegadas a lo largo y ancho de una ciudad. Estas cámaras son de la propia ciudad y de ciudadanos y negocios que han dado permiso al usuario final para que pueda consumir sus flujos. Estas cámaras por ende son de muy diversa naturaleza (modelo, marca, códecs, ancho de banda disponible…). Para más inri estos parámetros en muchas de las cámaras son completamente desconocidos a priori.  

El proyecto tendrá que soportar el máximo de cámaras disponibles en el mercado y para el resto debe definirse bien la incompatibilidad y que por ejemplo un códec incompatible no tire la plataforma.

Los retos de distribución multimedia

Nos centraremos en los retos de la distribución de media, ya que el resto de los retos que puede suponer manejar cámaras públicas (seguridad, volumen, privacidad, etc.) así como los retos de crear una buena interfaz estaban bajo control y perfectamente abordados por nuestro cliente. 

  • Acceso concurrente a flujos de media
  • Compatibilidad de codecs

Acceso concurrente a los flujos de media.

Algo que muchas veces se nos pasa por alto es que para transmitir media desde una cámara se debe abrir al menos un túnel de comunicaciones para cada cliente/usuario conectado a dicha cámara, esto implica que en caso de que haya 10 clientes/usuarios intentando obtener el flujo de una cámara esta cámara tendrá que ser capaz de tener 10 túneles abiertos y de enviar el media por esos 10 túneles. Esto de por sí ya es complejo y la mayor parte de las cámaras del mercado no soportan tantos flujos concurrentes. Pero lo que es más estos 10 túneles están utilizando el mismo ancho de banda, por lo que la probabilidad de pérdidas de paquetes, retardos, etc. se multiplica por 10. Lo que supone un serio problema por ejemplo si hablamos de cámaras wifi sobre redes domésticas, o GPRS. 

Uno de los principales problemas con este tipo de fallos es que muchas veces se detectan una vez el software se pone en producción ya que funcionalmente no tiene grandes implicaciones hasta que no existen varios usuarios concurrentes. (Porque cuando no tienes en cuenta que la concurrencia puede ser un problema en media tampoco vas a pensar en añadirlo a las pruebas).

Solución

La solución es relativamente sencilla utilizar un servidor multimedia que sea capaz de multiplexar las señales de las cámaras. Este servidor multimedia deberá estar ubicado en una máquina que ofrezca buena capacidad de proceso pero sobre todo un buen ancho de banda. De esta forma la cámara solo emitirá un flujo de media y será nuestro servidor quien haga la multiplexación para cada cliente, es decir mantenga los diferentes túneles por los que hará llegar el media a cada cliente. 

Compatibilidad de codecs

Como hemos dicho las camaras de este proyecto son muchas y muy diversas y soportar absolutamente todas las configuraciones es muy complicado y costoso. Para empezar sabemos que la aplicación es una aplicación web. Los navegadores tienen una compatibilidad limitada para codecs de video. Y por tanto en muchos casos no se puede mostrar directamente el flujo de una cámara en el navegador sino que tenemos que transcodificarlo (“traducirlo”) a un codec que entienda el navegador.  Este proceso de transcodificación es caro a nivel de CPU por lo que la mayoría de las cámaras no son capaces de realizarlo, y simplemente son capaces de enviar los flujos con un codec preestablecido (algunas veces configurable dentro de un rango de codecs).

Solución

En este caso la solución también pasa por utilizar un servidor o proxy que sea capaz de realizar la transcodificación para que el cliente/usuario reciba en su navegador un flujo de video que pueda visualizar. Debido a que el proceso de transcodificación es “caro”, como se ha explicado anteriormente, la máquina que aloje el servidor deberá disponer de una capacidad de procesamiento adecuada al número de flujos simultáneos que puedan existir.

LA SOLUCION

Kurento fue la primera elección para abarcar este proyecto ya que encaja al 100% con el caso de uso (multiplexación de flujos y transcodificación transparente). Aunque tiene unas desventajas:

  • No es fácil de escalar (manejar un cluster de kurentos no es sencillo)
  • Requiere un conocimiento de los componentes de kurento bastante profundo para optimizar su funcionamiento y desarrollo java específico para gestionar los pipelines de Kurento (para añadir en caliente webrtc-endpoints cada vez que se conecte un usuario). 

Desde Naeva Tec se propuso el uso de OpenVidu PRO ya que este corre sobre Kurento pero (i) es capaz de manejar clusters de Kurento de forma transparente para la aplicación cliente y (ii) simplifica el manejo de los flujos de media ya que proporciona un API sencilla por la que se pueden gestionar todos los parámetros necesarios de Kurento para este caso de uso.  

De forma que al final lo que se tenía era una sesión de Openvidu para cada cámara y los usuarios que querían visualizar una cámara lo que realmente estaban haciendo (de forma transparente) es unirse a la sesión de OpenVidu que estaba sirviendo esta cámara.  Con la introducción de OpenVidu Pro las modificaciones necesarias del código original fueron mínimas pero el impacto en el uso muy grande. 

 

Aunque no todo lo que reluce es oro, ya que surgieron nuevos retos relacionados con la calidad del video mostrado. Ver parte 2.