Corte con precisión los archivos de video desde la línea de comando

22

Tengo problemas para encontrar una aplicación cli que pueda tomar un archivo de video (avi, mkv y mp4 preferiblemente) y cortar clips muy cortos (2-6 segundos) con precisión de tiempo. Intenté ffmpeg , mencoder , avidemux y mp4box, pero todos cortaron en fotogramas clave que crean más de 6 segundos de clips. ¿Existe una herramienta que vuelva a codificar el archivo de entrada y reduzca el tiempo exacto o lo corte incorrectamente, vuelva a codificar y luego corte con precisión?

curmil
fuente
Probablemente tendrá que volver a codificar antes de cortar para hacerlo bien. Probablemente podría acelerar las cosas cortando primero los fotogramas clave circundantes y solo volver a codificar los fragmentos.
Nifle
44
¿Qué comando FFmpeg has probado exactamente? Creo que si decodifica el video antes (es decir, coloca el -ssparámetro después -i ), debería ser más preciso.
slhck
1
¡El truco de FFmpeg funcionó! No me di cuenta de que la orden importaba tanto. ¿Es lo mismo para alguna de las otras herramientas?
curmil

Respuestas:

23

Cortar video con ffmpeg

Usted puede cortar con precisión vídeos con FFmpeg. Desde la versión 2.5 es muy fácil. Esto, por ejemplo, reduciría 10 segundos, comenzando desde 0 minutos, 3 segundos y 123 milisegundos.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

La posición y el tiempo pueden ser en segundos o en hh:mm:ss[.xxx]forma.

Tenga en cuenta que en estos ejemplos, el video se volverá a codificar utilizando el codificador x264 ; el audio se copia

También puede usar en -tolugar de -tespecificar el punto final en lugar de la duración. En este caso, sin embargo, -toes equivalente a -t, ya que al poner -ssdelante -i, ffmpeg primero buscará ese punto y luego comenzará a salir.

Ver también la entrada Wiki de búsqueda .


Corte preciso para ffmpegversiones anteriores.

Si tiene una versión anterior de ffmpeg, entonces, para una búsqueda precisa, debe colocar el -ssafter -i, lo que hace que el proceso de codificación sea un poco más lento, porque todo el video debe decodificarse primero:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Aquí, -toy -tcomportarse de manera diferente. -t 10crearía un clip de diez segundos de duración, mientras -to 10que crearía un clip de siete segundos de duración.

slhck
fuente
En lugar de -c:v libx264 -c:a libfaaccreo que podemos usar el -acodec copy -vcodec copyque le dice a ffmpeg solo para detectar y usar los mismos códecs que el archivo original. ¿Alguien puede confirmar?
Baodad
2
@Baodad Puedes, pero esto no se cortará con precisión . Al copiar flujos de bits de video / audio, ffmpeg debe comenzar en un fotograma clave, que puede colocarse a cada segundo o incluso más.
slhck
¿Cómo superar el error "Codificador desconocido 'libfaac'"?
Doug
@Doug Elija un codificador diferente, por ejemplo -c:a aac -strict experimental. Esa es la solución más simple.
slhck
1

La única herramienta de línea de comandos de Linux que he encontrado hasta ahora, que puede cortar en el cuadro exacto (o, con precisión de cuadro), es melt( sudo apt-get install melt).

Digamos que tiene un inputvid.mp4- primero verifique su configuración de codificación con say ffmpeg(aquí, solo digo que quiero codificarlo nuevamente -f mp4, pero como el archivo /dev/nullse descarta la salida; redirijo stderr para que pueda pasar por él - nota en el medio , el comando solicita, y debe responder ycon ENTER, para que el proceso continúe y descargue la información útil; esto es con ffmpeg 3.3.3 en Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, entonces podemos ver ffmpegopciones libx264y aaccodificadores para este video; entonces podemos ingresar esto para melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... y meltse corte con la pieza entre los marcos 7235 y 7349 en un nuevo archivo, cut.mp4. Luego, para verificar si los cut.mp4bucles están correctamente, úselos meltnuevamente para reproducirlos dos veces, y reprodúzcalos en una ventana SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... y esto es lo que ffmpegve para este archivo:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

La configuración de codificación de video cut.mp4parece ser idéntica, inputvid.mp4excepto que la tasa de bits de video cambió de 389 kb / sa 526 kb / s, y también la configuración de codificación de audio es casi la misma, excepto que la frecuencia de muestreo cambió de 44100 a 48000 Hz; aunque eso se puede regular con:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... sin embargo, incluso con esto, la tasa de bits de video final para mí termina 337 kb / s. Aún así, los cortes en bucle están bien (y eso incluye audio) cuando se reproducen en bucle, por lo que supongo que esto es realmente preciso en el marco ...

sdaau
fuente
1
meltestá volviendo a codificar el video y utiliza las bibliotecas FFmpeg debajo. Si permite volver a codificar, ffmpeg puede producir la misma salida.
Gyan
Gracias @Gyan - no estaba al tanto de eso (especialmente que meltusa bibliotecas FFmpeg), ¡es bueno saberlo!
sdaau
melt parece más fácil de usar que ffmpeg, todo lo que necesitamos es una forma de especificar tiempos, particularmente tiempos en hr, min, sec o hr, min, sec, ms, que los convierte al marco correcto.
barlop
0

Como dijo Baodad en los comentarios (publico porque no es fácil de encontrar si lees rápidamente), el mejor enfoque es detectar los codificadores de audio / video automáticamente mediante ffmpeg, entonces:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • inicio @ 00: 05: 17.18
  • input = in.mp4
  • parada @ 00: 06: 29.10
  • salida = out.mp4
Gilles Quenot
fuente
2
Esto no vuelve a codificar y no proporciona precisión de cuadro.
Andrea Lazzarotto