GStreamer te ayuda en tus videoconferencias

publicado en: Blog | 0
Share Button

Últimamente nos han preguntado mucho sobre la configuración de la aplicación que usamos para videoconferencia, cómo hacemos para que la pantalla aparezca partida, se mezclen de determinada forma varias fuentes, aparezca una “mosca” con nuestro logotipo… y ahora, con este texto, cumplimos la promesa de explicarlo a todos.

En realidad, lo que ha interesado a nuestros vídeo-interlocutores no se configura en nuestros programas de videoconferencia favoritos (que tampoco son, por desgracia, los mismos que ellos usan y no serviría de mucha ayuda) Sentimos desilusionaros, no hay misterio, no hay magia, lo único que hacemos es preparar el dispositivo de vídeo usando una webcam virtual gracias al bucle local de vídeo de Linux y mezclamos con el excelente framework multimedia GStreamer las distintas partes.

GStreamer. Framework multimedia y multiplataforma libre.

Lo que vamos a contar a continuación no es un tutorial riguroso ni completo del uso de GStreamer, se trata sólo de explicar lo que nosotros solemos usar para videoconferencia y que seguro que, aunque tu campo no sea la multimedia, te dará ideas para explotarlo a tu manera.

Como ya hemos confesado en alguna ocasión nuestra afición a Debian y sus derivadas, vamos a empezar por explicar cómo lo preparamos, que por desgracia no es sólo instalar un paquete ¡Recuerda usar sudo!

Como siempre, lo primero actualizar
aptitude update

Después instalar los módulos del núcleo correspondientes a tu versión
aptitude install linux-headers-`uname -r` module-assistant

Ya le toca al bucle local de vídeo
aptitude install v4l2loopback-source

Luego preparamos/compilamos/instalamos el controlador del bucle local de vídeo
m-a prepare
m-a update
m-a a-i v4l2loopback-source

Para cargarlo a mano
modprobe v4l2loopback

O para que se cargue sólo al iniciar
echo "v4l2loopback" >> /etc/modules

Y ya que estamos, instala GStreamer-tools, que lo vamos a necesitar

aptitude install gstreamer-tools

La verdad es que esto no ha sido muy entretenido; no te preocupes, ahora llega la diversión usando GStreamer. Si nos sigues, ya te habrás imaginado que automatizamos el uso de GStreamer con Python, pero lo siguiente lo vamos a explicar con gst-launch (esa especie de consola para GStreamer) que es perfectamente válida y nos ahorramos una capa de complejidad para quien prefiera usar otro lenguaje, o ninguno, en estas tareas de vídeo.

Por ejemplo y para ir abriendo boca, para ver la webcam real en una ventana basta con escribir
gst-launch v4l2src device=/dev/video0 ! autovideosink

Suponiendo, claro, que tu webcam sea video0

Mostrar la webcam en una ventana con gst-launch

Usar las prestaciones multimedia que GStreamer ofrece desde la consola con gst-launch es bastante sencillo, su filosofía se parece mucho a las clásicas tuberías con las que ya habrás trabajado si te gusta la consola. El signo de cierre de admiración sustituye en GStreamer la barra vertical de las tuberías.

Los distintos elementos que forman una cadena en GStreamer pueden ser fuente (source) de audio, vídeo, imagen… destino (sink) o conectores (pads) entre ellas. Los elementos pueden incluir también cierta parametrización.

En nuestro primer ejemplo, v4lsrc es una fuente o elemento de entrada (source) con el parámetro o propiedad device asignado a /dev/video0 y autovideosink es un elemento de salida o destino (sink) que se une al anterior con una tubería, representada en el comando con el signo de cierre de admiración. Tal como te imaginas el significado vendría a ser algo así como lee del dispositivo de v4l video0 y mándalo a una ventana de la manera más automática posible.

Hasta ahora puede que no parezca muy espectacular. A lo mejor con el siguiente uso ya te vas animando. Suponiendo que el bucle local de vídeo te ha creado el dispositivo /dev/video1, con la orden
gst-launch \
   filesrc location=acadacual.avi ! \
   decodebin2 ! \
   v4l2sink device=/dev/video1

