Befehlszeilen-Videobearbeitung unter Linux (Ausschneiden, Verbinden und Vorschau)


32

Ich habe ziemlich einfache Bearbeitungsanforderungen - ich muss einige Videos zerschneiden, möglicherweise einige PNGs dazwischen einfügen und diese Videos zusammenfügen (Übergänge, Effekte usw. sind nicht erforderlich). Grundsätzlich pitiviwürde ich tun, was ich will - außer, ich verwende AVIs mit 640 x 480 und 30 fps von einer Kamera und sobald ich mehr als ein paar Minuten dieses Materials einlege, pitivifriert die Vorschau ein und wird somit unbrauchbar.

Also suchte ich nach einem Befehlszeilentool für Linux. Ich denke nur ffmpeg( Kommandozeile - Verwenden von ffmpeg zum Schneiden von Videos - Super User ) und mplayer( Sam - Bearbeiten von Videodateien mit Mencoder unter Linux ) sind bisher Kandidaten, aber ich kann keine Beispiele für die Verwendung finden, die ich mir vorgestellt habe.

 

Grundsätzlich würde ich mir vorstellen, dass es Encoder- und Player-Tools (wie ffmpegvs ffplay; oder mencodervs mplayer) gibt - so dass zunächst die Bearbeitungssequenz direkt in der Befehlszeile angegeben werden kann, vorzugsweise mit Frame-Auflösung - ein Pseudocode wie folgt aussehen würde:

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

... oder es könnte eine "Playlist" -Textdatei geben, wie:

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 

... so könnte man es nennen mit

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

Die Idee hier wäre, dass alle Videos im gleichen Format sind - das Werkzeug zu vermeiden Umcodierung ermöglichen, und einfach eine „rohe Kopie“ statt (wie in mencoder‚s kopieren Codec:" -oac copy -ovc copy„) - oder in Mangel an , dass, unkomprimiertes Audio / Video wäre in Ordnung (obwohl es ein bisschen Platz verschlingen würde). Im Fall des Standbilds würde das Tool die von den Videodateien festgelegte Codierung verwenden.

 

Die Sache ist, ich kann das soweit sehen mencoderund ffmpegeinzelne Dateien bearbeiten; B. einen einzelnen Abschnitt aus einer einzelnen Datei ausschneiden oder Dateien zusammenfügen ( mencoderverfügt auch über EDL ( Edit Decision Lists)) , mit der Sie rahmengenaue Schnitte ausführen können. Sie können also mehrere Schnittbereiche definieren, die jedoch wieder einer einzelnen Datei zugeordnet werden ). Was bedeutet, dass ich zuerst einzelne Dateien ausschneiden muss (jede davon würde eine eigene temporäre Datei auf der Festplatte erfordern) und sie dann zu einer endgültigen Videodatei zusammenfügen muss.

Ich würde mir dann vorstellen, dass es ein entsprechendes Player-Tool gibt, das dasselbe Befehlszeilenoptionsformat / dieselbe Wiedergabelistendatei wie das Codierungs-Tool lesen kann - es wird jedoch keine Ausgabedatei generiert, sondern das Video abgespielt. zB im Pseudocode:

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

... und, da es genug Speicher, wäre es eine Low-Res - Video - Vorschau in RAM, erzeugen und es wieder in einem Fenster spielen, während einige begrenzte Interaktion anbieten (wie mplayer‚s Tastenkombinationen für Wiedergabe, Pause, Rücklauf, Schritt Rahmen ). Natürlich würde ich mir vorstellen, dass sich die Start- und Endzeiten auf die gesamte Wiedergabeliste beziehen und alle Dateien, die möglicherweise in dieser Region landen, in die Wiedergabeliste aufnehmen.

Das Endergebnis all dessen wäre also: Befehlszeilenoperation; keine temporären Dateien während der Bearbeitung - und auch keine temporären Dateien (noch Transcodierung) beim Rendern der endgültigen Ausgabe ... was ich selbst schön finde.

Also, während ich denke, dass all das ein bisschen langwierig sein könnte - gibt es irgendetwas, das den oben beschriebenen Workflow annähern würde?


1
Ich benutze mkvmerge auch oft, wenn ich Videos teilen / verbinden muss.
Vi.

