Cortar un segmento de tiempo

Cortar un segmento de tiempo

He leído sobre cortar y empalmar usandoconcatpero esto no es suficiente para mí.

Me gustaría cortar partes de video marcadas y unirlas en un solo archivo de video sin volver a codificarlo. ¿Es posible cortar y fusionar (en memoria) de una sola vez?

En teoría, no debería haber un límite en la cantidad de partes de video que se pueden cortar o unir. El audio debe estar sincronizado.

Vídeo: H.264+AAC

Editar:

De las respuestas aprendí que aún es necesaria la recodificación de video.

Me gustaría aclarar que cortar videoclips desde la mitad de un archivo de video se puede realizar en varios pasos. Estaba pensando que procesar el vídeo de una vez sería beneficioso para el rendimiento al guardar parte de la actividad de E/S. Sin embargo, no es un objetivo en sí mismo.

Respuesta1

Tu pregunta, si la entendí bien, tiene cuatro partes principales:

  • Cómo cortar un segmento de tiempo de una película
  • Cómo fusionar varios segmentos juntos
  • Cómo hacer lo anterior sin transcodificar la película y, por lo tanto, no perder calidad
  • Cómo hacer lo anterior de manera eficiente en términos de velocidad

Cortar un segmento de tiempo

Puede cortar un segmento saltando a su punto inicial con la -ssopción, luego configurando la duración del segmento con -to configurando el punto final con -to:

# skip 30 seconds, then copy the next 60 seconds
ffmpeg -ss 30 -t 60 full-movie.mp4 segment.mp4

En la documentación de ffmpeg por favor consulte la sección5.4 Opciones principalescon respecto a la diferencia entre colocar las opciones -ssy -tantes del archivo de entrada o antes del archivo de salida. Una vez que experimente con esto, puede encontrar que esta diferencia sea relevante en su caso.

Nota importante: el ejemplo anterior hace que el vídeo se transcodifique. Discutiremos a continuación la posibilidad de hacer esto sin transcodificación.

Fusionando varios segmentos

Hay tres métodos principales para realizar una combinación de películas; dos de ellos se explican mejor en esteartículo wiki de ffmpeg, y el tercero es eldemultiplexor concat. Si todos sus segmentos son idénticos en términos de especificación de codificación a/v y formato de contenedor, probablemente encontrará que el método más sencillo es el concat:protocolo:

# merge the segments
ffmpeg -i "concat:seg1.mp4|seg2.mp4|seg3.mp4" final.mp4

Es importante señalar que esta fusión, al igual que el corte, transcodifica una vez más la película, por lo que tenemos aquí una transcodificación de una transcodificación, lo que potencialmente degrada la calidad del vídeo, por lo queen realidad¡Queremos evitar esta transcodificación tanto como podamos!

Cortar y fusionar sin transcodificar

La razón por la que los ejemplos de las secciones anteriores requieren transcodificación es porque cada archivo y cada segmento resultante es una película independiente que se empaquetó para proporcionar todo lo que espera al abrir una película completa, como la duración de la película y otros. metadatos. Pero bueno, no buscas reproducirlas como películas independientes, sino que quieres que estos segmentos formen parte de una transmisión de video más grande. Entonces, en lugar de servir ffmpeg con películas en caja, será mejor que vuelvas a empaquetar (re-mux) los archivos de entrada en un contenedor de transmisión en tiempo real, olvidándote de los encabezados que realmente no necesitas en este momento. En el caso de H.264, el formato mux de transmisión se llama MPEG-TS, y así es como puede volver a mezclar su transmisión sin transcodificarla:

# re-muxing the whole movie (see a better option in next example)
ffmpeg -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb full-movies-as-ts.ts

Bueno, como ya lo estás haciendo, también puedes aprovechar esta oportunidad para cortar sólo el segmento que necesitas:

# skip 30 seconds and re-mux a 60 seconds segment
ffmpeg -ss 30 -t 60 -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb segment.ts

Cuando fusionas los segmentos TS, también puedes volver a mezclarlos en un contenedor mp4:

# merge the segments and re-mux them as mp4
ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c:v copy -c:a copy -movflags empty_moov -flags global_header -bsf:v dump_extra edited-final.mp4

Así que ahora tenemos todo hecho sin transcodificar la película, preservando la calidad original. Pero como siempre, hay una advertencia...

ADVERTENCIA: El corte sólo se puede realizar en un límite de fotograma clave. Explicación: H.264 organiza los fotogramas comprimidos en paquetes, cada uno de los cuales comienza con una imagen completa pero comprimida del primer fotograma, seguida de los deltas de los siguientes fotogramas, lo que reduce el almacenamiento necesario para cada paquete. Para nuestro propósito, cada paquete es como un zip sellado de todos los marcos durante ese período: es todo o nada. Si desea solo una parte del paquete, debe descomprimirlo y volver a comprimirlo, en otras palabras, transcodificarlo. Por lo tanto, el método anterior es relevante sólo si tiene un fotograma clave en cada posición donde desea cortar la película. Por ejemplo, si tienes un fotograma clave cada 5 segundos, puedes cortarlo solo cada 5 segundos.

Así que ahora la pregunta es si puedes aceptar las limitaciones en los puntos de corte, particularmente porque probablemente no tengas idea de en qué parte de tu película tienes fotogramas clave. Y esa es la razón por la que sugerí leer arriba5.4 Opciones principalessobre especificar -sy -tantes de la entrada o antes de la salida. Si especifica antes de la entrada, ffmpeg encontrará un fotograma clave cercano para realizar su solicitud, que estará "más o menos" donde deseaba realizar el corte. Si no te importa la precisión del corte, entonces bien, hazlo.

Pero si necesitas que el corte esté en esa posición precisa, entonces no tienes otra opción, deberás decodificar la película para poder localizar el fotograma que estás buscando. Bueno, al menos tenemosalgunoBuenas noticias: en lugar de transcodificar y volver a transcodificar, puedes hacerlo con una sola transcodificación, lo que mejora un poco la situación:

# skip PRECISELY 30 seconds and transcode a 60 seconds TS segment
ffmpeg -i full-movie.mp4 -ss 30 -t 60 -bsf:v h264_mp4toannexb segment.ts

Dado que los segmentos resultantes estarán en TS, no es necesario realizar otra transcodificación al fusionar los segmentos.

Velocidad

En elArtículo de ffmpeg wiki sobre la fusiónhay una explicación sobre cómo ejecutar todo el proceso a través de tuberías, eliminando así la necesidad de archivos intermedios y acelerando todo el proceso.NO.te llevarámás extenso. La razón por la que hacerlo todo en la memoria llevará más tiempo no es porque durará más, sino porque no obtendrá resultados intermedios mientras descubre cómo hacer todo, y se encontrará ejecutando todo el proceso una y otra vez. de nuevo. Entonces la teoría de las tuberías es buena, pero en tu caso debes comenzar trabajando y perfeccionando cada paso. Descubrirá que hacer que todo funcione y produzca un resultado decente requerirá algunos ajustes y ajustes adicionales. Una vez que domine todo el proceso y desee realizar algunas secuencias de comandos para la edición masiva automatizada, podrá revisar el concepto de tubería.

Espero que lo anterior ayude.

información relacionada