Frage Wie konvertiere ich ein Video in GIF mit ffmpeg, mit angemessener Qualität?


Ich konvertiere .flv Film zu .gif Datei mit ffmpeg.

ffmpeg -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000  output.gif

Es funktioniert gut, aber Ausgabe Gif-Datei hat eine sehr geringe Qualität.

Irgendwelche Ideen wie kann ich die Qualität von konvertierten Gif verbessern?

Ausgabe des Befehls:

ffmpeg -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000  output.gif
ffmpeg version 0.8.5-6:0.8.5-0ubuntu0.12.10.1, Copyright (c) 2000-2012 the Libav developers
  built on Jan 24 2013 14:52:53 with gcc 4.7.2
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.flv':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-02-14 04:00:07
  Duration: 00:00:18.85, start: 0.000000, bitrate: 3098 kb/s
    Stream #0.0(und): Video: h264 (High), yuv420p, 1280x720, 2905 kb/s, 25 fps, 25 tbr, 50 tbn, 50 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 192 kb/s
    Metadata:
      creation_time   : 2013-02-14 04:00:07
[buffer @ 0x92a8ea0] w:1280 h:720 pixfmt:yuv420p
[scale @ 0x9215100] w:1280 h:720 fmt:yuv420p -> w:320 h:240 fmt:rgb24 flags:0x4
Output #0, gif, to 'output.gif':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-02-14 04:00:07
    encoder         : Lavf53.21.1
    Stream #0.0(und): Video: rawvideo, rgb24, 320x240, q=2-31, 200 kb/s, 90k tbn, 10 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Stream mapping:
  Stream #0.0 -> #0.0
Press ctrl-c to stop encoding
frame=  101 fps= 32 q=0.0 Lsize=    8686kB time=10.10 bitrate=7045.0kbits/s dup=0 drop=149    
video:22725kB audio:0kB global headers:0kB muxing overhead -61.778676%

Vielen Dank.


247
2018-02-22 20:06


Ursprung




Antworten:


ffmpeg kann jetzt GIF mit höherer Qualität ausgeben. Wenn Sie einen älteren Build verwenden, beachten Sie einen aktuellen statischen Build herunterladen oder kompilieren ffmpeg.

ffmpeg Beispiel

gif with ffmpeg
203k

In diesem Beispiel werden die ersten 30 Sekunden der Eingabe übersprungen und eine 3-Sekunden-Ausgabe erstellt. Die Ausgabe wird auf eine Breite von 320 Pixeln skaliert und die Höhe automatisch bestimmt, während das Seitenverhältnis beibehalten wird. Das palettegen und paletteuse Filter generieren und verwenden eine benutzerdefinierte Palette, die aus Ihrer Quelle generiert wird.

  1. Generiere eine Palette:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Gib das GIF mit der Palette aus:

    ffmpeg -ss 30 -t 3 -i input.flv -i palette.png -filter_complex \
    "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
    

Sehen Hochwertiges GIF mit FFmpeg für viele weitere Beispiele und Optionen.


convert Beispiel

Eine andere Befehlszeilenmethode wäre, den Film mithilfe von in Frames zu exportieren ffmpeg dann mach das GIF mit convert von ImageMagick (oder GraphicsMagick).

ffmpeg and convert
246k

  1. Frames exportieren:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Dann benutze convert (oder gm convert Wenn Sie GraphicsMagick bevorzugen), um Ihr animiertes GIF zu erstellen:

     convert -loop 0 frames/ffout*.png output.gif
    

Mit convert Sie können die Verzögerung zwischen Bildern mit steuern -delay wenn gewünscht.


374
2018-02-22 21:31