puedes simular la webcam con un vídeo que esté grabado y así hablar en pijama con tu jefe desde el hotel mientras parece que ya estás en perfecto estado de revista; bueno, eso suponiendo que has grabado antes un vídeo en el que lo parezca.

En la orden hemos añadido un elemento más a la cadena: decodebin2 que se encarga de decodificar la señal del vídeo y mandarla a video1. Y como quedaría larga e ilegible, verás que hemos usado la barra hacia atrás (back slash) para separar las diferentes partes en diferentes líneas ¿Verdad que ahora se lee mucho mejor?

Como te imaginabas, en la lista de dispositivos de vídeo disponibles de tu programa de videoconferencia tendrás que elegir el dispositivo al que se dirige el bucle local de vídeo (v4l2loopback)

Cuadro de diálogo para elegir el dispositivo de vídeo en Ekiga


Vídeo de Paola seleccionado en Ekiga

Por cierto, si el vídeo no dura tanto como tu conversación con el jefe, a lo mejor quieres que se repita indefinidamente o se va a notar el truco. Sin usar Python, como decíamos antes, desde la consola puedes hacer algo como
while true; \
  do \
    gst-launch \
      filesrc location=acadacual.avi ! \
      decodebin2 ! \
      v4l2sink device=/dev/video1
 \
  ; \
done

que puede que no sea muy elegante pero funcionará. Evidentemente esto no tiene nada que ver con GStreamer, es la consola la que se encarga.

GStreamer dispone de elementos adaptadores que permiten convertir las diferentes capacidades de un elemento para que sean compatibles con las de otro. Por ejemplo, sirven para pasar vídeo en formato RGB a un consumidor que lo necesite, traduciendo desde un productor que genere YUV o codecs, que permiten codificar/decodificar la señal según las especificaciones de determinado formato. Si ahora que no tienes el pelo revuelto y ya no estás en pijama quieres grabarte desde la webcam para poder relajarte después puedes usar la orden

gst-launch -e \
  v4l2src device=/dev/video0 ! \
  theoraenc ! \
  oggmux ! \
  filesink location="presentable.mkv"

Evidentemente el documento generado sólo contiene vídeo, es decir, imagen sin audio; así puedes hablar con el jefe y que no se note. Para que no cante el corte y lo puedas reproducir cíclicamente, puedes usar el viejo truco de duplicar y pegar reproduciendo hacia atrás; pero cuidado como te mueves, que también se puede notar.

Y esto nos lleva a la siguiente cuestión ¿Como podemos reproducir a la vez audio y vídeo? Para eso y para muchas otras operaciones multimedia, GStreamer incorpora los mezcladores (muxers) y las T (era de esperar, como toda buena tubería) La idea es muy sencilla: se crea un mezclador o una T con un nombre y se deriva la tubería para obtener un duplicado de la señal o juntar en una varias señales (para esto es la T) o superponer varias señales (eso hacen los mezcladores)

De esa forma, para no grabarte a ciegas y ver en una ventana qué tal quedas puedes usar la orden

gst-launch \
  v4l2src device=/dev/video0 ! \
    tee name=copia \
  copia. ! \
    queue ! \
    autovideosink \
  copia. ! \
    queue ! \
    theoraenc ! \
    oggmux ! \
    filesink location="presentable.mkv"

En la segunda línea de la orden anterior dirigimos la webcam a una T que hemos llamado copia. En la tercera línea hacemos que se vea en una ventana y en la cuarta lo grabamos. Ten cuidado, cuando se usa la T su nombre lleva un punto detrás y no lo lleva cuando se define.

Capturar vídeo y a mismo tiempo mostrar la imagen usando una T

Para verte más corporativo, prueba a usar la siguiente orden con la que podrás superponer el logotipo y así vemos cómo funcionan los mezcladores.

gst-launch \

  v4l2src device=/dev/video0 ! \
  ffmpegcolorspace ! \
  mezclador. \
  multifilesrc location=logo_acadacual.png caps="image/png,framerate=1/1" ! \
  pngdec ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 alpha=.7 top=-340 left=-510 ! \
  mezclador. \
  videomixer name=mezclador ! \
  ffmpegcolorspace ! \
  autovideosink

