¿Es posible crear un nuevo archivo mp4 desde una sola porción de rango de bytes de transmisión?

Si tengo un archivo mp4 remoto en un servidor que admite rangos de bytes, ¿es posible recuperar un rango de un solo byte y crear un mp4 nuevo / autocontenido a partir de esos datos de rango?

Si bash escribir un dato de rango de bytes devuelto directamente en un archivo mp4 usando fs.createWriteStream(remoteFilename) archivo fs.createWriteStream(remoteFilename) , no obtiene los metadatos del video (duración, dimensiones, etc.) que necesita para poder reproducirse.

Cuando obtengo un rango de bytes que comienza con 0 y termina con XX, se puede reproducir la salida mp4, pero tendrá los metadatos de duración de toda la duración del video y se congelará la pantalla cuando el rango de bytes se realice por el rest de la duración hora.

¿De qué otra manera puedo tomar un rango de bytes y crear un archivo .mp4 independiente desde ese objeto de flujo?

El objective de esto es evitar descargar todo el archivo de 10 minutos antes de que pueda hacer un clip de 5 segundos con ffmpeg. Si puedo calcular y descargar el rango de bytes, debería haber una forma de escribirlo en un archivo mp4 independiente.

Gracias de antemano por cualquier ayuda que pueda proporcionar.

Los archivos MP4 están estructurados con cajas. Dos de ellos principales son moov y mdat (caso general de MP4 no fragmentado):

  • cuadro de moov: contiene otros cuadros :): cada uno de ellos contiene información sobre los datos codificados presentes en el cuadro mdat (moov = metadatos sobre el archivo MP4). Las metadatas típicas son la duración, la frecuencia de cuadros, la información de los códecs, la referencia a los cuadros de video / audio …
  • mdat box: contiene los datos codificados reales para el archivo. Puede provenir de varios códecs e incluye datos de audio y video (o solo uno de ellos, si es que lo es). Para H264, las unidades NAL están contenidas dentro de la caja mdat.

El cuadro de moov está (debería estar) al comienzo del archivo para la entrega web del archivo MP4, por lo que si escribe una solicitud de rango de bytes de 0 a XX, es probable que obtenga el cuadro de moov completo + una cierta cantidad de datos mdat. Por lo tanto, el archivo se puede reproducir hasta cierto punto. Si tiene un rango de bytes de YY a XX, es probable que no obtenga una caja de moov decente, pero sí una gran cantidad de mdat que, como tal, no se pueden usar a menos que se reempaquen en un archivo MP4 con una caja de moov adecuada que haga referencia a la información sobre el mdat de “corte” .

Es posible volver a crear un archivo MP4 válido a partir de una porción de rango de bytes, pero requiere un conocimiento avanzado de la estructura del formato de archivo MP4 (es necesario recuperar el cuadro de Moov para que sea soportable). El formato de archivo MP4 se basa en el formato de archivo de medios base ISO , que se especificó como ISO / IEC 14496-12 (MPEG-4 Parte 12).

Conozco 2 bibliotecas que podrían ayudarlo a hacer lo que quiera: una en PHP y otra en Java . No sé si existe tal lib para node.js (supongo que podría portarse). Incluso si no los usa, las 2 bibliotecas anteriores contienen información valiosa sobre el tema.

Para responder a su pregunta, puede abordar el problema con un ángulo diferente. Saber qué parte del archivo desea en milisegundos puede ejecutar un comando ffmpeg para unir el lado del servidor de archivos MP4 de longitud completa en uno más pequeño y luego hacer lo que necesita con este nuevo archivo más pequeño de MP4 (ya que no necesita para descargar datos innecesarios en el cliente).

El comando ffmpeg para eso es (en este caso, cortado a 1 minuto del inicio del archivo):

 ffmpeg -i input.mp4 -ss 00:00:00.000 -t 00:01:00.000 -c:a copy -c:v copy output.mp4 

Vea esta publicación para obtener más información sobre la línea de comando anterior

Esto se hace bastante rápido, ya que la estructura de archivos MP4 simplemente se reorganiza sin volver a transcodificar.

EDITAR: ¿ O puedo usar ffmpeg en un archivo remoto y crear el nuevo clip localmente?

 ffmpeg -ss 00:01:00.000 -i "http://myfile.mp4" -t 00:02:00.000 -c:a copy -c:v copy output.mp4 

Suponiendo que tiene ffmpeg en su cliente (aplicación / web) si ejecuta el comando anterior, ffmpeg buscará el mp4 en la URL de entrada, buscará 1 minuto y cortará 2 minutos desde allí y escribirá el contenido generado en output.mp4 localmente ( sin descargar el archivo completo del curso).

ffmpeg debe comstackrse con soporte para la entrada del protocolo http (que encontrará en la mayoría de los binarios). Puede leer aquí para obtener más información sobre dónde colocar el parámetro -ss (pros / contras).