Einige Beispielergebnisse hinzugefügt (nur Standbilder). Hier beträgt die erste Datei 4,1 MB, die zweite etwa 8 MB. - slhck
@LordNeckbeard, du bist großartig! Vielen Dank für -vf scale=320:-1,format=rgb8,format=rgb24 - Kamil Hismatullin
Übrigens, für die convert Befehl zum Konvertieren von den PNG-Frames, die ich verwendet habe convert -delay 5 -loop 0 -dither None -colors 80 "frames/ffout*.png" -fuzz "40%" -layers OptimizeFrame "output.gif", was die Gesamtdateigröße ziemlich reduziert - Wilf
Ich denke der convert Befehl sollte verwenden -delay 10 (0,1 Sekunden zwischen Frames), um die Übereinstimmung zu erzielen -r 10 (10 fps) Bildrate, die Sie gerade speisen ffmpeg. Wenn ich benutze -delay 5Ich sehe das Gif mit doppelter Geschwindigkeit spielen. - Jack O'Connor
Okay, ich habe es, ich habe es benutzt scale=0:-1Wenn Sie die Skalierung auf 0, wird es die Skala von dem Video nehmen. - Mousa Alfhaily


Wenn Sie Zwischenbilddateien lieber vermeiden möchten, können Sie zwischen den Befehlen von LordNeckBeard pinnen ffmpeg und ImageMagicks convert damit keine Zwischendateien benötigt werden:

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - output.gif

Das -f image2pipe sagt ffmpeg, das Video in Bilder aufzuteilen und es passend zu machen, ausgelöscht zu werden, und -vcodec ppm spezifiziert das Ausgabeformat als ppm (aus irgendeinem Grund, wenn das Format png ist, entweder convert liest nicht alle Bilder aus der Pipe, oder ffmpeg gibt sie nicht alle aus). Das - Bei beiden Befehlen wird angegeben, dass eine Pipe für die Ausgabe bzw. Eingabe verwendet wird.

Um das Ergebnis zu optimieren, ohne eine Datei zu speichern, können Sie die Ausgabe von pipen convert zu einer Sekunde convert Befehl:

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - gif:- | convert -layers Optimize - output.gif

Das gif:- erzählt convert um seine Ausgabe als gif formatierte Daten und -layers Optimize erzählt die Sekunde convert aufführen optimize-frame und optimize-transparancy Methoden (siehe ImageMagick Einführung in die Animation Optimierung). Beachten Sie, dass die Ausgabe von der -layers Optimize stellt möglicherweise nicht immer eine kleinere Dateigröße bereit, daher sollten Sie zuerst versuchen, die Konvertierung in ein Gif ohne Optimierung durchzuführen.

Denken Sie daran, dass während des gesamten Prozesses alles im Speicher ist, so dass Sie möglicherweise genügend Speicher benötigen, wenn die Bilder ziemlich groß sind.


79
2018-03-18 09:47



Diese Befehlsgruppe funktioniert auch mit avconv - raphael
Sie sollten die letzten beiden Konvertierungsbefehle zusammenführen: convert -delay 5 -loop 0 -layers Optimize - output.gif - Clément
Das GIF scheint mit der doppelten Geschwindigkeit des Quellvideos zu laufen? - Titan
@Titan glaube, es ist die -r 10 im ersten Befehl und die -delay 5 in der Sekunde. Ich habe die Verzögerung auch auf 10 geändert und es scheint jetzt normal zu spielen. - Steven Huang
Sie können auch Zwischenbilddateien vermeiden, indem Sie die split Filter in ffmpeg. Keine Notwendigkeit, irgendetwas zu pumpen: ffmpeg -ss 30 -t 3 -i "input.flv fps=10,scale=320:-1:flags=lanczos,split[x][z];[z]palettegen[y];[x][y]paletteuse" output.gif - Ajedi32


Ab ffmpeg 2.6 können wir noch besser machen:

palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"

ffmpeg -i input.flv -vf "$filters,palettegen" -y $palette
ffmpeg -i input.flv -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y output.gif

HT 


29
2018-03-23 18:39





Ich habe meine eigene Version des Skripts erstellt, die auch die Ausgabeauflösung und Bildrate parametrisiert.

Laufen ./gifenc.sh input.mov output.gif 720 10 wird 720p wide 10fps GIF aus dem Film ausgeben, den Sie ihm gegeben haben. Sie müssen möglicherweise tun chmod +x gifenc.sh für die Datei.

