lunes, 10 de agosto de 2020

Usar la cámara de tu Android como webcam

En esta parte 2 vamos a ver como usar la cámara de nuestro Android como webcam.

Para ello necesitaremos de:

  • Un teléfono con Android (obvio).
  • La aplicación de IP Webcam.
  • Lo ya contado en el artículo anterior.

Una vez contemos con esto, abrimos la aplicación en el móvil y la configuramos al gusto.

Nota: Tengo que avisar que aunque la aplicación está muy bien y cumple con lo deseado, la interfaz es algo fea, pero desde luego no seré yo quien critique eso.


Esquema de red
Esquema con la configuración de red.

IP Webcam. Configuración básica.

Nota: Aunque en esta entrada solo mencione el uso de la app como webcam, tengo que decir que tiene muchos otros usos, ya que podemos usarla como vigila-bebes, como cámara de seguridad (tiene incluso detección de movimiento), tiene compatibilidad con Automagic(gracias al plugin de Tasker). Como suele decirse ¡El cielo es el límite!

Lo primero será permitir la ejecución en segundo plano de la aplicación, esto solo será necesario si quieres poder apagar la pantalla del móvil mientras lo utilizas como webcam o si quieres minimizar la aplicación para hacer otras cosas. Por ejemplo mantener una ventana de chat abierta, alguna nota, un servidor x11, etc.
Para ello vamos a la app y en Permisos adicionales encontraremos la opción.

En la parte de Preferencias de vídeo podemos cambiar tanto la cámara principal (trasera/delantera) como la resolución. Esta segunda opción nos será muy útil en Skype.

En la parte de Retransmisión local estableceremos el usuario y contraseña (recomendable).

Finalmente cuando tengamos todo configurado a nuestro gusto, podemos ir a la parte de abajo del todo y pinchar en Iniciar servidor. Esto nos mostrará nuestra cámara y nos dará algo de información en la parte inferior sobre como podemos conectarnos.

Imagen de la APP
Captura del móvil una vez iniciado el servidor.

Capturar la señal de vídeo desde el ordenador.

El proceso será el mismo que en la entrada anterior, así que iré rápido.

# Crear la cámara virtual:
sudo modprobe v4l2loopback video_nr=0 card_label="Android camera"

# Iniciar la cámara:
input=https://geek:erratico@192.168.1.31:8080/videofeed
ffmpeg                 \
    -re                \
    -i $input          \
    -map 0:v           \
    -vcodec rawvideo   \
    -vf format=yuv420p \
    -f v4l2            \
    /dev/video0

Aquí lo importante es la entrada (el parámetro -i). En este ejemplo:

  • Mi usuario es: geek
  • Mi contraseña es: erratico
  • La ip de mi móvil es: 192.168.1.31
  • El puerto en el que escucha la app es: 8080

Si todo ha ido bien, se quedará el ffmpeg ejecutando la captura hasta que decidamos pararlo. Para ello pulsamos "Ctrl + c" o bien cerramos la aplicación en el móvil.

Ver correctamente la cámara en Skype.

Por motivos que desconozco, Skype no admite cámaras con una resolución superior a 800x600. Esto es algo que descubrí a golpe de prueba y error, pero que me frustró mucho las primeras veces hasta que me dí cuenta del detalle.

Para solucionar esto hay dos opciones:

  1. Cambiar la resolución en la configuración de la aplicación móvil.
  2. Redimensionar con el ffmpeg.

Yo personalmente recomiendo la primera. El motivo es que poner una resolución más alta y después redimensionar no hará que la imagen gane calidad, sino más bien lo contrario (puede deformar la imagen). Además a veces me pasa que con resoluciones más altas el vídeo va con retraso.

Por cierto, si os pasa esto, reiniciar el ffmpeg y/o la app, a veces se soluciona.

Esto es como quedaría el comando si decidimos redimensionar (útil si queremos emitir otro contenido como un vídeo de Youtube o un stream de OBS).

input=https://geek:erratico@192.168.1.31:8080/videofeed
ffmpeg                 \
    -re                \
    -i $input          \
    -map 0:v           \
    -vcodec rawvideo   \
    -vf format=yuv420p \
    -s 800x600         \
    -f v4l2            \
    /dev/video0

Configuración Skype
Pantalla de configuración de la cámara en Skype

Finalmente dejo el script que uso para iniciar el ffmpeg sin tener que calentarme mucho la cabeza:

#!/bin/bash

# Script: ipcam.sh
# Autor: McA
# Sitio: http://geekerratico.blogspot.com
# Versión: 1.0

# Variables:
# SKYPE : Forzar la imagen a 800x600 (sin este tamaño no funciona la cámara en Skype).
# MIRROR: Voltear la imagen como en un espejo.
# HOLD  : Dejará cargado el módulo de kernel al terminar (opción ideal si se usa el script el un bucle).

# Dependencias:
# v4l2loopback-dkms, v4l-utils, ffmpeg.


# Skype:
# En el móvil configurar la resolución de la cámara a 800x600 (otras resoluciones no he conseguido hacerlo funcionar).
# Otra opción es usar el parámetro "-s" ejemplo:
# ffmpeg -re -i $input -map 0:v -vcodec rawvideo -vf format=yuv420p -s 800x600 -f v4l2 $video

