Wie extrahiere ich alle N Sekunden ein Einzelbild eines Videos in ein Bild?


71

Wie kann ich eine Videodatei in eine Folge von Bildern konvertieren, zum Beispiel alle N Sekunden ein Bild. Kann mplayer oder ffmpeg das? Ich habe MPlayer verwendet, um Screenshots manuell zu erstellen, möchte dies jedoch für ein langes Video automatisieren.


Diese verwandte Frage zur Auswahl der Bildqualität: stackoverflow.com/questions/10225403/…
Pierz

Antworten:


70

Mit ffmpeg ist dies sehr einfach und es kann alle N Sekunden ein Bild ohne zusätzliches Scripting ausgegeben werden . Zum Exportieren als Bildsequenz verwenden Sie einfach myimage_%04d.pngoder ähnliches als Ausgabe. Das %0xdBit wird in eine mit Nullen aufgefüllte Ganzzahl umgewandelt x- das Beispiel, das ich gegeben habe, wird ausgegeben als

  • myimage_0000.png,
  • myimage_0001.png,
  • myimage_0002.png

    usw..

Sie können eine Vielzahl von Standbildformaten (PNG, JPEG, TGA usw.) verwenden ( ffmpeg -formatseine vollständige Liste finden Sie hier).

Ok, jetzt wissen wir, wie man den Film als Folge von Bildern exportiert, aber sagen wir, wir wollen nicht jedes einzelne Bild exportieren?

Der Trick besteht darin, die Framerate der Ausgabe mithilfe der -r nOption, bei der ndie Anzahl der Frames pro Sekunde angegeben ist, einfach auf das zu ändern, was wir möchten . 1 Bild pro Sekunde wäre -r 1, ein Bild alle vier Sekunden wäre -r 0.25, ein Bild alle zehn Sekunden wäre -r 0.1und so weiter.

Also um es alle zusammen, das ist , wie es aussehen würde , einen Rahmen von speichern input.movalle vier Sekunden output_0000.png, output_0001.pngetc .:

ffmpeg -i input.mov -r 0.25 output_%04d.png

Beachten Sie, dass die -r 0.25Option hinter dem -i input.movTeil steht, da sie die Bildrate der Ausgabe steuert . Wenn Sie es vor die Eingabe stellen, wird die Eingabedatei so behandelt, als ob sie die angegebene Bildrate hätte.

Ändern Sie% xd auf die Anzahl der benötigten Stellen, z. B. wenn der Befehl mehr als 10.000 Frames erstellen würde, ändern Sie den Wert %04dauf %05d. Dies funktioniert auch für Eingabedateien mit Bildsequenz. Lesen Sie hier mehr .

Windows-Benutzer : In der Befehlszeile verwenden%

Beispiel: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

In CMD- und BAT-Skripten verwenden %%

Beispiel: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Also doppelt %%in Skripten und einfach %in der interaktiven Befehlszeile. Wenn Sie es in beiden Situationen falsch machen, wird ein Fehler generiert.


Was muss ich tun, -rwenn ich jeden Frame exportieren möchte ? Wenn ich die FPS des Videos kenne, gebe ich das wohl ein, aber was ist, wenn nicht?
Tomáš Zato

4
Verwenden Sie überhaupt nicht das Flag -r. Dann verwendet FFMPEG die Bildrate der Eingabedatei.
Stib

2
Beachten Sie, dass Sie dies wirklich verwenden möchten jpegs, es sei denn, Sie sind sich sicher, dass Sie pnges möchten. In meinem Fall waren jpegs jeweils etwa 50 KB und pngs etwa 2 MB.
mlissner

5
Der Vorteil von PNGs ist die verlustfreie Komprimierung. Wenn Sie also die Bildsequenz als Zwischenstufe verwenden und die zusätzliche Größe nicht beachten, können Sie PNG verwenden.
Stib

Es ist erwähnenswert , dass hinzuzufügen -q:v 1ist eine sehr nützliche Option hier wie in superuser.com/questions/318845/...
Nikolay Shmyrev

27
mplayer -vo jpeg -sstep 5 file.avi

speichert alle 5 Sekunden einen Frame als JPEG-Datei.

Es wird jedoch nicht am Ende der Datei angehalten, sondern es werden weiterhin Kopien des letzten Frames erstellt. Um dies zu vermeiden, ermitteln Sie die Dauer des Videos in Sekunden mit einem anderen Player oder mit mplayer:

mplayer -vo null -ao null -frames 0 -identify file.avi

und suchen Sie nach einer Zeile wie "ID_LENGTH = 147.00".

Subtrahieren Sie 2 von der Länge und verwenden Sie diesen Wert für die -endposOption. Beispiel für ein 147 Sekunden langes Video:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi

Das klingt wie ein Mplayer-Bug. schöne Problemumgehung.
Quack Quijote

Könnten Sie zumindest erwähnen, auf welchem ​​Betriebssystem Sie diesen Befehl verwenden?
Tomáš Zato

Es war vor 5 Jahren, aber es war wahrscheinlich der neueste Ubuntu-Desktop zu der Zeit, Ubuntu 10.4.
Liam