#!/bin/sh

palette="/tmp/palette.png"

filters="fps=$4,scale=$3:-1:flags=lanczos"

ffmpeg -v warning -i "$1" -vf "$filters,palettegen" -y "$palette"
ffmpeg -v warning -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$2"

Sie können die Details auf meiner lesen Github

Annahmen: ffmpeg ist installiert, und das Skript befindet sich im selben Ordner wie die anderen Dateien.


13
2017-07-12 09:35



Vielen Dank für Ihr Skript. Ich habe es gerade getestet und es funktioniert super! - orschiro


ein Skript gemacht, getestet und funktioniert.

Verwendung:

./avi2gif.sh ./vokoscreen-2015-05-28_12-41-56.avi

Habe PHUN :)

vim avi2gif.sh

#!/bin/sh

INPUT=$1

# default settings, modify if you want.

START_AT_SECOND=0; # in seconds, if you want to skip the first 30 seconds put 30 here

LENGTH_OF_GIF_VIDEO=9999999; # in seconds, how long the gif animation should be

echo "Generate a palette:"
ffmpeg -y -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png

echo "Output the GIF using the palette:"
ffmpeg -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" $INPUT.gif

Übrigens: vokoscreen ist ein ausgezeichnetes ScreenCapturing Tool für Linux :)

Vielen Dank Michael Kohaupt :) Rock Steady.

einige Dateigrößen-Statistiken:

5.3M = vokoscreen-2015-04-28_15-43-17.avi -> vokoscreen-2015-05-28_12-41-56.avi.gif = 1013K

Siehe die Ergebnisse hier.


7
2018-05-28 10:55





Die Antwort von @ Stephane ist sehr gut. Aber es wird eine Warnung erhalten wie Buffer queue overflow, dropping. für einige Videos und die generierten gif hat einige Rahmen fallen gelassen.

Hier ist eine bessere Version mit fifo Filter zu vermeiden Buffer queue overflow beim Benutzen paletteuse Filter. Durch die Nutzung split Filter, um die Erstellung der Zwischenpalette PNG-Datei zu vermeiden.

ffmpeg -i input.mp4 -filter_complex 'fps=10,scale=320:-1:flags=lanczos,split [o1] [o2];[o1] palettegen [p]; [o2] fifo [o3];[o3] [p] paletteuse' out.gif

7
2017-10-05 12:04





Linux / Unix / macOS

Folgend @LordNeckbeard Ansatz mit ffmpeg Befehl, finden Sie die folgende nützliche Bash-Funktion, die zu Ihrem hinzugefügt werden kann ~/bash_profile Datei:

# Convert video to gif file.
# Usage: video2gif video_file (scale) (fps)
video2gif() {
  ffmpeg -y -i "${1}" -vf fps=${3:-10},scale=${2:-320}:-1:flags=lanczos,palettegen "${1}.png"
  ffmpeg -i "${1}" -i "${1}.png" -filter_complex "fps=${3:-10},scale=${2:-320}:-1:flags=lanczos[x];[x][1:v]paletteuse" "${1}".gif
  rm "${1}.png"
}

Sobald die Datei geladen ist (. ~/.bash_profile), du solltest neu haben video2gif Befehl.

Beispielverwendung:

video2gif input.flv

oder:

video2gif input.flv 320 10

Skalieren Sie auf 320 Breite mit 10 Bildern pro Sekunde.

Sie können auch ein anderes Videoformat angeben (z. B. mp4).


Mac OS

Du kannst es versuchen GIF Brauerei App, die GIFs aus Videodateien erstellen kann.


Alternativ gibt es mehrere Websites, die kostenlos online Conversion durchführen.


6
2017-12-09 17:34



Tangential / Offtopic: Für jeden, der sich fragt, warum Community dies bearbeitet hat, war es HTTPSify den Link in der ersten Zeile der Antwort. (Der HTTPS-Übergang von Stack Overflow ist in vollem Gange!) - i336_