Con esta orden hemos añadido también alguna cosa nueva: el elemento multifilesrc que nos permite mostrar el logotipo, pngdec que decodifica el documento PNG que lo contiene, ffmpegcolorspace que convierte entre el espacio de color del PNG y el de la ventana de vídeo que lo mostrará y videobox que posiciona el logotipo en una esquina. Tanto el mezclador (que se usa similar a la T) como los parámetros se autoexplican, o eso esperamos.

Roma en una webcam con el logo de acadacual

Habrás notado que GStreamer utiliza la transparencia del documento PNG y que además puedes añadir una transparencia global con el parámetro alpha. Esto te da la posibilidad de hacer sombras para superponer elementos (más allá de las que la imagen tenga) y simular relieves o combinar modos de imagen invertida para darle más visibilidad a lo que se superpone cuando el fondo sea oscuro. La imagen de abajo es un ejemplo en el que sólo se ha modificado el documento PNG; más adelante verás alguno en el que se usa una sombra al componer.

Roma con el logo de Acadacual.es en versión original y un poco de sombraVíctor Ventura con el logo de Acadacual.es en relieveAna con el logo de Acadacual.es invertido

Puede que sea útil, especialmente cuando uses mezcladores, que te asegures que se recibe correctamente el fin de fichero (EOF) Para eso puedes usar la opción --eos-on-shutdown (abreviada como -e) de gst-launch y así podrás terminar con un Control+C sin problemas. Puedes consultar otras opciones (algunas muy útiles como --verbose, --tags y --index) con man gst-launch

Con todo lo anterior seguro que ya sabrías simular una webcam virtual usando la webcam real y superponerle el logo un poco transparente. Nosotros lo hacemos así:

gst-launch \
  v4l2src device=/dev/video0 ! \
    alpha method=0 alpha=1 ! \
    mezclador. \
  multifilesrc location=logo_acadacual.png caps="image/png,framerate=1/1" ! \
    pngdec ! \
    videobox border-alpha=0 alpha=.6 top=-340 left=-510 ! \
    mezclador. \
  videomixer name=mezclador ! \
    videorate ! \
    ffmpegcolorspace ! \
    video/x-raw-yuv ! \
    v4l2sink device=/dev/video1 sync=false

Aquí puedes encontrar alguna cosa nueva, por ejemplo videorate, que se encarga de reajustar el vídeo para que el stream quede correcto y video/x-raw-yuv un adaptador con el que pasamos el vídeo al formato YUV

Webcam virtual con el logotipo de Acadacual.es

Con GStreamer se puede obtener imagen desde muchas fuentes, por ejemplo, si sigues como nosotros Medialab Prado, puedes usar esta orden para ver sus charlas en directo

gst-launch -eti \
  souphttpsrc \
    location="http://d3.intergridnetwork.net:8000/medialab-prado.ogg" ! \
    tee name=audioyvideo \
  audioyvideo. ! \
    queue ! \
    oggdemux ! \
    vorbisdec ! \
    audioconvert ! \
    audioresample ! \
    alsasink \
  audioyvideo. ! \
    queue ! \
    decodebin2 ! \
    autovideosink

Usando gst-launch para ver una conferencia de MediaLab Prado

En tiempos pasados, ese mismo sistema también nos servía para ver el taller desde el estudio con el viejo y querido conversor de vídeo-ip de AVIOSYS con la orden

gst-launch -eti \
  souphttpsrc location="http://taller.acadacual.es:8086/GetData.cgi" ! \
  multipartdemux ! \
  image/jpeg,width=640,height=480,framerate=0/1 ! \
  jpegdec ! \
  autovideosink sync=false

AVIOSYS 9100A para ver el taller de diseño gráfico de Acadacual.es desde la oficina multimedia

Y una cosa muy interesante que nosotros usamos frecuentemente en videoconferencias: mostrar una zona del escritorio o de una ventana, por ejemplo, con la orden

