Android: grabación y transmisión al mismo tiempo

Esto no es realmente una pregunta, sino una presentación de todos mis intentos de resolver una de las funcionalidades más desafiantes que enfrenté.

yo suelolibstreaming biblioteca para transmitir videos en tiempo real aServidor Wowza y necesito grabarlo al mismo tiempo dentro de la tarjeta SD. A continuación presento todos mis intentos para recopilar nuevas ideas de la comunidad.

Copie bytes de la secuencia de libstreaming a un archivo mp4

Desarrollo

Creamos una intercepción en la biblioteca libstreaming para copiar todos los bytes enviados a un archivo mp4. Libstreaming envía los bytes al servidor Wowza a través de un LocalSocket. Utiliza MediaRecorder para acceder a la cámara y al micrófono del dispositivo y establece el archivo de salida como flujo de entrada de LocalSocket. Lo que hacemos es crear un contenedor alrededor de esta secuencia de entrada que se extiende desde InputStream y crear una secuencia de salida de archivo dentro de ella. Entonces, cada vez que libstreaming ejecuta una lectura sobre el flujo de entrada del LocaSocket, copiamos todos los datos al flujo de salida, tratando de crear un archivo MP4 válido.

Impedimento

Cuando intentamos leer el archivo, está dañado. Nos dimos cuenta de que falta información meta del archivo MP4. Específicamente el átomo de moov. Intentamos retrasar el cierre de la transmisión para dar tiempo a enviar este encabezado (esto todavía era una suposición) pero no funcionó. Para probar la coherencia de estos datos, utilizamos un software pago para intentar recuperar el video, incluido el encabezado. Se volvió jugable, pero en su mayoría era pantalla verde. Entonces esto se convirtió en una solución no confiable. También intentamos usar "untrunc", un programa gratuito de línea de comandos de código abierto y ni siquiera podía comenzar la recuperación, ya que no había un átomo de moov.

Use ffmpeg compilado en Android para acceder a la cámara

Desarrollo

FFMPEG tiene un complemento gradle con una interfaz java para usarlo dentro de las aplicaciones de Android. Pensamos que podíamos acceder a la cámara a través de la línea de comando (probablemente esté en "/ dev / video0") y la enviamos al servidor de medios.

Impedimento

Recibimos el error "Permiso denegado" al intentar acceder a la cámara. La solución sería rootear el dispositivo para tener acceso a él, pero esto hace que los teléfonos pierdan su garantía y podría bloquearlos.

Utilice ffmpeg compilado en Android combinado con MediaRecorder

Desarrollo

Intentamos hacer que FFMPEG transmita un archivo mp4 que se graba dentro del teléfono a través de MediaRecorder

Impedimento

FFMPEG no puede transmitir archivos MP4 que aún no se hayan realizado con la grabación.

Utilice ffmpeg compilado en Android con libstreaming

Desarrollo

Libstreaming usa LocalServerSocket como la conexión entre la aplicación y el servidor, por lo que pensamos que podríamos usar ffmpeg conectado con la dirección local LocalServerSocket para copiar la transmisión directamente a un archivo local dentro de la tarjeta SD. Justo después de que comenzó la transmisión, también ejecutamos el comando ffmpeg para comenzar a grabar los datos en un archivo. Usando ffmpeg, creemos que crearía un archivo MP4 de la manera adecuada, lo que significa que incluye el encabezado del átomo moov.

Impedimento

La "dirección" creada no es legible a través de la línea de comando, como una dirección local dentro del teléfono. Entonces la copia no es posible.

Use OpenCV

Desarrollo

OpenCV es una biblioteca multiplataforma de código abierto que proporciona bloques de construcción para experimentos y aplicaciones de visión por computadora. Ofrece interfaces de alto nivel para capturar, procesar y presentar datos de imágenes. Tiene sus propias API para conectarse con la cámara del dispositivo, por lo que comenzamos a estudiarla para ver si tenía las funcionalidades necesarias para transmitir y grabar al mismo tiempo.

Impedimento

Descubrimos que la biblioteca no está realmente definida para hacer esto, sino más bien como manipulación matemática de imágenes. Incluso obtuvimos la recomendación de usar libstreaming (que ya lo hacemos).

Use Kickflip SDK

Desarrollo

Kickflip es un servicio de transmisión de medios que proporciona su propio SDK para el desarrollo en Android e iOS. También usa HLS en lugar de RTMP, que es un protocolo más nuevo.

Impedimento

Su SDK requiere que creamos una Actividad con vista de cámara que ocupe toda la pantalla del dispositivo, rompiendo la usabilidad de nuestra aplicación.

Use Adobe Air

Desarrollo

Comenzamos a consultar a otros desarrolladores de aplicaciones que ya están disponibles en Play Store, que ya transmiten a los servidores.

Impedimento

Al ponerse en contacto con esos desarrolladores, aseguraron que no sería posible grabar y transmitir al mismo tiempo utilizando esta tecnología. Además, tendríamos que rehacer toda la aplicación desde cero usando Adobe Air.

ACTUALIZARWebrtc

Desarrollo

Comenzamos a usar WebRTC siguiendoeste gran proyecto. Incluimos el servidor de señalización en nuestro servidor NODEJS y comenzamos a hacer el protocolo de enlace estándar a través del socket. Todavía estábamos alternando entre la grabación local y la transmisión a través de webrtc.

Impedimento

Webrtc no funciona en todas las configuraciones de red. Aparte de eso, la adquisición de la cámara es todo código nativo, lo que hace mucho más difícil intentar copiar los bytes o interceptarlo.

Respuestas a la pregunta(1)

Su respuesta a la pregunta