Editing video da riga di comando in Linux (tagliare, unire e visualizzare in anteprima)


32

Ho esigenze di editing piuttosto semplici: ho bisogno di tagliare alcuni video, magari inserire alcuni PNG tra loro e unirmi a questi video (non sono necessarie transizioni, effetti, ecc.). Fondamentalmente, pitivifarei quello che voglio - tranne, io uso 640x480 30 fps AVI da una fotocamera, e non appena inserisco più di un paio di minuti di quel tipo di materiale, pitiviinizia a congelare in anteprima e quindi diventa inutilizzabile.

Quindi, ho iniziato a cercare uno strumento da riga di comando per Linux; Immagino che solo ffmpeg( riga di comando - Utilizzo di ffmpeg per tagliare video - Super utente ) e mplayer( Sam - Modifica file video con mencoder su Linux ) sono finora candidati, ma non riesco a trovare esempi dell'uso che ho in mente.

 

Fondamentalmente, immagino che ci sia un encoder e strumenti player (come ffmpegvs ffplay; o mencodervs mplayer) - in modo tale che, per cominciare, la sequenza di modifica possa essere specificata direttamente sulla riga di comando, preferibilmente con risoluzione del frame - uno pseudocodice sarebbe simile a:

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

... oppure, potrebbe avere un file di testo "playlist", come:

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 

... quindi potrebbe essere chiamato con

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

L'idea sarebbe che tutti i video sono nello stesso formato - che consente lo strumento per evitare di transcodifica, e basta fare una "copia grezza", invece (come in mencoder's copy codec: " -oac copy -ovc copy") - o in mancanza di questo, l'audio / video non compresso sarebbe OK (anche se consumerebbe un po 'di spazio). Nel caso del fermo immagine, lo strumento userebbe la codifica impostata dai file video.

 

Il fatto è che posso vederlo finora mencodere ffmpegposso operare su singoli file; ad es. tagliare una singola sezione da un singolo file o unire i file ( mencoderha anche Modifica elenchi di decisioni (EDL) , che può essere utilizzato per eseguire il taglio esatto di frame - in modo da poter definire più aree di taglio, ma viene nuovamente attribuito a un singolo file ). Il che implica che devo lavorare prima a tagliare prima i pezzi dai singoli file (ognuno dei quali richiederebbe il proprio file temporaneo su disco) e poi unirli in un file video finale.

Immagino quindi che esista uno strumento player corrispondente, in grado di leggere lo stesso formato opzione / riga di comando della riga di comando dello strumento di codifica, tranne per il fatto che non genererà un file di output, ma invece riprodurrà il video; ad es. in pseudocodice:

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

... e, dato che c'è abbastanza memoria, genererebbe un'anteprima video a bassa risoluzione nella RAM e la riprodurrebbe in una finestra, offrendo allo stesso tempo alcune interazioni limitate (come mplayerle scorciatoie da tastiera per giocare, mettere in pausa, riavvolgere, fotogramma passo ). Ovviamente, immagino che gli orari di inizio e fine si riferiscano all'intera playlist e includano nella playlist qualsiasi file che potrebbe finire in quella regione.

Pertanto, il risultato finale di tutto ciò sarebbe: operazione dalla riga di comando; nessun file temporaneo durante la modifica - e anche nessun file temporaneo (né transcodifica) durante il rendering dell'output finale ... che io stesso penso sarebbe carino.

Quindi, mentre penso che tutto quanto sopra possa essere un po 'allungato - esiste qualcosa che possa approssimare il flusso di lavoro sopra descritto?


1
Uso spesso mkvmerge anche quando devo dividere / unire video.
Vi.

Grazie per questo, @Vi. - Non ne avevo mai sentito parlare mkvmergeprima, mi assicurerò di provarlo .. Saluti!
sdaau,

Risposte:



23

Ok, dato che non riesco a trovare molto meltsull'utilizzo della riga di comando, ecco alcune note .. (e dopo, vedi questa risposta Usare la sostituzione di processo per ingannare i programmi che prevedono file, con estensioni specifiche come argomento? - Scambio di stack Unix e Linux per uno script esempio via bash)

Per cominciare, esiste un pacchetto Ubuntu / Debian per melt(ho Ubuntu 11.04 con MLT melt 0.6.2); il link fornito da @Ielton è per il Wiki "Media Lovin 'Toolkit" (MLT), che meltfa parte di (ma anche openshote kdenlive). Ecco il link ai file di testo della documentazione dal loro git: mltframework.org/mlt.git/tree - docs / ; nota che il wiki ha una pagina su BuildScripts .

Per ora, il più grande (unico) problema che ho con esso, è che non riesco a trovare un modo per esportare una composizione video non compressa (come pngframe o un formato video non compresso).

 

Innanzitutto, nella riga di comando meltpuoi controllare la riproduzione attraverso i frame; ad esempio, per "creare" uno spazio bianco lungo di 15 fotogrammi e visualizzarlo con il meltlettore incorporato , utilizzare

melt -blank 15

Quando visualizzi con melt, otterrai anche informazioni sulla riga di comando stderrper il player integrato:

$ 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 volta terminata la meltriproduzione, non si chiuderà, quindi è necessario digitare qper uscire.

Dobbiamo notare che ci sono i cosiddetti "produttori" e "consumatori" in melt. Se non viene specificato nulla, il "consumatore" predefinito è una finestra SDL (Simple DirectMedia Layer) che riproduce il video; quindi il comando sopra è lo stesso di:

