Transcoding de video en tiempo real

chromecast_tips_header

Hoy quiero hablarles de un proyecto que acabo de terminar y que, espero, les sirva a más de uno para usarlo, mejorarlo, etc.

Como feliz poseedor de un chromecast me he dado cuenta de la cantidad de formatos de video que hay disponibles en internet y de los pocos que acepta este excelente aparato. Y como desarrollador Android tenía que hacer algo al respecto. A día de hoy hay muchas apps que permiten pasar un video no compatible (por ejemplo FLV) y transmitirlo en tiempo real a chromecast. Pero claro, todas estas soluciones son de código cerrado y, en el mejor de los casos, ofuscado para que no podamos usmear nada para hacer nuestra propia app que haga algo similar.

Buscando por las entrañas de github, xda, etc, no he encontrada nada abierto que nos ejemplifique como aprovecharnos de las distintas herramientas libres que hay para realizar esta tarea. Es más, he visto que es un gran solicitado en sitios de “freelanceo” porque realmente la tendencia es que el multimedia aporta mucho y, con cosas como chromecast y apple tv, transmitir nuestros contenidos a la pantalla remota es esencial.

Entonces lo que libero es un ejemplo funcional de cómo coger una url de un video incompatible (en el ejemplo es un flv) y servirlo en tiempo real mediante un webserver (nanohttpd) convirtiéndolo con ffmpeg.

La app propiamente dicha no conecta con chromecast porque no es la idea que sea una app independiente sino que sirva de ejemplo para poder hacer nuestras propias apps de multimedia que aprovechen el ejemplo para servir el contenido a sus propias soluciones de cast. Aprovecho para recomendar Connect SDK (https://github.com/ConnectSDK/) que nos permite en una única librería transmitir contenido a Chromecast, apple tv, fire tv o, incluso, varias smart tv compatibles. Está un poco buguienta pero se puede mejorar y usarla fácilmente.

Entonces vamos al lío. Acá está la librería https://github.com/munix/FFmpeg-Transcoding-To-Chromecast

¿Cómo funciona?

La verdad que es bastante sencillo. Primero que nada tenemos en el directorio assets el binario de ffmpeg compilado para android (en este caso está compilado para arquitectura armv7a-neon). Al arrancar la app copia el binario dentro de nuestro directorio sandboxeado de la app y le da permisos de ejecución. Luego arrancamos el webserver en el puerto 8080 (se puede cambiar, claro) y obtenemos nuestra ip local para saber la url con la que vamos a servir. Lo siguiente es decirle al webserver mediante un método setUrl cual va a ser la url no compatible que servirá “transcodeada”

Entonces, en mi caso, he montado la url en http://IP:8080/stream. El webserver al recibir una petición a esta url lanza mediante ProcessBuilder el comando que llama a ffmpeg con los parámetros para encodear el video. La salida, por fortuna, es un InputStream que es justo lo que nefcesita NanoHTTPD para servir su respuesta. El resto es coser y cantar porque simplemente formamos la respuesta con algunas headers como Connection: keep-alive,  Transfer-Encoding: chunked y el mime a video/mkv para decirle al que lo reciba que se quede conectado y recibiendo trozos y trozos del video para consumir. De esta manera logramos algo como un streaming porque sino tendríamos que darle el content-lenght y se nos jode lo del tiempo real porque tendríamos que codificar el video, escribirlo a disco, leerlo y escribirlo en la salida de la respuesta… no mola.

Y básicamente eso es todo. Tanto secreto para algo tan simple. Espero que os sea de utilidad

 

 

Déjame un comentario

Intenta ser respetuoso al escribir