gst-launch -eti \
  ximagesrc \
    use-damage=0 \
    startx=50 \
    starty=100 \
    endx=250 \
    endy=300 \
    xname="Inkscape" ! \
  ffmpegcolorspace ! \
  "video/x-raw-yuv,format=(fourcc)YUY2" ! \
  v4l2sink device=/dev/video1

En el ejemplo anterior, mandamos a la webcam virtual la zona de la (supuesta) ventana "Inkscape" que va de la esquina 50,100 a la esquina 25,300

caption id=

¿Eres de los que tienen la webcam a un lado? Entonces te gustará saber cómo girar la imagen con GStreamer, con esta orden es muy sencillo

gst-launch -eti \
  v4l2src device=/dev/video0 ! \
  videoflip method=clockwise ! \
  v4l2sink device=/dev/video1

Lógicamente, tendrás que cambiar el valor de method por counterclockwise si tu cámara está girada en la dirección contraria.

Ana tiene la webcam girada y lo resolvemos con GStreamer para que pueda usar Kopete sin problemas

Otra de las razones por las que usamos GStreamer para videoconferencia (está claro que tenemos muchas para usarlo para proyectos multimedia) es por nuestro actual ancho de banda, que en el lugar de Granada en el que estamos ahora, casi deberíamos decir estrecho de banda. Si intentamos hacer una videoconferencia con más de un ordenador se pueden oír las carcajadas del router desde la distancia. Pero lo que sí podemos hacer es juntar en una la imagen de dos o más cámaras web (u otras fuentes) y aunque el tamaño aumente, funciona decentemente.

Suponiendo que en video0 y video1 hay webcam reales y en video2 está el bucle local de vídeo, para unir en una única señal de webcam virtual la suma de las dos webcam reales podemos usar, por ejemplo, la orden

gst-launch -eti \

  videomixer name=doblewebcam ! \
  autovideosink sync=false \
  v4l2src device=/dev/video0 ! \
  doblewebcam. \
  v4l2src device=/dev/video1 ! \
  videobox border-alpha=0 top=0 left=-640 ! \
  doblewebcam.

Lo anterior resuelve el problema del ancho de banda de la conexión con Internet pero puede que introduzca un nuevo problema con el ancho de banda de los puertos USB. Si te ocurre, verás el desagradable error del sistema "no queda espacio en el dispositivo" (System error: No space left on device) ¿De qué depende? Aunque parece falta de músculo para tanto USB, no estamos seguros; en un humilde Core 2 Duo (con USB2) podemos ver cuatro cámaras mientras que en un portátil nuevo con un i5 (también con USB2) aparece el famoso error al intentar usar más de una.

Una forma de aligerar la carga y probablemente de resolver el problema puede ser utilizar menos fotogramas por unidad de tiempo y/o una resolución menor. Con un ejemplo en una orden sencilla seguramente se entienda mejor

gst-launch \
  v4l2src device=/dev/video0 ! \
  video/x-raw-yuv,width=640,height=480,framerate=30/1 ! \
  autovideosink

gst-launch \
  v4l2src device=/dev/video0 ! \
  video/x-raw-yuv,width=320,height=240,framerate=15/1 ! \
  autovideosink

En la primera orden usamos toda la capacidad de la webcam y en la segunda limitamos a la mitad la resolución y el número de fotogramas por segundo. Evidentemente, esos valores dependerán de lo que tu modelo de webcam en concreto pueda hacer.

Otra solución puede ser no utilizar USB en absoluto. Nuestras pruebas con el viejo AVIOSYS (y bastante ensayo y error) nos han permitido resolver el problema del portátil usando VideoIP a dos fotogramas por segundo (suficiente, aunque no lo parezca, para videoconferencia) Si tu ordenador tiene un puerto PCI libre, una solución mucho mejor es usar una tarjeta capturadora de vídeo para videovigilancia, ya que tienen varias entradas de vídeo (la nuestra 4, pero conocemos algunas de hasta de 24). Si el modelo que eliges lo permite (nosotros lo hemos conseguido sin problemas) obtendrás cuatro dispositivos /dev/video en lugar de uno y si el ratio de fotogramas por segundo de la tarjeta es bastante alto (100 fotogramas por segundo en nuestro caso) puedes llegar fácilmente a capturar cuatro cámaras a 25 fotogramas por segundo a toda la resolución PAL. Es la solución más barata y (dependiendo de las cámaras de vídeo que uses, por supuesto) con más calidad; de sobra para videoconferencia seguro.

