Edición de video de línea de comandos en Linux (cortar, unir y previsualizar)

32

Tengo necesidades de edición bastante simples: necesito cortar algunos videos, tal vez insertar algunos PNG entre ellos y unirlos (no necesita transiciones, efectos, etc.). Básicamente, pitiviharía lo que quisiera, excepto que uso 640x480 30 fps AVI de una cámara, y tan pronto como agrego más de un par de minutos de ese tipo de material, pitivicomienza a congelarse en la vista previa y, por lo tanto, se vuelve inutilizable.

Entonces, comencé a buscar una herramienta de línea de comandos para Linux; Supongo que solo ffmpeg( línea de comando - Usar ffmpeg para cortar video - Super Usuario ) y mplayer( Sam - Editar archivo de video con mencoder en linux ) son candidatos hasta ahora, pero no puedo encontrar ejemplos del uso que tengo en mente.

 

Básicamente, me imagino que hay un codificador y herramientas de reproducción (como ffmpegvs ffplay; o mencodervs mplayer), de modo que, para comenzar, la secuencia de edición podría especificarse directamente en la línea de comando, preferiblemente con resolución de cuadro, un pseudocódigo se vería así:

videnctool -compose --file=vid1.avi --start=00:00:30:12 --end=00:01:45:00 --file=vid2.avi --start=00:05:00:00 --end=00:07:12:25 --file=mypicture.png --duration=00:00:02:00 --file=vid3.avi --start=00:02:00:00 --end=00:02:45:10 --output=editedvid.avi

... o podría tener un archivo de texto de "lista de reproducción", como:

vid1.avi      00:00:30:12 00:01:45:00 
vid2.avi      00:05:00:00 00:07:12:25 
mypicture.png -           00:00:02:00
vid3.avi      00:02:00:00 00:02:45:10 

... por lo que podría llamarse con

videnctool -compose --playlist=playlist.txt --output=editedvid.avi

La idea aquí sería que todos los videos estén en el mismo formato, lo que permite que la herramienta evite la transcodificación, y simplemente haga una "copia en bruto" (como en mencoderel códec de copia : " -oac copy -ovc copy"), o en ausencia de eso, el audio / video sin comprimir estaría bien (aunque consumiría un poco de espacio). En el caso de la imagen fija, la herramienta usaría la codificación establecida por los archivos de video.

 

La cuestión es que hasta ahora puedo ver eso mencodery ffmpegpuedo operar en archivos individuales; por ejemplo, cortar una sola sección de un solo archivo, o unir archivos ( mencodertambién tiene Editar Listas de Decisiones (EDL) , que se puede usar para hacer un corte exacto del marco - para que pueda definir múltiples regiones de corte, pero nuevamente se atribuye a un solo archivo ) Lo que implica que primero tengo que trabajar cortando piezas de archivos individuales (cada una de las cuales exigiría un archivo temporal propio en el disco), y luego unirlas en un archivo de video final.

Entonces me imagino que hay una herramienta de reproducción correspondiente, que puede leer el mismo formato de opción de línea de comando / archivo de lista de reproducción que la herramienta de codificación, excepto que no generará un archivo de salida, sino que reproducirá el video; por ejemplo, en pseudocódigo:

vidplaytool --playlist=playlist.txt --start=00:01:14 --end=00:03:13

... y, dado que hay suficiente memoria, generaría una vista previa de video de baja resolución en RAM y la reproduciría en una ventana, al tiempo que ofrece una interacción limitada (como mplayerlos atajos de teclado para reproducir, pausar, rebobinar, marco de pasos ) Por supuesto, me imagino que las horas de inicio y finalización hacen referencia a toda la lista de reproducción e incluyen cualquier archivo que pueda terminar en esa región en la lista de reproducción.

Por lo tanto, el resultado final de todo esto sería: operación de línea de comando; no hay archivos temporales mientras se realiza la edición, y tampoco archivos temporales (ni transcodificación) cuando se procesa la salida final ... lo cual creo que sería bueno.

Entonces, si bien creo que todo lo anterior puede ser un poco exagerado, ¿existe algo que se aproximaría al flujo de trabajo descrito anteriormente?

sdaau
fuente
1
También suelo usar mkvmerge cuando necesito dividir / unir videos.
Vi.
Gracias por eso, @Vi. - Nunca había oído hablar mkvmergeantes, se asegurará de que lo revise ... ¡Salud!
sdaau el

Respuestas:

17

Sí hay. Intenta usar la aplicación llamada "Melt". Vea la documentación aquí:

https://www.mltframework.org/docs/melt/

Si usa una distribución derivada de Debian:

apt-get install melt
Ielton
fuente
en mac:brew install mlt
kraftydevil
23