Danke dafür, @Vi. - hatte noch nie davon gehört mkvmerge, werde mich darum kümmern .. Prost!
Sdaau

Antworten:



23

Ok, da ich nicht viel über die Verwendung der meltBefehlszeile herausfinden kann , hier ein paar Hinweise. (Und danach diese Antwort. Verwenden der Prozessersetzung, um Programme auszutricksen, die Dateien mit bestimmten Erweiterungen als Argument erwarten? - Unix & Linux Stack Exchange für ein Skript Beispiel via bash)

Zu Beginn - gibt es ein Ubuntu / Debian-Paket für melt(ich habe Ubuntu 11.04 mit MLT Melt 0.6.2); Der von @Ielton angegebene Link bezieht sich auf das "Media Lovin 'Toolkit" (MLT) Wiki, das meltTeil von (aber auch openshotund kdenlive) ist. Hier ist der Link zu den Dokumentationstextdateien von ihrem Git: mltframework.org/mlt.git/tree - docs / ; Beachten Sie, dass das Wiki eine Seite über BuildScripts enthält .

Das größte (einzige) Problem, das ich derzeit habe, ist, dass ich keine Möglichkeit finde, eine unkomprimierte Videokomposition (entweder als pngFrames oder als unkomprimiertes Videoformat) zu exportieren .

 

Erstens können Sie in der Befehlszeile meltdie Wiedergabe über Frames steuern. meltVerwenden Sie beispielsweise, um ein weißes Leerzeichen mit einer Länge von 15 Frames zu erstellen und mit dem integrierten Player anzuzeigen

melt -blank 15

Wenn Sie mit anzeigen melt, erhalten Sie auch eine Befehlszeileninformation stderrfür den eingebauten Player:

$ 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

Sobald meltdie Wiedergabe abgeschlossen ist, wird sie nicht mehr beendet. Geben Sie qdaher Folgendes ein, um sie zu beenden.

Wir sollten beachten, dass es sogenannte "Produzenten" und "Konsumenten" gibt melt. Wenn nichts angegeben ist, ist der Standard-Consumer ein SDL- Fenster (Simple DirectMedia Layer) , in dem das Video wiedergegeben wird. Der obige Befehl ist also der gleiche wie:

melt -blank 15 -consumer sdl

Wenn wir also speichern möchten, was meltangezeigt wird, sollten wir den Consumer auf etwas ändern, das ein Dateiformat unterstützt. So erhalten Sie eine Liste der Verbraucher:

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

Der libdvVerbraucher gibt DV-formatierte Daten direkt an aus stdout. So speichern Sie das Video in einer von .dvIhnen erstellten Datei:

melt -blank 15 -consumer libdv > test.dv

Beachten Sie, dass von den aufgelisteten Verbrauchern das einzige Format, das ich ausprobiert habe und das auch in einer anderen Anwendung geöffnet werden kann, ist libdv(ich habe es vlcals andere Anwendung verwendet). Dies kann jedoch bei einer anderen Art der Transcodierung fehlschlagen ( z. B. wenn ich anstelle eines Leerzeichens versuche, ein Snippet aus einer .flvDatei zu konvertieren , wird die resultierende .dv-Datei geöffnet und abgespielt vlc, ist jedoch beschädigt ).

 

Nun zum Bearbeitungsteil ; Im Wesentlichen können Sie eine Reihe von Dateinamen- / Ein- / Ausgabe-Zeilengruppen direkt in der Befehlszeile angeben . Angenommen, Sie haben eine Datei. video.aviDann könnten Sie Folgendes tun:

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

oder etwas besser formatiert:

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

Dies bedeutet, dass video.avivon seinem Bild 30 bis zu seinem Bild 79 abgespielt wird; dann ein 15-Frame-Rohling; und dann die video.aviSequenz von Bild 30 zu Bild 79 erneut.

So verwenden Sie Bilder (z. B. .png) in einer Videobearbeitungskomposition:

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

Beachten Sie, dass für test.png, in=Parameter nicht 0 sein muss - jedoch wird das Bild für angezeigt out- inZeit; In diesem Fall ist es am einfachsten, den in=0Parameter ganz wegzulassen.

 