Capturadora para videovigilancia que en Acadacual.es usamos para videoconferencia

Si has decidido mostrar dos o más cámaras a lo mejor necesitas identificar lo que se ve en cada una de ellas. Para hacer eso es útil textoverlay como en la siguiente orden

gst-launch -eti \

  videomixer name=doblewebcam ! \
  autovideosink sync=false \
  v4l2src device=/dev/video0 ! \
  textoverlay \
    font-desc=”Droid Sans 26″ \
    text=”VIX” \
    valign=bottom \
    halign=right \
    shaded-background=false ! \
  doblewebcam. \
  v4l2src device=/dev/video1 ! \
  textoverlay \
    font-desc=”Droid Sans 26″ \
    text=”ROMA” \
    valign=bottom \
    halign=right \
    shaded-background=false ! \
  videobox border-alpha=0 top=0 left=-640 ! \
  doblewebcam.

Si las cámaras están lo bastante cerca, no es necesario utilizar tuberías para el audio como hacemos con el vídeo ya que bastará con elegir un micrófono en el programa de videoconferencia y seguramente será suficiente sólo con el alcance del micrófono para los participantes de la videoconferencia en la misma sala. Pero si queremos grabar el sonido (o la imagen y el sonido) GStreamer vuelve a ser de gran ayuda. Con la siguiente orden podemos enviar el audio de la entrada por defecto de PulseAudio a un documento en MP3

gst-launch -eti \
  pulsesrc ! \
  audioconvert ! \
  lamemp3enc target=1 bitrate=128 cbr=true ! \
  filesink location=undostresprobando.mp3

La orden anterior es muy probable que funcione ya que usa el dispositivo de entrada de sonido por defecto y seguro que lo tendrás preparado (siempre que digáis algo en frente del micrófono, evidentemente) lo que puede resultar un poco más antipático es elegir de entre una serie de dispositivos de entrada.

La orden pactl list permite ver los módulos del servidor de sonido PulseAudio que están cargados. Antes de que la uses debes saber que te va a mostrar un montón de información. Lo mejor es filtrarla para ver sólo lo que necesitamos. Si has sido impaciente habrás visto que aparecen, entre otras muchas cosas, las distintas fuentes (dispositivos de entrada) en un formato muy sencillo: El número de la fuente y dos líneas con el nombre en la segunda así que podemos quedarnos sólo con esos nombres escribiendo

pactl list | grep -a2 "Fuente" | grep "Nombre"

El resultado tendrá un formato parecido a lo que nos muestra en un ordenador con tres cámaras web Creative Live Cam Socialize conectadas por USB, una salida HDMI de una tarjeta gráfica y la entrada y salida analógca del sistema de sonido integrado en la placa base

Nombre: alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor
Nombre: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
Nombre: alsa_input.pci-0000_00_1b.0.analog-stereo
Nombre: alsa_input.usb-Creative_Labs_VF0640_Live__Cam_Socialize_1H030008-02-Socialize.analog-mono
Nombre: alsa_input.usb-Creative_Labs_VF0640_Live__Cam_Socialize_1H030018-02-Socialize_1.analog-mono
Nombre: alsa_input.usb-Creative_Labs_VF0640_Live__Cam_Socialize_0H273605-02-Socialize_2.analog-mono

Ten cuidado, en la orden anterior damos por hecho que tu sistema está en español. Si utilizas otro idioma tendrás que cambiar "Fuente" y "Nombre" por lo que corresponda a tu sistema.

Para usar un dispositivo de entrada de audio concreto podemos referirnos a él por su nombre com en la orden

gst-launch -e \
  pulsesrc device="alsa_input.pci-0000_00_1b.0.analog-stereo" ! \
  audioconvert ! \
  lamemp3enc target=1 bitrate=128 cbr=true ! \
  filesink location=holaholaeheh.mp3

Si el formato MP3 no te parece lo bastante libre, a lo mejor prefieres guardar el sonido como Ogg Vorbis con esta orden

