So erstellen Sie mit FFmpeg ein Miniaturbild aus der Mitte eines Videos

So erstellen Sie mit FFmpeg ein Miniaturbild aus der Mitte eines Videos

Gibt es eine Möglichkeit, in FFmpeg ein Video-Thumbnail zu erfassen?

Ich möchte das mittlere Bild als Video nehmen und es als Miniaturbild verwenden. Die Videodauer ist unbekannt.

Auch die Möglichkeit, die Abmessungen des Miniaturbilds festzulegen, wäre hilfreich.

Antwort1

Einzeiliger Befehl:

ffmpeg -i input.mp4 -vcodec mjpeg -vframes 1 -an -f rawvideo -ss `ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'` output.jpg

Der Unterbefehl ermittelt die Gesamtdauer des Eingangsvideos

ffmpeg -i input.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,

Und leiten Sie es weiter, awkum die Dauer/2 wie folgt zu berechnen

echo '00:01:30.000' | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'

Geben Sie dies also innerhalb von Sekunden in die Option -ss ein, und fertig.

Wenn Sie die Größe angeben möchten, fügen Sie die Option -s wie WxH hinzu, wobei W und H ganzzahlige Werte sind (z. B. -s 800x600 oder -s svga), oder lesen Sie die Manpage von ffmpeg, um andere verfügbare Optionen oder Formate anzuzeigen.

Antwort2

Hier ist eine Methode, die Folgendes verwendet:

  • ffprobeum die Dauer zu erhalten
  • bcdie halbe Dauer zu berechnen
  • ffmpegum das Miniaturbild zu erstellen

Beispiel:

input=input.mp4; ffmpeg -ss "$(bc -l <<< "$(ffprobe -loglevel error -of csv=p=0 -show_entries format=duration "$input")*0.5")" -i "$input" -frames:v 1 half.png

Antwort3

Verwenden Sie zunächst immer die neueste Version von FFmpeg.

Wenn Sie Zugriff auf PHP haben, wird Ihre Frage auf Stack Overflow perfekt beantwortet:FFMpeg verwenden, um das mittlere Bild eines Videos zu erhalten?

$output = shell_exec("/usr/local/bin/ffmpeg -i {$path}");
preg_match('/Duration: ([0-9]{2}):([0-9]{2}):([^ ,])+/', $output, $matches);
$time = str_replace("Duration: ", "", $matches[0]);
$time_breakdown = explode(":", $time);
$total_seconds = round(($time_breakdown[0]*60*60) + ($time_breakdown[1]*60) + $time_breakdown[2]);
shell_exec("/usr/local/bin/ffmpeg -y  -i {$path} -f mjpeg -vframes 1 -ss " . ($total_seconds / 2) . " -s {$w}x{$h} {$output_filename}"; 

Es extrahiert lediglich die Dauer aus der FFmpeg-Ausgabe und verwendet diese, um den Zeitcode des mittleren Frames zu bestimmen.

Das lässt sich problemlos an andere Shells anpassen und einfach in den folgenden Befehl einfügen, wobei der mittlere Frame ungefähr bei 534Sekunden steht:

ffmpeg -y  -i input.mp4 -f mjpeg -vframes 1 -ss 534 thumbnail.jpg

Du kannst die Größe jederzeit mit -s 480x320oder ähnlich ändern, je nachdem wie groß du es haben möchtest, irgendwo nach der -i input.mp4Option eingefügt.


Die obige Lösung ist ein wenig ungenau. Sie erhalten zwar sofort ein Ergebnis, können aber nicht angeben, welches Bild Sie möchten. Wenn Sie bereits genau wissen, welches Bild Sie extrahieren möchten, verwenden Sie den selectFilter, z. B. mit der Bildnummer 12345:

ffmpeg -i input.mp4 -filter:v select="eq(n\,12345)" -vframes 1 thumbnail.jpg

Beachten Sie, dass dieser Befehl eine Weile dauern kann, da er zum angegebenen Frame springen muss, bevor er ihn extrahieren kann.

Antwort4

Die einfache Lösung ist:

 ffmpeg -i l1.mp4 -ss 00:00:14.435 -vframes 1 out.png

verwandte Informationen