
Compartir:
Roberto is a Full Stack Engineer on the OpenTok Client SDK team. He loves learning new bits of Android, iOS, Linux, Windows, you name it! In his free time, he is very passionate about programming languages, computer graphics, and video game development for current and old platforms like ZX Spectrum and Commodore 64.
Crea filtros de RA personalizados con la Video API de Vonage y DeepAR
Tiempo de lectura: 12 minutos
La IA aumentada es el futuro de las videollamadas. Nos ayudará a romper el hielo (virtual), a navegar por los nuevos casos de uso del vídeo interactivo, como las compras y la teleasistencia, y a crear experiencias totalmente nuevas. Es probable que los futuros inventores de esas experiencias estén "sentados" en un aula virtual y se estén formando con el vídeo virtual como ninguna generación antes que ellos.
Como desarrolladores de la API de Video de Vonage, pueden integrar nuestra API de Video con el SDK de DeepAR para enriquecer la experiencia de video de tus usuarios.
Puede hacer que las videollamadas sean más profesionales abstrayendo el fondo, sustituyendo, difuminando o pixelando los objetos, o mejorar la experiencia del usuario mejorando la iluminación y los sutiles efectos de tono de piel.
O diviértete aún más con la gran variedad de filtros animados de DeepAR.
Augmented Reality filters in action
Realidad aumentada en nuestra vida cotidiana
Es muy probable que ya hayas participado en una reunión por vídeo, ya sea de trabajo, una consulta médica o un encuentro familiar.
En este nuevo paradigma de reuniones centradas en el vídeo, muchas aplicaciones nuevas pueden añadir valor a la comunicación por vídeo. Repasemos algunas formas habituales en que se está utilizando el aumento para mejorar las experiencias de los usuarios y ayudarnos a ser más eficaces en nuestras interacciones a distancia:
Abstracción del fondo
Una de las mejoras para la comunicación por Video es abstraer todo lo que hay en el fondo del usuario con unas simples funciones de desenfoque, pixelado o reemplazo del fondo. Entre las ventajas se incluyen:
activar la privacidad de las llamadas
facilitar la participación del espectador eliminando distracciones
crear experiencias de marca
Aumentos del altavoz
Otro ejemplo de cómo llevar las videollamadas al siguiente nivel con RA es aplicar filtros a los altavoces en primer plano. Implementar este tipo de filtros permite a tus usuarios:
relájate en la videollamada con filtros de luz, tono de piel y belleza
deleita y divierte con divertidos animojis
interactuar en tiempo real con objetos 3D e incluso con pintura facial virtual
A dog face AR filter in use
La flexibilidad de la Video API de Vonage hace que esto sea posible cuando se integra con socios de RA como DeepAR. En esta entrada de blog, demostraremos cómo hacer posibles los casos de uso anteriores utilizando una combinación de las dos API.
¿Qué es DeepAR?
DeepAR es un motor de RA optimizado para móviles y HTML5 para realidad aumentada, filtros faciales, segmentación de fondos, maquillaje, filtros de belleza y animoji.
El sitio SDK de DeepAR ofrece a los desarrolladores acceso al motor DeepAR, gestiona la compatibilidad entre dispositivos y viene con una herramienta DeepAR Studio para ayudarte a crear los activos de RA.
Uso de DeepAR
Para añadir el framework DeepAR SDK a tu aplicación iOS, tienes que descargar el archivo zip de su página web, https://developer.deepar.ai/. Una vez que tengas el archivo zip, tienes que descomprimirlo y arrastrar el archivo del framework a tu proyecto Xcode.