gst-launch -eti \
  pulsesrc ! \
  audioconvert ! \
  vorbisenc ! \
  oggmux ! \
  filesink location=sisieheh.ogg

Y ahora vamos a juntar casi todo en un ejemplo en el que se simulará una webcam virtual usando el bucle local de vídeo en el que se mostrará una captura de una ventana, tres cámaras de vídeo reales en directo con un texto que las identifica y el logotipo de acadacual

gst-launch -eti \

  videomixer name=webcamvirtual ! \
  v4l2sink device=/dev/video4 \
  multifilesrc \
    location=logotipo_acadacual_opaco.png \
    caps="image/png,framerate=1/1" ! \
  pngdec ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 alpha=0 top=-768 left=0 ! \
  webcamvirtual. \
  v4l2src device=/dev/video3 ! \
  "video/x-raw-yuv, width=360, height=288" ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=12 bottom=20 left=52 right=52 ! \
  textoverlay \
    font-desc="Droid Sans 26" \
    text="VIX" \
    halignment=left \
    valignment=top \
    deltax=-10 \
    deltay=-15 \
    color=2576980377 \
    shaded-background=false ! \
  videobox border-alpha=0 top=-512 left=0 ! \
  webcamvirtual. \
  v4l2src device=/dev/video2 ! \
  "video/x-raw-yuv, width=360, height=288" ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=12 bottom=20 left=52 right=52 ! \
  textoverlay \
    font-desc="Droid Sans 26" \
    text="ROMA" \
    halignment=left \
    valignment=top \
    deltax=-10 \
    deltay=-15 \
    color=2576980377 \
    shaded-background=false ! \
  videobox border-alpha=0 top=-256 left=0 ! \
  webcamvirtual. \
  v4l2src device=/dev/video1 ! \
  "video/x-raw-yuv, width=360, height=288" ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=12 bottom=20 left=52 right=52 ! \
  textoverlay \
    font-desc="Droid Sans 26" \
    text="ANA" \
    halignment=left \
    valignment=top \
    deltax=-10 \
    deltay=-15 \
    color=2576980377 \
    shaded-background=false ! \
  videobox border-alpha=0 top=0 left=0 ! \
  webcamvirtual. \
  ximagesrc \
    use-damage=0 \
    startx=0 \
    starty=0 \
    endx=984 \
    endy=919 ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=0 left=-256 ! \
  webcamvirtual.

Webcam virtual mostrando tres webcam reales, el logotipo de Acadacual.es y captura del escritorio

Habrás notado que hemos utilizado una versión del logotipo de acadacual que es opaca; es para evitar los problemas que puede dar ximagesrc con las transparencias. Por eso también formamos a la izquierda una barra vertical compacta con todo lo que quede fuera de la captura del escritorio.

También hemos usado algunos parámetros más para textoverlay. El parámetro color, que espera un valor ARGB (el canal de transparencia, el de rojo, verde y azul expresados como un entero decimal) y deltax y deltay que son el desplazamiento del texto desde su posición normal. También hemos usado dos veces videobox, con valores negativos para posicionar y con valores positivos para recortar, tanto para evitar la zona sin imagen de la cámara de vídeo analógico como para dar forma cuadrada al espacio que hemos reservado para mostrar a los interlocutores.

Cuando hay varios interlocutores en la misma sala pero no se quiere llenar la ventana de la aplicación de videoconferencia con las caras de cada cual, una opción interesante puede ser usar una sola ventana para las webcam y que alguien se encargue de ir mostrando en esa ventana a la persona que habla en cada momento usando hardware.

gst-launch -eti \

  videomixer name=webcamvirtual ! \
  v4l2sink device=/dev/video1 \
  multifilesrc \
    location=logotipo_acadacual_vertical_bn.png \
    caps="image/png,framerate=1/1" ! \
  pngdec ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 alpha=0 top=-256 left=0 ! \
  webcamvirtual. \
  v4l2src device=/dev/video0 ! \
  "video/x-raw-yuv, width=360, height=288" ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=12 bottom=20 left=52 right=52 ! \
  webcamvirtual. \
  ximagesrc \
    use-damage=0 \
    startx=0 \
    starty=0 \
    endx=799 \
    endy=679 ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=0 left=-256 ! \
  webcamvirtual.

