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 mp4Desarrollo
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ámaraDesarrollo
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 MediaRecorderDesarrollo
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 libstreamingDesarrollo
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 OpenCVDesarrollo
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 SDKDesarrollo
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 AirDesarrollo
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.
ACTUALIZARWebrtcDesarrollo
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.