No olvide establecer la embed del marco de trabajo en "Incrustar y firmar", o es posible que la aplicación no encuentre la biblioteca en tiempo de ejecución.
Una vez configurado esto, el siguiente paso es ir a https://developer.deepar.ai/ y crear un proyecto para obtener la App key que necesitarás más tarde.
Añadir Leones a la Entrada de Video Capturada
En esta entrada del blog, vamos a crear un UIView donde se mostrará el contenido de su cámara frontal, y su cara, cuando se detecta, se aumentará con un león fresco.
Si desea ver todo el código de este post en un solo lugar, puede encontrarlo en la página de GitHub de DeepAR.
En el código, tendrá que lidiar con dos clases; una es CameraController de DeepAR SDK, esta clase se encarga de acceder a la cámara del dispositivo y obtener imágenes de ella. Una vez que tiene imágenes de vídeo, las envía a la instancia ARView, que es la otra clase que tienes que instanciar.
ARView es responsable de mostrar el contenido de la cámara con los filtros AR aplicados. ARView es un UIView hijo normal, por lo que necesitas añadirlo a cualquier vista padre dentro de la jerarquía de vistas de tu app.
Sabiendo esto, el código podría tener este aspecto:
let deepARCameraController = CameraController()
let deepARView = ARView(frame: UIScreen.main.bounds)
deepARView.setLicenseKey(deepARLicense)
deepARView.delegate = self
deepARCameraController.arview = deepARView
parentView.insertSubview(deepARView, at: 0)
deepARView.initialize()
deepARCameraController?.startCamera()En el código de arriba, primero creas el CameraController, luego creas la instancia ARView usándola como frame el fullscreen ya que lo mostraremos ocupando toda la pantalla.
Tenga en cuenta que estamos asignando self como delegado de ARView, por lo que necesitará implementar/conformarse al protocolo ARViewDelegate. Lo necesitaremos más adelante.
Una vez que tenemos ambas instancias, asignamos la propiedad ARView de la instancia CameraController a nuestra vista y la insertamos en nuestro archivo parentView.
Lo único que queda es inicializar la vista y capturar video de la cámara llamando a startCamera.
Si ejecutas tu código, notarás que no hay 🦁 sobre tu cara, y eso es porque aún no hemos activado el efecto.
Para ello, es necesario implementar didInitializeun método del ARViewDelegate, que llamaremos una vez que el ARView haya terminado de inicializarse, entonces podremos activar el filtro león.
func didInitialize() {
deepARView.switchEffect(withSlot: "effect", path: Bundle.main.path(forResource: "lion", ofType: ""))
}Para que funcione, tienes que añadir un archivo llamado "lion" a tu proyecto. Puede encontrarlo en el paquete gratuito de filtros que puede obtener en https://developer.deepar.ai/downloads. Una vez que lo tengas descargado, tienes que arrastrar el archivo "lion" a la carpeta raíz del proyecto Xcode y comprobar que tiene como destino tu aplicación, para que quede empaquetado con ella.
XCode
Si ejecutas la aplicación en este punto, deberías ver tu cara con un león superpuesto que sigue todos tus movimientos y gestos.
Lion
OpenTok y controladores de Video personalizados
La forma en que la mayoría de los desarrolladores interactúan con la Video API de Vonage es a través del SDK de OpenTok. Una de las funciones más interesantes del SDK es la posibilidad de crear tu controlador de Video para enviar cualquier tipo de contenido de video a la sesión de OpenTok a la que está conectado tu editor.
Los controladores de Video pueden dividirse en dos partes diferentes:
Por un lado, tenemos el capturador de Video, que como su nombre indica, tiene que capturar el video de cualquier fuente (o producir el suyo propio de alguna manera) y alimentar el SDK con los fotogramas de video que se van a enviar.
Por otro, tenemos el renderizador de Video, y como probablemente habrás adivinado, se encarga de renderizar los fotogramas de video que llegan remotamente a través de una sesión de OpenTok mediante un suscriptor.
Si has utilizado el SDK de OpenTok, probablemente habrás notado que no necesitas tratar con estas clases en un escenario típico. Esto se debe a que el SDK de OpenTok incluye capturadores y renderizadores por defecto que capturan vídeo de la cámara del sistema por defecto y renderizan los fotogramas de vídeo remotos utilizando la tecnología gráfica de cada plataforma, ya sea Metal, OpenGL o DirectX.
Los controladores de Video son muy potentes. Puedes crear un controlador de Video para enviar cualquier contenido de video. Por ejemplo, puedes capturar la salida de cualquier motor de juegos, y enviar esos cuadros de video al SDK de OpenTok, y estarás transmitiendo el contenido de tu juego a cualquier participante de una sesión de OpenTok. También puedes aplicar cualquier filtro de renderizado, como B&N o detección de bordes para que cualquier abonado tenga un aspecto diferente.
Creación de un capturador de Video personalizado de OpenTok
Aunque pueda parecer que crear un capturador de vídeo personalizado es una tarea complicada, probablemente sea más sencillo de lo que puedas esperar.
Sólo tienes que implementar una interfaz, extender una clase, o conformar un protocolo en función del lenguaje y la plataforma de su elección. Aunque, como has visto más arriba, estamos utilizando swift y iOS en los ejemplos de código fuente para este post.
En esa clase, necesitarás implementar o sobreescribir algunos métodos básicos que controlan el ciclo de vida del capturador. Necesitarás implementar init, startCapture, stopCapture, isCaptureStarted así como un método para especificar la configuración de la capturadora, que consiste en especificar la altura, anchura, velocidad de fotogramas y formato de píxel de los fotogramas de vídeo que la capturadora va a enviar.
Una vez implementados estos métodos, necesitarás alimentar la capturadora con fotogramas. Dependiendo de la plataforma, puede ser diferente, pero por lo general, sólo tiene que llamar a un método con los datos de fotogramas de vídeo.
Veamos cómo podría ser una implementación inicial,
class DeepARVideoCapturer: NSObject, OTVideoCapture {
fileprivate var captureStarted = false
var videoCaptureConsumer: OTVideoCaptureConsumer?
func initCapture() {
}
func releaseCapture() {
}
func start() -> Int32 {
captureStarted = true
return 0
}
func stop() -> Int32 {
captureStarted = false
return 0
}
func isCaptureStarted() -> Bool {
return captureStarted
}
func captureSettings(_ videoFormat: OTVideoFormat) -> Int32 {
return 0
}
}
Arriba está el código necesario para un capturador personalizado. Como puedes ver, necesitas implementar el protocolo OTVideoCapture, que tiene métodos que serán llamados cuando el capturador de video necesite ser inicializado, iniciado o detenido. Es muy común tener una bandera interna para saber cuando la captura ha comenzado, y eso es lo que hacemos en esta implementación básica. Actualizaremos esa bandera en los métodos start y stop.
Habrás notado que esta clase hereda de NSObjectya que esto no es muy común en las clases swift, que heredan sólo de Object. La razón detrás de esto es que el protocolo OTVideoCapture hereda del protocolo NSObject, principalmente porque el código base de OpenTok SDK es en su mayoría Objective-C y en este lenguaje, todas las cosas heredan de NSObject.
Una vez que tengas una clase como esta, el siguiente paso es decirle al editor que, en lugar de usar el capturador por defecto, tiene que usar nuestra clase. El código para esto se parece a:
let settings = OTPublisherSettings()
settings.name = UIDevice.current.name
settings.videoCapture = DeepARVideoCapturer()
otPublisher = OTPublisher(delegate: self, settings: settings)La capturadora que construimos en el fragmento de código anterior todavía no envía nada, ya que sólo contiene código de inicialización. Si intentas usar lo que tenemos ahora, debería funcionar, pero sólo publicarás fotogramas negros. El siguiente paso es saber cómo enviar fotogramas.
Pero retrasaremos esta parte hasta que tengamos algunos fotogramas para enviar, y esos fotogramas serán la salida de nuestra vista DeepAR.
Integración de DeepAR y OpenTok
Hemos llegado a la última parte de la entrada del blog, en la primera parte vimos cómo construir un capturador de Video básico, en la segunda parte, vimos cómo ARView de DeepAR con un filtro AR de un león reemplazando tu cara. Lo único que faltaba en nuestro capturador de vídeo personalizado era enviar fotogramas de vídeo, así que parece que lo tenemos todo listo para el último paso.
En este paso, vamos a conectar ambos mundos juntos; tenemos que hacer un par de cosas. Primero, necesitamos obtener los cuadros de video que ARView está produciendo, y segundo, necesitamos enviarlos usando el capturador de video que construimos.
El primer paso consiste en obtener una imagen del ARView. Esto puede hacerse muy rápidamente configurando el delegado ARView o el listener. El delegado o la clase que implemente la interfaz listener recibirá una llamada a su método cuando un frame esté disponible. Una vez que esto sucede, tenemos que enviar ese marco al mundo OpenTok.
Si recuerdas, ya establecimos el delegado de ARView, y en su método didInitialize habilitamos el filtro del león, ahora necesitamos decirle a ARView que queremos obtener sus cuadros de video. Esto se hace utilizando el código de abajo:
func didInitialize() {
deepARView.switchEffect(withSlot: "effect", path: Bundle.main.path(forResource: "lion", ofType: ""))
deepARView.startFrameOutput(withOutputWidth: 640, outputHeight: 0, subframe: CGRect(x: 0, y: 0, width: 1, height: 1))
}La primera línea es la que tenemos en la primera parte de la entrada del blog, y con la segunda línea, estamos solicitando a ARView que llame a otro método delegado con el contenido de la AR View.
Después de hacer esto, necesitamos implementar el método frameAvailable que será llamado cada vez que un fotograma de video esté listo. En ese método, enviaremos el contenido del mismo a la capturadora OpenTok.
func frameAvailable(_ sampleBuffer: CMSampleBuffer!) {
autoreleasepool {
guard let pb = CMSampleBufferGetImageBuffer(sampleBuffer) else {
print("Invalid Image buffer")
return
}
deepARCapturer.pushFrame(pb)
}
}Usted puede haber notado el método pushFrame en la última línea, este método es donde hacemos el puente entre la vista DeepAR y el capturador de video OpenTok, si recuerdas, deepARCapturer era el nombre del capturador de video personalizado que estábamos usando.
Esta es probablemente la parte más complicada de la entrada del blog. Estamos tratando con CoreImage y CoreVideo iOS Frameworks para obtener la información RGB del fotograma.
Para que todo funcione, necesitamos implementar el pushFrame en el DeepARVideoCapturer, y se verá así:
func pushFrame(_ pb: CVPixelBuffer) {
// 1
if otFrame == nil {
let otFormat = OTVideoFormat()
otFormat.pixelFormat = .ARGB
otFormat.imageWidth = UInt32(CVPixelBufferGetWidth(pb))
otFormat.imageHeight = UInt32(CVPixelBufferGetHeight(pb))
otFormat.bytesPerRow = [CVPixelBufferGetBytesPerRow(pb)]
otFrame = OTVideoFrame(format: otFormat)
}
guard let frame = otFrame else {
print("Error creating video frame")
return
}
// 2
CVPixelBufferLockBaseAddress(pb, .readOnly)
if let frameData = CVPixelBufferGetBaseAddress(pb) {
frame.orientation = .up
frame.clearPlanes()
frame.planes?.addPointer(frameData)
// 3
videoCaptureConsumer?.consumeFrame(frame)
}
CVPixelBufferUnlockBaseAddress(pb, .readOnly)
}Vayamos paso a paso para entender este método. Como puedes ver, lo hemos dividido en tres secciones.
En la Sección 1 (marcada con //1 más arriba), construimos una nueva instancia de OTVideoFrame. Esta clase OTVideoFrame actúa como contenedor de la información del fotograma de vídeo que utilizaremos más tarde cuando introduzcamos el fotograma en el SDK de OpenTok. Típicamente un fotograma de Video contendrá su información de formato (RGB, YUV, etc.), las dimensiones, el número de bytes que pesa una fila en el fotograma de video, y obviamente, la información del fotograma de video.
Puede que te preguntes por qué necesitamos el tamaño en bytes de la fila, los formatos de fotograma de Video son complejos de explicar, y hay diferentes formatos, pero normalmente, ayuda saber cómo de grande es el buffer de información del fotograma de video. Puedes multiplicar el número de bytes por fila por la altura de la imagen, y lo tendrás. Hay veces que el tamaño de la fila no se calcula multiplicando el tamaño de un píxel por la anchura de la imagen, ya que a veces se añaden píxeles vacíos adicionales como relleno.
Si este último párrafo te resulta confuso, no te preocupes, no sabes qué poner ahí, ya que las funciones de CoreVideo te lo devolverán.
Volviendo a nuestro núcleo, como puedes ver, reutilizaremos el "contenedor" en cada fotograma, ten en cuenta que esta función será llamada unas 30 veces por segundo.
Después de crear una instancia de OTVideoFrame y rellenarla con la información que es constante en todos los fotogramas de Video, podemos pasar a la sección 2 (// 2).
En esta sección, antes de hacer nada bloqueamos el contenido del frame de video para evitar que cualquier otro thread pueda cambiarlo o borrarlo mientras estamos accediendo a él, podemos hacerlo llamando a CVPixelBufferLockBaseAddressDespués, obtenemos el puntero a la información del frame llamando a CVPixelBufferGetBaseAddress, y finalmente, añadimos esa información a nuestra instancia OTVideoFrame.
Como hemos dicho antes, hay diferentes tipos de formatos de imagen de Video. Aquí vamos a utilizar ARGB, que suele denominarse formato de imagen de píxeles. Eso significa que la memoria intermedia está compuesta por una sucesión de información de píxeles codificada con cuatro valores, uno para el canal Alfa y otros para R, G y B.
Hay otros formatos como YUV422, que se llama formato de imagen planar, y eso es porque la imagen está dividida en diferentes planos.
Explicamos esto para entender la llamada frame.planes?.addPointer() ya que estamos usando ARGB, y tiene un plano, así es como llenamos nuestra instancia OTVideoFrame con los datos del cuadro.
Por último, y teniendo una instancia completa de OTVideoFrame con la información del fotograma de vídeo y su contenido, sólo tenemos que enviarla al SDK de OpenTok para que la envíe a través de la red al resto de participantes de la Sesión. Y esto se hace en la Sección 3 (// 3) con videoCaptureConsumer?.consumeFrame(frame) call.
videoCaptureConsumer es un miembro del protocolo OTVideoCapture, y ese miembro se establece cuando el protocolo OTVideoCapturer es inicializado por el SDK de OpenTok, cada vez que quieras enviar un cuadro de video a la sesión, necesitas llamar a este método.
Después de todos estos pasos, ya tienes todo listo para construir un Publisher que enviará el contenido de DeepAR magic a una Sesión OpenTok e impresionará a todos con tu apariencia de león.
Para empezar
El equipo de Video API de Vonage se compromete a realizar inversiones en funciones y asociaciones de productos de RA para garantizar que nuestros clientes tengan a su disposición la mejor tecnología y experiencia a la hora de crear y mejorar experiencias de video interactivas.
A medida que Vonage hace crecer nuestra Video API, hemos visto un aumento en la demanda de los servicios provistos por nuestros socios. Estamos agradecidos de trabajar con fantásticas compañías de tecnología, aplicaciones e integración en todo el mundo. Con Vonage, puedes aprovechar el espectro completo de nuestras API de comunicación y obtener un pedazo más significativo del pastel.
También te puede gustar:
Tutorial: Utiliza una pantalla verde en Javascript con Vonage Video
Tutorial: Crea un fotomatón con Vue.js y Flask
Encuentre un socio: Socios de API de comunicaciones
Compartir:
Roberto is a Full Stack Engineer on the OpenTok Client SDK team. He loves learning new bits of Android, iOS, Linux, Windows, you name it! In his free time, he is very passionate about programming languages, computer graphics, and video game development for current and old platforms like ZX Spectrum and Commodore 64.