Webcam virtual compuesta con una webcam real, la captura del escritorio y el logotipo de acadacual

Entre los cacharrichis que tenemos en acadacual hay uno que sirve para hacerlo, es un conmutador de vídeo analógico (que también sirve de modulador de vídeo) que puede ir mostrando una de entre cuatro fuentes de vídeo eligiéndolas con un mando a distancia: perfecto para resolver el ejemplo.

Modulador y conmutador de vídeo analógico. Vista frontal con el mando a distancia.

Es curioso que ahora, que no se concibe otra cosa que no sea vídeo digital, se consigan unos resultados excelentes (mejores que con una webcam normal) con una equipación baratuna de vídeo analógico que seguramente ya tenías por ahí para reciclar. Para videoconferencia puedes comprar equipos analógicos perfectamente válidos como los que te estamos mostrando por muy poco dinero, el problema puede ser encontrarlos todavía en el mercado.

Modulador y conmutador de vídeo analógico. Vista de las conexiones.

Por último, puede ser interesante grabar tanto la captura de pantalla como el sonido por si hay que hacer posteriormente alguna referencia al contenido.

gst-launch -eti \

  multifilesrc \
    location=logotipo_acadacual_vertical_bn.png \
    caps="image/png,framerate=1/1" ! \
  pngdec ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 alpha=0 top=-264 left=0 ! \
  webcamvirtual. \
  v4l2src device=/dev/video0 ! \
  "video/x-raw-yuv, width=360, height=288" ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=8 bottom=16 left=52 right=52 ! \
  webcamvirtual. \
  ximagesrc \
    use-damage=0 \
    startx=0 \
    starty=0 \
    endx=767 \
    endy=687 ! \
  ffmpegcolorspace ! \
  videobox border-alpha=0 top=0 left=-256 ! \
  webcamvirtual. \
  videomixer name=webcamvirtual ! \
  tee name=verygrabar \
  verygrabar. ! \
  queue ! \
  v4l2sink device=/dev/video1 \
  verygrabar. ! \
  videorate ! \
  theoraenc ! \
  queue ! \
  audioyvideo. \
  pulsesrc ! \
  audioconvert ! \
  vorbisenc ! \
  queue ! \
  audioyvideo. \
  oggmux name=audioyvideo ! \
  filesink location="videoconferencia.mkv"

Lo que hemos hecho en este ejemplo ha sido crear un mezclador “webcamvirtual” que junta la entrada de vídeo de una webcam real en /dev/video0 (que puede ser redirigida desde varias con el conmutador de vídeo del que hemos hablado) con el logotipo de acadacual y con una captura del escritorio. El mezclador se bifurca con una T “verygrabar” que tiene una salida a la webcam virtual en /dev/video1 con el bucle de vídeo local (v4l2loopback) y otra salida a un mezclador ogg (oggmuxer) “audioyvideo” que genera un documento “videoconferencia.mkv” que contendrá la imagen de la webcam virtual y el sonido del micrófono. Un esquema seguro que aclara mucho, del ejemplo y de la filosofía de GStreamer.

Esquema de gst-launch con entrada de vídeo, logotipo y captura de pantalla y salida a webcam virtual y grabación

Si has leído hasta aquí, ya sea con o sin aspirina, seguro que te ha interesado GStreamer, puedes consultar la documentación en su web. y hacer muchas más cosas que las que hemos contado en este texto o adaptarlas a tu propio estilo.

Autor: Víctor Ventura

Seguir Víctor Ventura:

Desarrollador multimedia y web

Tengo la suerte de ir recorriendo una carrera profesional muy variada pero en la que siempre encuentro lugar para la expresión gráfica y para la programación. He desarrollado aplicaciones para CAD, presentaciones multimedia interactivas, tecnología web en el cliente y en el servidor y últimamente para Internet de las cosas, tanto en el ámbito electrónico como en el tratamiento de datos y el interfaz con los usuarios. En Acadacual Granada, además de programar, me encargo de que los servidores sigan funcionando.