label="Android camera"
input=${1:-https://mca:wololo@192.168.1.31:8080/videofeed}

load_v4l2(){
    sudo modprobe v4l2loopback video_nr=0 card_label="$label" || exit 1
    video=/dev/video0
}

lsmod | grep -q v4l2loopback && {
    for video in /dev/video*; do
        v4l2-ctl --info -d "$video" | grep -q -E "Card type +: +$label$" && break
    done
} || load_v4l2

ffmpeg                                \
  -re                                 \
  -i "$input"                         \
  -map 0:v                            \
  -vcodec rawvideo                    \
  -vf format=yuv420p${MIRROR:+,hflip} \
  ${SKYPE:+-s 800x600}                \
  -f v4l2                             \
  $video
[[ -z $HOLD ]] && sudo rmmod v4l2loopback 

Le he puesto varias opciones.

SKYPE=1 MIRROR=1 ipcam.sh video_gracioso.mkv

Por ejemplo con el siguiente comando ocurrirá que:

  1. Se emitirá un "vídeo gracioso" en vez de usar la cámara del móvil.
  2. Se voltea horizontal el vídeo ya que sino salen los textos invertidos.

Hay una opción más que es la del HOLD=. Esta opción evitará que se desmonte el módulo una vez termine el vídeo. Es ideal si se quiere usar el script en bucle. Por ejemplo:

while :; do
    sudo SKYPE=1 MIRROR=1 HOLD=1 ipcam.sh video_gracioso.mkv
    sleep 1
done
sudo rmmod v4l2loopback

Y esto es todo. Espero que te sea útil el tutorial.

¡Un saludo!

viernes, 7 de agosto de 2020

Mandar contenido a la cámara

Durante este confinamiento todos hemos empezado a usar mucho más el ordenador para hacer vídeollamadas, bien sea por motivos de teletrabajo, clases o lo que sea.

Esto nos ha obligado a muchos a estar comprando cámaras web que no teníamos.
La cuestión es ¿Para que comprar una cámara web si nuestros dispositivos móviles ya cuentan con varias? Y en muchos casos nada malas precisamente.

Bien pues en este tutorial y en el siguiente os enseñaré como hice yo para poder configurar la cámara de mi Android como si fuese una cámara web compatible con Skype.

Parte 1: Cómo configurar una cámara virtual.

En esta primera parte crearemos una cámara virtual la cual usaremos para poder colocar cualquier vídeo como fuente de entrada.
Esto resulta bastante interesante ya que si se tiene suficiente imaginación se pueden hacer cosas interesantes. Por ejemplo:

  • Reproducir vídeos de Youtube en una vídeollamada de Skype.
  • Colocar una grabación vuestra haciendo como que hacéis un examen.
  • Usar como fuente de entrada para OBS.
  • Etc.

Cargar el driver de v4l2loopback.

Antes de nada tengo que avisar que esto lo he realizado en un Ubuntu 20.04, así que en otras distribuciones algunos pasos pueden ser algo distintos.

Lo primero que necesitaremos es instalar algunas dependencias:

  • v4l2loopback-dkms: Esta nos permitirá crear la cámara virtual.
  • v4l-utils: Esta nos permitirá controlar los detalles de la cámara.
  • ffmpeg: Esta nos permitirá mandar contenido a ella.
  • youtube-dl: Esta nos permitirá usar vídeos de Youtube como fuente (opcional).
sudo apt install v4l2loopback-dkms v4l-utils ffmpeg youtube-dl

Una vez tengamos las dependencias descargadas e instaladas, hay que crear la cámara virtual. Para ello hay que:

sudo modprobe v4l2loopback video_nr=0 card_label="Mi webcam 1"

Esto dará como resultado el dispositivo nuevo /dev/video0.

  • video_nr: Indica que queremos crear la cámara 0 (Parámetro opcional).
  • card_label: Indica el nombre que le queremos dar a la cámara (Parámetro opcional).

Es posible crear más de una cámara, de esta forma podemos simular que tenemos muchas cámaras.
Para ello solo habría que especificar los números y labels separados por comas. Por ejemplo:

sudo modprobe v4l2loopback video_nr=0,3,5 card_label="Mi webcam 1","Mi otra webcam","La 5 pero que es la tercera"

Aquí se pueden consultar todas las opciones del driver.

Para ver sus detalles se puede ejecutar:

v4l2-ctl --info --device 0
v4l2-ctl --info --device 3
v4l2-ctl --info --device 5

Mandar contenido a la cámara.

Una vez creada la camara, solo queda enviarle contenido:

ffmpeg -re -i vídeo.mkv -vf hflip -f v4l2 /dev/video0
  • -re: Nos vale para que el vídeo se reproduzca como mucho a x1.
  • -i: Indica la fuente de vídeo.
  • -vf hflip: Voltea el vídeo horizontalmente (sino los textos salen del revés).
  • -f v4l2 /dev/video0: Indica la cámara virtual por la cual saldrá el vídeo.

Y listo. Ahora podemos abrir el VLC (por ejemplo) y ver lo que sale por la cámara:

Abrimos el VLC -> Pulsamos sobre el botón de play -> Dispositivo de captura:
    - Capture mode: Vídeo cámara.
    - Nombre del dispositivo de vídeo: /dev/video0
Reproducir.

Extra: Mandar un vídeo de Youtube.

Buscamos un vídeo de Youtube, copiamos la URL.
Con la URL lo primero será listar las distintas fuentes de vídeo, donde seleccionaremos el tamaño de la imagen:

youtube-dl -F https://www.youtube.com/watch?v=t9sK3mD5kzc

En mi caso he optado por la 135.

Ahora para mandarlo a la cámara:

fuente=$(youtube-dl -g -f 135 https://www.youtube.com/watch?v=t9sK3mD5kzc)
ffmpeg -re -i $fuente -f v4l2 /dev/video0

Aquí lo único diferente es que he decidido trocear el comando en 2 partes por claridad.

Y esto es todo.

En la próxima entrada comentaré como hice para usar la cámara de mi Android como webcam mediante la WiFi.