Warum erhalte ich beim Konvertieren in ein GIF in FFmpeg verpixelte Videos?

Warum erhalte ich beim Konvertieren in ein GIF in FFmpeg verpixelte Videos?

Ich möchte dieses WEBM-Video kodieren:

Mir ist aufgefallen, dass bei FFmpeg hinsichtlich der Qualität Abstriche gemacht wurden.

Ich wandle WEBM in GIF um, falls das hilft. Und fast alle Online-Konverter verwenden im Hintergrund FFmpeg, was zu demselben Qualitätsverlust führt.

Beachten Sie, dass das erste Bild der FFmpeg-Kodierung sehr pixelig ist:

Bildbeschreibung hier eingeben

Hier ist der Befehl, den ich für die Kodierung verwendet habe.

ffmpeg -i connecting.webm -vf "fps=40,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

Selbst wenn ich die WEBM-Quelle in ein MP4 statt in ein GIF konvertiere, bleibt der Qualitätsverlust bestehen.

Und ich musste die -vfOption hinzufügen, die fehlerhafte Bildrate zu beheben. Die fehlerhafte Konvertierung finden Sie weiter unten.

Bildbeschreibung hier eingeben

Warum passiert das?

Antwort1

Die ursprüngliche WebM-Eingabedatei verfügt über einen Alphakanal (Transparenzkanal).
Eine mögliche Lösung besteht darin, das halbtransparente Video über einen schwarzen Hintergrund zu legen:

ffmpeg -y -c:v libvpx-vp9 -i connecting.webm -vf "[v:0]fps=40[v0];color=black:rate=40[b];[b][v0]scale2ref[b][v0];[b]setsar=1[b];[b][v0]overlay=shortest=1,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

Beim Ignorieren des Alphas wird das Video pixelig, da die Glätte durch eine allmähliche Änderung der Transparenz um das Objekt herum entsteht.


  • -c:v libvpx-vp9- Decoder verwenden libvpx-vp9. Wir brauchen ihn, weil der Standarddecoder den Alphakanal (Transparenzkanal) ignoriert.
  • color=black:rate=40[b]– Erstellt ein schwarzes Video mit 40 fps und einer gewissen Nennauflösung.
  • [b][v0]scale2ref[b][v0]- Skaliert das Schwarzvideo auf die Auflösung des Eingangsvideos.
  • [b]setsar=1[b]- Stellen Sie das Seitenverhältnis des schwarzen Videos auf 1:1 ein.
  • [b][v0]overlay=shortest=1- legt das Eingangsvideo über das schwarze Video.
  • scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse"- Skalieren Sie die generierte Palette und verwenden Sie sie, wie in der Frage beschrieben.

Ausgabe:
Bildbeschreibung hier eingeben


Anmerkungen zum Alphakanal (Transparenzkanal) der Eingabe:

Bei der Ausführung ffprobe connecting.webmwird Folgendes angezeigt:

  Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv, progressive), 400x400, SAR 1:1 DAR 1:1, 60 fps, 60 tbr, 1k tbn (default)
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc58.134.100 libvpx-vp9
      DURATION        : 00:00:01.067000000

Die alpha_mode : 1Metadaten weisen darauf hin, dass ein Alphakanal (Transparenzkanal) vorhanden ist.

Ich denke, es handelt sich um eine Art „spezielle“ Konfiguration (normalerweise würde ich erwarten, dass das Pixelformat yuva420p und nicht yuv420p ist, wenn ein Alphakanal vorhanden ist).
Es gibt einige Dokumentationen zu den alpha_mode : 1damit verbundenenVP8-Kodierung.

verwandte Informationen