melt -blank 15 -consumer sdl

Pertanto, se vogliamo salvare ciò che meltviene visualizzato, dovremmo cambiare il consumatore in qualcosa che supporti un formato di file. Per ottenere un elenco di consumatori:

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

Il libdvconsumatore produrrà direttamente i dati in formato DV stdout, quindi per salvare il video in un .dvfile che faresti:

melt -blank 15 -consumer libdv > test.dv

Si noti che tra i consumatori elencati, l'unico formato che ho provato, che può anche essere aperto in un'altra applicazione è libdv(l'ho usato vlccome un'altra applicazione); tuttavia, ciò potrebbe non riuscire per un diverso tipo di transcodifica ( ad es. se invece di uno spazio vuoto, provo a convertire uno snippet da un .flvfile, il file .dv risultante si apre e viene riprodotto vlc, ma è corrotto ).

 

Ora per la parte di modifica ; in sostanza, è possibile specificare una serie di stanze nome-file / in / out direttamente dalla riga di comando; dire che hai un file, video.avi- allora potresti fare:

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

o leggermente meglio formattato:

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

Ciò significa che video.avidal suo frame 30 al suo frame 79 verrà riprodotto; quindi uno spazio vuoto di 15 frame; e quindi di nuovo la video.avisequenza dal frame 30 al frame 79.

Per utilizzare le immagini (diciamo, .png) in una composizione di modifica video:

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

Si noti che per test.png, il in=parametro non deve essere 0 - tuttavia, l'immagine verrà visualizzata per out- intempo; in questo caso, sarebbe più semplice lasciare del in=0tutto fuori il parametro.

 

La cosa buona è che questa sequenza di editing può essere salvata - o come la meltchiama, serializzata - in un file; si noti che ci sono due modi per tale serializzazione: "semplice" o XML. Ad esempio, per salvare il comando sopra come un file serializzato "semplice", possiamo semplicemente aggiungere l' -serialise [filename]opzione 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.

Ora file.meltcontiene:

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

Apparentemente, questo "semplice" formato di file serializzato non contiene un carattere "commenting" - se provo ad aggiungere una " # comment" linea, mi meltlamento con: " Impossibile caricare" # comment " " (ma a parte questo, sembra che tale una riga viene ignorata e la riproduzione continua comunque). " .melt" sembra essere un'estensione che meltriconosce come semplice file serializzato.

Ora, per riprodurre nuovamente questo file serializzato, in linea di principio potremmo semplicemente chiamare melt file.melt, tuttavia una riga di comando più completa sarebbe:

melt melt_file:file.melt -consumer sdl

... il che significherebbe: utilizzare il melt_file"produttore" per aprire file.melte rendere i suoi frame sul "consumatore" sdl(finestra).

Nota che ho l'esperienza, che (diciamo) i .flvvideo vengono riprodotti senza problemi sulla riga di comando - tuttavia, causano un errore di segmentazione quando sono specificati nel file.meltfile serializzato! .dvi video prodotti da meltsoli sembrano funzionare bene in file.melt...

 

Il tipo XML di serializzazione può essere ottenuto utilizzando l' -consumer xml:opzione ( anziché-serialise ) - quindi l'esempio sopra sarebbe ora:

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

Per "riprodurre" il file.mltfile XML appena generato , ora si può fare direttamente melt file.mlt- oppure una riga di comando più completa sarebbe:

melt xml:file.mlt -consumer sdl

... il che significherebbe: usare il xml"produttore" ( nota, in precedenza era un consumatore ) per aprire file.mlte rendere i suoi frame sul "consumatore" sdl(finestra).

Si noti che in questo caso, ho sperimentato che gli stessi .flvvideo che hanno causato la segfault con un semplice file di serializzazione - funzionano perfettamente con un file di serializzazione XML!

In questo caso, il file.mltfile XML risultante ha molte più impostazioni, come risoluzione, frequenza dei fotogrammi, informazioni sul codec ecc., Ma è anche più difficile lavorare direttamente in un editor di testo:

<?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>

Inoltre, ecco un esempio di tagli accurati per i frame: tagliare accuratamente i file video dalla riga di comando - Super User
sdaau

7

La soluzione ffmpeg a questo problema è simile alla seguente:

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

Utilizza pipe denominate, quindi non è possibile creare file temporanei su disco e consente di tagliare blocchi di clip video e aggiungere immagini.

Questo esempio utilizza il tempo 30-60 del primo input, quindi aggiunge il primo minuto del secondo input, quindi inserisce un file di immagine e quindi l'intero terzo video.

Codice estratto da:

Pagina concatenata di ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

pagina superutente Uso di ffmpeg per tagliare il video

pagina superutente https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg


Grazie per questo, ho anche recentemente appreso di ffmpeg-concat , che è scritto in JavaScript (e devi npminstallarlo), quindi ho pensato di menzionarlo
sdaau,

4

Anch'io ho cercato uno strumento del genere e sembra che lo scioglimento sia lo strumento per il lavoro, tuttavia la documentazione è quasi impossibile da capire / mancare. Puoi eseguire quasi tutte le combinazioni di modifica. Avevo dei filmati "action cam" ... il suono era inutilizzabile però. Ho unito il video (h264) insieme, ho aggiunto una dissolvenza di 60 fotogrammi e sostituito il suono con una traccia sonora 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

Puoi leggere di più qui . Il sito Web principale è qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.