Ok, ya que no puedo encontrar mucho sobre el meltuso de la línea de comandos, aquí hay algunas notas ... (y después de esto, vea esta respuesta ¿Cómo usar la sustitución de procesos para engañar a los programas que esperan archivos, con extensiones específicas como argumento? - Unix y Linux Stack Exchange para un script ejemplo a través de bash)

Para empezar, hay un paquete Ubuntu / Debian para melt(tengo Ubuntu 11.04 con MLT melt 0.6.2); el enlace proporcionado por @Ielton es para el Wiki "Media Lovin 'Toolkit" (MLT), que meltforma parte de (pero también openshoty kdenlive). Aquí está el enlace a los archivos de texto de la documentación de su git: mltframework.org/mlt.git/tree - docs / ; tenga en cuenta que el wiki tiene una página sobre BuildScripts .

Por ahora, el mayor (único) problema que tengo con él es que no puedo encontrar una manera de exportar una composición de video sin comprimir (ya sea como pngcuadros o algún formato de video sin comprimir).

 

Primero, en la línea de comandos meltpuede controlar la reproducción a través de cuadros; por ejemplo, para "crear" un espacio en blanco blanco de 15 cuadros y verlo con el meltreproductor incorporado, use

melt -blank 15

Cuando veas con melt, también obtendrás una información de línea de comando stderrpara el reproductor incorporado:

$ melt -blank 15 
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|1=-10| |2= -5| |3= -2| |4= -1| |5=  0| |6=  1| |7=  2| |8=  5| |9= 10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
+---------------------------------------------------------------------+
|               H = back 1 minute,  L = forward 1 minute              |
|                 h = previous frame,  l = next frame                 |
|           g = start of clip, j = next clip, k = previous clip       |
|                0 = restart, q = quit, space = play                  |
+---------------------------------------------------------------------+
Current Position:         15

Una vez meltque termine la reproducción, no saldrá, por lo que debe escribir qpara salir.

Debemos tener en cuenta que hay los llamados "productores" y "consumidores" en melt. Si no se especifica nada, el "consumidor" predeterminado es una ventana SDL (Simple DirectMedia Layer) que reproduce el video; entonces el comando anterior es el mismo que:

melt -blank 15 -consumer sdl

Por lo tanto, si queremos guardar lo que se meltmuestra, debemos cambiar al consumidor a algo que admita un formato de archivo. Para obtener una lista de consumidores:

$ melt -query "consumers"
---
consumers:
  - sdl
  - sdl_audio
  - sdl_preview
  - sdl_still
  - gtk2_preview
  - avformat
  - libdv
  - xml
  - decklink
  - null
...

El libdvconsumidor emitirá datos con formato DV directamente stdout, por lo que para guardar el video en un .dvarchivo que haría:

melt -blank 15 -consumer libdv > test.dv

Tenga en cuenta que de los consumidores enumerados, el único formato que he probado, que también se puede abrir en otra aplicación es libdv(lo usé vlccomo otra aplicación); sin embargo, esto puede fallar para un tipo diferente de transcodificación ( por ejemplo, si en lugar de un espacio en blanco, trato de convertir un fragmento de un .flvarchivo, el archivo .dv resultante se abre y se reproduce vlc, pero está dañado ).

 

Ahora para la parte de edición ; esencialmente, puede especificar una serie de estrofas de nombre / entrada / salida de archivo directamente en la línea de comando; diga que tiene un archivo, video.avientonces podría hacer:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79

o ligeramente mejor formateado:

melt \ 
video.avi in=30 out=79 \ 
-blank 15 \
video.avi in=30 out=79

Esto significa video.avique se jugará desde su cuadro 30 hasta su cuadro 79; luego un espacio en blanco de 15 cuadros; y luego la video.avisecuencia del cuadro 30 al cuadro 79 nuevamente.

Para utilizar imágenes (por ejemplo, .png) en una composición de edición de video:

melt \
video.avi in=30 out=79 \
test.png in=0 out=15 \
video.avi in=30 out=79 \
-blank 15

Tenga en cuenta que para test.png, in=el parámetro no tiene que ser 0 - Sin embargo, la imagen se visualiza para out- intiempo; en este caso, sería más fácil simplemente dejar el in=0parámetro por completo.

 

Lo bueno es que esta secuencia de edición se puede guardar, o como se meltllama, serializar , en un archivo; Tenga en cuenta que hay dos formas de dicha serialización: "simple" o XML. Por ejemplo, para guardar el comando anterior como un archivo serializado "simple", simplemente podemos agregar el -serialise [filename]interruptor al comando:

$ melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -serialise file.melt 
Project saved as file.melt.

Ahora el file.meltcontiene:

video.avi
in=30
out=79
-blank
15
video.avi
in=30
out=79

Aparentemente, este formato de archivo serializado "simple" no contiene un carácter de "comentario". Si trato de agregar una " # comment" línea, me meltquejo con: ' Error al cargar "# comentario" ' (pero aparte de eso, parece que tal se ignora una línea y la reproducción continúa de todos modos). " .melt" parece ser una extensión que meltreconoce como simple archivo serializado.

Ahora, para reproducir este archivo serializado, en principio podríamos simplemente llamar melt file.melt, sin embargo, una línea de comando más completa sería:

melt melt_file:file.melt -consumer sdl

... lo que significaría: usar el melt_file"productor" para abrir file.melty renderizar sus marcos en el "consumidor" sdl(ventana).

Tenga en cuenta que tengo la experiencia, que (digamos) los .flvvideos se reproducen sin problemas en la línea de comando; sin embargo, ¡causan una falla de segmentación cuando se especifican en el file.meltarchivo serializado! .dvlos videos producidos por meltsí mismos parecen funcionar bien en file.melt...

 

El tipo de serialización XML se puede lograr utilizando el -consumer xml:conmutador (en lugar de-serialise ), por lo que el ejemplo anterior ahora sería:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -consumer xml:file.mlt

Para "reproducir" el file.mltarchivo XML recién generado , ahora se puede hacer directamente melt file.mlt, o una línea de comando más completa sería:

melt xml:file.mlt -consumer sdl

... lo que significaría: use el xml"productor" ( nota, anteriormente era un consumidor ) para abrir file.mlty renderizar sus marcos en el "consumidor" sdl(ventana).

Tenga en cuenta que en este caso, he experimentado que los mismos .flvvideos que causaron la falla con un simple archivo de serialización, ¡funcionan bien con un archivo de serialización XML!

En este caso, el file.mltarchivo XML resultante tiene muchas más configuraciones, como resolución, velocidad de cuadros, información de códec, etc., pero también es más difícil trabajar directamente en un editor de texto:

<?xml version="1.0" encoding="utf-8"?>
<mlt root="/path/to" title="video.avi">
  <profile description="automatic" width="320" height="240" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="320" display_aspect_den="240" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
  <producer id="producer0" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <producer id="producer1" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <playlist id="playlist0">
    <entry producer="producer0" in="0" out="49"/>
    <blank length="16"/>
    <entry producer="producer1" in="0" out="49"/>
  </playlist>
  <tractor id="tractor0" title="video.avi" global_feed="1" in="0" out="115">
    <track producer="playlist0"/>
  </tractor>
</mlt>
sdaau
fuente
Además, aquí hay un ejemplo para cortes con precisión de fotograma: corte con precisión archivos de video desde la línea de comandos
Superusuario
7

La solución ffmpeg a este problema se parece a esto:

mkfifo temp1 temp2 temp3
ffmpeg -i input.wmv -ss 30 -to 60 -c copy output.wmv temp1 2> /dev/null & \
ffmpeg -i input2.wmv -t 60 -c copy temp2 2> /dev/null & \
ffmpeg -i input3.wmv -i image.png -filter_complex "[0:v][1:v] \
overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy temp3 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp1|temp2|temp3" -c copy output.mp4

Utiliza canalizaciones con nombre, por lo que no se pueden crear archivos temporales en el disco y le permite cortar fragmentos de los videoclips y agregar imágenes.

Este ejemplo usa el tiempo 30-60 de la primera entrada, y luego agrega el primer minuto de la segunda entrada, luego inserta un archivo de imagen y luego el tercer video completo.

Código levantado de:

Página de concatenación de ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

página de superusuario Uso de ffmpeg para cortar video

página de superusuario https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg

codeMonkey
fuente
Gracias por eso, también me enteré recientemente de ffmpeg-concat , que está escrito en JavaScript (y necesitas npminstalarlo), así que pensé en mencionarlo
sdaau
4

Yo también he estado buscando una herramienta de este tipo y parece que Melt es la herramienta para el trabajo, sin embargo, la documentación es casi imposible de entender / falta. Puedes hacer casi cualquier combinación de edición. Tenía algunas imágenes de 'cámara de acción' ... sin embargo, el sonido era inutilizable. Me uní al video (h264), agregué un desvanecimiento de 60 cuadros y reemplacé el sonido con una pista de sonido usando:

% melt -video-track vid1.avi vid2.avi -mix 60 -mixer luma vid3.avi \
   -mix 60 -mixer luma -audio-track vorbis:track1.ogg vorbis:track2.ogg \
   -consumer avformat:OUT.avi acodec=libmp3lame vcodec=libx264

Puedes leer más sobre esto aquí . El sitio web principal está aquí .

usuario196805
fuente