Die gute Sache ist , dass diese Bearbeitung Sequenz gespeichert werden - oder wie sie meltnennt, serialisiert - in eine Datei; Beachten Sie, dass es zwei Möglichkeiten für eine solche Serialisierung gibt: "simple" oder XML. Um zum Beispiel den obigen Befehl als "einfache" serialisierte Datei zu speichern, können wir einfach den -serialise [filename]Schalter zum Befehl hinzufügen :

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

Nun file.meltenthält das:

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

Scheinbar enthält dieses "einfache" serialisierte Dateiformat kein "kommentierendes" Zeichen. Wenn ich versuche, eine " # comment" Zeile hinzuzufügen , meltbeschwert ich mich mit: "# comment" konnte nicht geladen werden (aber ansonsten scheint das so Eine Zeile wird ignoriert und die Wiedergabe wird trotzdem fortgesetzt. " .melt" scheint eine Erweiterung zu sein, meltdie eine einfache serialisierte Datei erkennt.

Um diese serialisierte Datei erneut abzuspielen, können wir im Prinzip nur aufrufen melt file.melt- eine vollständigere Befehlszeile wäre jedoch:

melt melt_file:file.melt -consumer sdl

... was bedeuten würde: Verwenden Sie den melt_file"Producer" file.melt, um seine Frames auf dem "Consumer" sdl(Fenster) zu öffnen und zu rendern .

Beachten Sie, dass ich die Erfahrung habe, dass (sagen wir) .flvVideos problemlos über die Befehlszeile abgespielt werden - jedoch einen Segmentierungsfehler verursachen, wenn sie in der file.meltserialisierten Datei angegeben sind! .dvSelbst produzierte Videos meltscheinen in file.melt...

 

Der XML-Serialisierungstyp kann mithilfe des -consumer xml:Schalters ( anstelle von-serialise ) erreicht werden. Das obige Beispiel lautet nun:

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

Um die neu erzeugte file.mltXML-Datei "abzuspielen" , kann man sie jetzt direkt ausführen melt file.mlt- oder eine vollständigere Befehlszeile wäre:

melt xml:file.mlt -consumer sdl

... was bedeuten würde: Verwenden Sie den xml"Producer" ( Hinweis, zuvor war es ein Consumer ) file.mlt, um seine Frames im "Consumer" sdl(Fenster) zu öffnen und zu rendern .

Beachten Sie, dass ich in diesem Fall .flvfestgestellt habe, dass die gleichen Videos, die bei einer einfachen Serialisierungsdatei zu Segfault geführt haben, auch bei einer XML-Serialisierungsdatei einwandfrei funktionieren.

In diesem Fall enthält die resultierende file.mltXML-Datei viel mehr Einstellungen wie Auflösung, Bildrate, Codec-Informationen usw. - es ist jedoch auch schwieriger, direkt in einem Texteditor zu arbeiten:

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

Hier ist auch ein Beispiel für
bildgenaue

7

Die ffmpeg-Lösung für dieses Problem sieht ungefähr so ​​aus:

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

Es werden Named Pipes verwendet, sodass keine temporären Dateien auf der Festplatte erstellt werden können. Außerdem können Sie Teile der Videoclips ausschneiden und Bilder hinzufügen.

In diesem Beispiel wird die Zeit 30-60 der ersten Eingabe verwendet und anschließend die erste Minute der zweiten Eingabe hinzugefügt. Anschließend wird eine Bilddatei und anschließend das gesamte dritte Video eingefügt.

Code aufgehoben von:

Seite zum Verknüpfen von ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

Superuser-Seite Verwenden von ffmpeg zum Schneiden von Videos

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


Vielen Dank, ich habe kürzlich auch von ffmpeg-concat erfahren , das in JavaScript geschrieben ist (und das Sie npminstallieren müssen). Ich dachte, ich würde es erwähnen
sdaau,

4

Ich habe auch nach einem solchen Werkzeug gesucht und es scheint, dass Schmelze das Werkzeug für den Job ist, jedoch ist die Dokumentation fast unmöglich zu verstehen / zu fehlen. Sie können fast jede Kombination von Bearbeitungen durchführen. Ich hatte Action-Cam-Aufnahmen ... der Sound war jedoch unbrauchbar. Ich habe das (h264) -Video zusammengefügt, eine 60-Frame-Überblendung hinzugefügt und den Ton durch eine Tonspur ersetzt.

% 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

Sie können mehr darüber lesen Sie hier . Die Hauptwebsite ist hier .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.