Wie kann ich Schritte wählen, die kürzer als 1s sind? Es werden nur ganze Zahlen akzeptiert.
FCPENHA

Heutzutage mpv --vo=image --sstep=5 movie.mkvfunktioniert es ohne den oben erwähnten Fehler ( mpv ist eine Abspaltung von mplayer) mit mpv 0.27.0 unter Debian großartig.
Adam Katz

11

Mit ffmpegkönnen Sie Folgendes tun:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

Dieser Befehl generiert in der 4. Sekunde des Videos ein JPG-Miniaturbild in der Größe 320 × 240. Fügen Sie dies in ein Skript ein, das die Uhrzeit und den Dateinamen ändert, und Sie sind fertig.

Weitere Informationen: Erstellen Sie alle X Sekunden ein Miniaturbild des Videos


Dies scheint zu tun, was ich will, aber mit einem Problem. Die Datei wird bei jeder Iteration von Anfang an verarbeitet und dabei exponentiell langsam.
Liam

@Liam - Hilft es, wenn Sie die Versatzzeit in Ruhe lassen (auf 1 setzen) und -ss positionstattdessen das Flag verwenden, um weiter in der Datei zu suchen? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle

1
@liam: setze das -ssvor das, -iso dass die Suche passiert, bevor das Eingangsvideo dekodiert wird. Dies sollte es beschleunigen. source
quack quixote

2
Es gibt einen besseren, viel schnelleren Weg, dies mit ffmpeg zu tun. Siehe meine Antwort unten.
Stib

Die Lösung von stib ist die beste IMO.
Griffin

8

Wenn Sie nach einer Art Kontaktabzug suchen und mit einem Unix-ähnlichen Betriebssystem arbeiten, können Sie dieses aufwändige Skript verwenden, das bis zum Punkt Videokontaktabzug * NIX , kurz vcs , aufgerufen wird .

Im Hintergrund wird auch ffmpeg(standardmäßig) oder verwendet mplayer, daher können viele Videoformate verarbeitet werden. Es automatisiert den Prozess der Aufnahme von Standbildern aus dem Film und setzt diese zu einem Bild mit Kopf- und Fußzeile zusammen. Sie können zB auswählen, wie viele Captures Sie möchten oder alternativ die Zeitunterschiede zwischen ihnen.

Für ein Intervall von 10 Minuten sieht der Aufruf folgendermaßen aus:

vcs -i 10m input.avi

Überprüfen Sie die vollständige Liste der Befehlszeilenoptionen für einige andere Optimierungen.

Hier ist ein Beispiel eines Kontaktformulars von der Homepage :

Bildbeschreibung hier eingeben


7

Ab VLC 1.1.0 können Sie den Szenenvideofilter verwenden:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

Das obige speichert 1 von 24 Bildern (--scene-ratio = 24), beginnend um 00:00:10 und endend um 00:00:11.

Gerade getestet und bestätigt, dass dies mit VLC 2.0.3 unter einer neuen Windows 8-Installation funktioniert (ich habe keine zusätzlichen Video-Plugins oder Software).

Vollständige Dokumentation: http://wiki.videolan.org/How_to_create_thumbnails


2

VirtualDub kann dies für Sie tun

File-> Export->Image sequence

Bildbeschreibung hier eingeben


Speichert dies jeden Frame als Bild?
Liam

Ja, jedes Bild.
Shevek

Ich muss die meisten Frames überspringen, da die Ausgabe aller Frames zu viel Speicherplatz beansprucht. Ich brauche nur ein Bild alle paar Sekunden.
Liam

1

Sie könnten dies auch versuchen

von der VLC-Befehlszeile ...

vlc "C: \ DEIN \ file \ path \ file.avi" -V image --image-out-prefix = capname --image-out-ratio = 60

file.avi ist das Video, von dem Sie aufnehmen möchten, capname ist das Präfix der gespeicherten Bilder, möglicherweise möchten Sie mit dem Verhältnis herumspielen (60 bedeutet, dass 1 von 60 Bildern aufgenommen wird). Sie können beispielsweise weitere Befehle hinzufügen --image-out-format jpeg speichert Ihre Großbuchstaben als JPEGs anstelle von PNGs. --snapshot-path legt fest, wo Sie Ihre Großbuchstaben speichern möchten.

Quelle von oben


Ich habe die folgende Meldung erhalten: Die Befehlszeilenoptionen konnten nicht geladen werden. Überprüfen Sie, ob sie gültig sind.
Liam

Unter Ubuntu habe ich folgende Meldung erhalten: Unbekannte Option oder fehlendes obligatorisches Argument "--image-out-prefix = capname"
Liam

1

Sie können Frames in VirtualDub überspringen. Verwenden Sie einfach die Option "Decimate By" im Menü Video -> Frame Rate. Wenn Sie beispielsweise "Dezimieren um 100" festlegen und dann "Datei -> Exportieren -> Bildsequenz" wählen, wird nur jedes 100. Bild gespeichert.

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.