Skip to content

Creación de apps de audio y video con GStreamer (Parte I)

Share on twitter
Share on linkedin
Share on email
Share on whatsapp
Creación de apps de audio y video con GStreamer

En los últimos años el COVID, las condiciones climáticas y sociales o la guerra en Ucrania, nos han hecho llegar a una situación muy complicada en muchos ámbitos, incluidas las relaciones interpersonales. Esto ha hecho surgir una tendencia global a la utilización de videollamadas, conferencias multimedia y consumo masivo de contenidos online. De la misma forma se han generalizado los casos de uso de monitorización remota y la comunicación con asistentes digitales y dispositivos IoT. El denominador común de todos ellos es que utilizan la transmisión de datos, audio y video en tiempo real.   

En FutureSpace llevamos tiempo trabajando en proyectos de este tipo, y para ello utilizamos distintas herramientas. Entre ellas figura GStreamer, sobre la que vamos a hablar hoy desde un enfoque práctico.

Conceptos básicos en las apps de audio y video con GStreamer

GStreamer es un framework open source, extremadamente potente y versátil. Su arquitectura está basada en componentes conectados entre sí en forma de cadenas o pipelines. Describimos a continuación algunos conceptos importantes sobre esta arquitectura y sus distintos bloques.

Codec: los codecs son los estándares de compresión de datos. Son algoritmos que permiten optimizar el manejo y la transmisión de streams multimedia. Los hay de audio (como MP3, AAC o Vorbis) y de video (como h264-265, VP8-9, o MPEG-2).

Formato: es un contenedor que guarda datos de uno o varios tipos (audio, video, datos) procesados mediante codecs. Ejemplos de contenedores son los ficheros de tipo Quicktime, OGG, Avi, etc. Los distintos datos se insertan en el contenedor mediante multiplexores (muxers) y se extraen con demultiplexores (demuxers).

Elemento: es un componente del framework que procesa los datos que le llegan, y realiza una función específica con ellos (codificación/descodificación, comunicaciones de red, filtrado, conversión, etc.). Un elemento puede tener sources (src) y sinks y se conecta mediante ellos con los demás elementos. También puede comunicarse con una aplicación mediante mensajes al bus, o recibir eventos y consultas desde la app o desde otros componentes.

Pipeline: secuencia de elementos de GStreamer en la que hay una o más fuentes de entrada (micrófonos, cámaras, captura de pantalla, ficheros), componentes de proceso (codecs, multiplexores, filtros, convertidores, etc.), y una o más salidas o sinks: ficheros, altavoces, monitores, sockets, etc.

Arquitectura de una app multimedia
Arquitectura con ejemplo de pipeline

El entorno de desarrollo

GStreamer está escrito en C y es multi-plataforma, por lo que dispone de SDKs para Linux, MacOS, Windows, Android, iOS, etc. Sin embargo, hoy vamos a centrarnos en las herramientas de línea de comandos, que nos permiten hacer prototipos de pipelines y probar su funcionamiento muy rapidamente.

Puedes consultar la documentación oficial para instalar las Command Line Tools de GStreamer en tu plataforma. No obstante, si trabajas en Linux, lo más probable es que tu distribución ya lo incluya por defecto. Si no fuera así, puedes instalarlo con Apt, Yum o el gestor de paquetes que corresponda. Por ejemplo, con apt instalamos todos los paquetes de esta forma:

apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio

En Mac, se puede instalar muy facilmente con Homebrew:

brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav

Una vez instaladas las CLI Tools, tendremos acceso a varios comandos de GStreamer, entre los que destacamos:

  • gst-launch-1.0: Con esta herramienta podemos ejecutar pipelines que definimos en la línea de comandos.
  • gst-inspect-1.0: Si se invoca sin parámetros, muestra un listado de todos los elementos disponibles. Si se invoca con el nombre de un elemento, nos muestra la documentación, parámetros, etc. de dicho elemento.
  • gst-discoverer-1.0: Se utiliza con una URI (URL, nombre de fichero local) como parámetro, y nos muestra información sobre el formato, tamaño, duración y codificación del contenedor.

Manos a la obra! algunos ejemplos de pipelines

Después de la introducción teórica, vamos a experimentar con varios pipelines sencillos, para que vayas haciéndote una idea de la potencia del framework.

ejemplo 1: Generación de una frecuencia de prueba

Con este pipeline básico, generamos una frecuencia de 440 hz (la nota La!).

gst-launch-1.0 audiotestsrc volume=1 freq=440 ! autoaudiosink

Como vemos, los elementos (audiotestsrc y autoaudiosink) se separan con un signo «!», que simboliza el enlace entre el src del primero y el sink del segundo. El elemento audiotestsrc sirve para generar frecuencias y patrones de sonido. Con el parámetro freq definimos la frecuencia, y con wave el tipo de onda: sinusoidal, cuadrada, sierra, ruido blanco, rosa, etc. (recuerda que puedes ver todos los parámetros que admite con gst-inspect-1.0). El elemento autoaudiosink se encarga de buscar y seleccionar la salida de audio disponible.

Ejemplo 2: reproducción de un fichero WebM

Vamos ahora a descargar un fichero de audio y video. Es un trailer de un corto de animación, Sintel, de Fundación Blender, que al tener licencia Creative Commons se utiliza mucho para todo tipo de pruebas.

Trailer con audio y video
Corto de animación Sintel (Fundación Blender, 2010)

Una vez descargado, podemos ver sus características con:

gst-discoverer-1.0 ./sintel_trailer-480p.webm

Sin entrar en detalles de la salida del comando, podemos ver que es un conenedor WebM, con un canal de audio codificado con Vorbis y un canal de video codificado con VP8. Para pruebas rápidas, podemos reproducirlo con el gst-play-1.0. Este comando «estudia» el contenedor y genera un pipeline de reproducción acorde a las características, codecs, etc:

gst-play-1.0 ./sintel_trailer-480p.webm

Ejemplo 3: extracción y reproducción del audio de un fichero WebM:

También podríamos separar el canal de video (VP8) y el del audio (Vorbis), procesar cada uno de ellos por separado (filtros, efectos de sonido…) y después volverlos a juntar para reproducir ambos. Con el siguiente pipeline separamos sólo el audio del fichero:

gst-launch-1.0 -v filesrc location=sintel_trailer-480p.webm ! matroskademux ! vorbisdec ! audioconvert ! autoaudiosink

Ejemplo 4: visualización de un espectrograma del audio

Para terminar con la primera parte del artículo, con el siguiente pipeline podemos extraer el audio del trailer. Después, bifurcarlo (elemento tee) y enviar uno de los streams a la salida de altavoz, y el otro a un elemento spectrascope para visualizar su espectro de frecuencias:

gst-launch-1.0 -v filesrc location=sintel_trailer-480p.webm ! matroskademux ! vorbisdec ! tee name=t ! queue ! audioconvert ! spectrascope shader=fade-and-move-right shade-amount=0x00040302 ! videoscale ! video/x-raw,width=720,height=480 ! autovideosink t. ! queue ! autoaudiosink

Visualización del espectro de frecuencias del audio

Espero que os haya parecido interesante! En la segunda parte del post veremos pipelines más complejos para casos de uso como cámaras de vigilancia o videollamada. Para aquellos que os atreváis, entraremos también en aspectos más avanzados de GStreamer y el apasionante mundo de la codificación y transmisión de audio y video.

Share the article

Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on email
Email
Share on whatsapp
WhatsApp

A new generation of technological services and products for our customers