9 Punkte von GN⁺ 2025-01-15 | 1 Kommentare | Auf WhatsApp teilen
  • FFmpeg-Aufgaben werden durch die Kombination vieler Optionen schnell komplex. FFmpeg By Example ist eine Dokumentations-Website, auf der sich die benötigten Methoden zur Medienverarbeitung anhand realer Befehlsbeispiele schnell finden lassen.
  • Sie bietet außerdem ein GitHub-Repository, eine Discord-Community und eine Beitragsseite, über die Nutzer neue Ideen zur Nutzung von FFmpeg direkt einreichen können.
  • Am Beispiel des Filters testsrc zeigt sie Eingabequelle, Auflösung, Framerate und Ausgabedatei in einem einzigen Befehl, sodass sich die Befehlsstruktur direkt nachvollziehen lässt.
  • Die Beispiele decken das gesamte Spektrum der Medienverarbeitung ab, darunter Bitratenberechnung, Bildgrößenanpassung, Audio-Rauschminderung, Übergangseffekte, Stream-Mapping, Hardwarebeschleunigung und Metadatenverarbeitung.
  • Jedes Beispiel ist in Tags und einzelne Seiten gegliedert, sodass sich die passenden FFmpeg-Befehle leicht nach bestimmten Filtern oder Umwandlungszielen durchsuchen lassen.

Beispielorientierte FFmpeg-Dokumentations-Website

  • FFmpeg By Example ist eine Website, die verschiedene Einsatzmöglichkeiten von FFmpeg in Form einzelner Beispiele strukturiert aufbereitet.
  • Sie bietet außerdem Links für Community-Beteiligung und Beiträge.

Beispiel zur Erstellung eines testsrc-Testvideos

ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 testsrc.mpg

Encoding, Konvertierung und Hardwarebeschleunigung

Audioverarbeitung

Bilder und Animationen

Filter und visuelle Effekte

Extraktion, Analyse und Metadaten

Generierte Quellen und Ausgabe-Pipelines

1 Kommentare

 
GN⁺ 2025-01-15
Meinungen auf Hacker News
  • Der Spaß an ffmpeg ist um 1000 % gestiegen.
    Früher habe ich mühsam per Google Stack-Overflow-Antworten zusammengesucht und daraus Befehle gebastelt; heute schreibt ChatGPT die Befehle für mich, was viel bequemer ist.

    • Dank LLMs nutze ich ffmpeg mehrmals pro Woche.
      Der beste Anwendungsfall für mein Tool llm cmd:

      uv tool install llm
      llm install llm-cmd

      llm cmd use ffmpeg to extract audio from myfile.mov and save that as mp3

      https://github.com/simonw/llm-cmd

    • Lange Zeit hatte ich ffmpeg in dieselbe Schublade wie reguläre Ausdrücke gesteckt: „Das sollte ich wirklich lernen, aber ich werde es wohl furchtbar hassen.“
      Dann kam ChatGPT und hat beides gelöst.

    • Geht mir genauso. Solche Aufgaben hat AI komplett übernommen, und ich bin nur noch der Vermittler, der Fehler-Traces kopiert und einfügt.

    • Es gibt inzwischen viele andere Tools, aber ich habe gerade ein Skript gebaut, das solche Befehlsketten ziemlich vereinfacht: llmpeg https://github.com/jjcm/llmpeg
      Wenn ffmpeg installiert ist und der OpenAI-API-Schlüssel als Umgebungsvariable gesetzt ist, sollte es direkt funktionieren.

      Demo: https://image.non.io/1c7a92ef-0917-49ef-9460-6298c7a9116c.we...

    • Nachdem ich gelernt hatte, wie komplexe Filter funktionieren, wurde die Nutzung von ffmpeg noch angenehmer.

  • Mir fiel ein, dass ich einmal veröffentlichen sollte, wie ich digitalisierte Heimvideokassetten per Szenenerkennung in Clips verwandle.
    Falls jemand danach sucht, hier ein gist, das ziemlich gut funktioniert hat [0]. Allerdings ließ es sich manchmal von Kamerablitzen oder Verwacklern täuschen, sodass ich separate Start-/Enddateien übergeben und sie mit ffmpeg wieder zusammenfügen musste [1].

    Merkwürdig war, dass die Performance nach dem neuesten Mac-Update ohne -c:v h264_videotoolbox besser war. Vielleicht ist das eine Performance-Regression in Sequoia, aber ich bin mir nicht sicher. Das entsprechende Flag für Windows-Maschinen mit Nvidia-GPU ist -c:v h264_nvenc. Ich frage mich, warum ffmpeg das nicht automatisch erkennt. Damit bekam ich etwa eine 8-fache Leistungssteigerung.
    Der einzige Moment, in dem ich in der Firma wirklich mein Gehalt wert war: Als wir kurz davor waren, teuer zusätzliche Cloud-Server mit GPU für Videoverarbeitung zu buchen, stellte ich fest, dass das installierte ffmpeg ohne GPU-Beschleunigung kompiliert worden war.

    [0] https://gist.githubusercontent.com/nielsbom/c86c504fa5fd61ae...

    [1] https://gist.githubusercontent.com/jazzyjackson/bf9282df0a40...

    • Das Problem bei Cloud-CPUs ist, dass ihnen die Hardware-Videoencoder fehlen, die in Consumer-CPUs stecken; deshalb muss man auf deutlich teurere GPU-Maschinen ausweichen.
      Ehrlich gesagt habe ich in der Cloud keinen sauberen Preisvergleich mit Hardwarebeschleunigung gemacht; ich frage mich, ob du das tatsächlich ausprobiert hast und ob es gemessen an den Kosten okay war.

    • Ich habe mit ffmpeg Erkennung leerer Szenen gemacht.
      Ich habe eine Kamera auf die Flugroute nach SFO gerichtet und alle Frames ohne Bewegung entfernt; übrig blieb ein durchgehendes Video mit vorbeifliegenden Flugzeugen, ohne langweilige Abschnitte.

    • -c:v h264_nvenc ist nützlich für Batch-Encoding, wenn man mehrere Videos gleichzeitig encodiert, weil man damit den Encoding-Durchsatz erhöhen kann.
      Allerdings war die Ausgabequalität in meinen früheren, begrenzten Tests etwas schlechter als bei libx264. Ob es dafür einen Workaround gibt, weiß ich nicht, aber ich war damit nicht allein.

    • Der Grund, warum ffmpeg das nicht automatisch erkennt, ist, dass Hardware-Encoding meist weniger Einstellmöglichkeiten bietet, größere Kompromisse gegenüber ausgefeilten Software-Codecs eingeht und selbst bei denselben Parametern nicht exakt dieselben Ergebnisse liefert.
      Außerdem gibt es auf einem System oft mehrere auswählbare Hardware-APIs, und deren Funktionen unterscheiden sich.

      FFmpeg ist ein komplexes Kommandozeilen-Tool und richtet sich an Nutzer, die bereit sind, die Details zu lernen; ich bin mir daher nicht sicher, ob es sinnvoll wäre, auf Annahmen basierende Defaults zu setzen.

    • Dem Snippet nach zu urteilen scheint kein Deinterlacing gemacht zu werden.
      Wenn die Clips schon vor der Digitalisierung deinterlaced wurden, ist das okay; andernfalls encodiert man Interlaced-Material als progressiv und ruiniert damit die Qualität. Es wäre gut, den Filter bwdif hinzuzufügen, damit 30i-Content als 60p encodiert wird. Das dürfte näher an den ursprünglichen Videokassetten aussehen.

  • Mit der Zeit bin ich mit vielen Teilen von ffmpeg ziemlich vertraut geworden. Die CLI hat ihre eigene Logik und ist reihenfolgeabhängig. Das gilt nicht für jede Unix-CLI.
    In letzter Zeit beschäftige ich mich mit etwas obskureren Funktionen. Zum Beispiel damit, Rohmaterial einer Videokamera direkt auf einer ziemlich langsamen Maschine zu speichern. Ich habe ein Mikroskop gebaut und lese von der Kamera Frames in einem Rohvideoformat (YUYV 1280x720) mit 120 FPS; wenn man sie unverändert auf die Festplatte schreibt, wächst das schnell um mehrere Gigabyte pro Minute. Speicherplatz ist billig, aber es wirkt verschwenderisch, deshalb habe ich mir nahezu verlustfreie Verfahren angesehen, mit denen sich exakte Bilder schnell komprimiert speichern lassen.

    Ich stellte fest, dass die RGB24-Konvertierung in ffmpeg sehr langsam ist, und nachdem ich eine Weile an der Kommandozeile herumprobiert hatte, bin ich bei Folgendem gelandet:

    ffmpeg -f rawvideo -pix_fmt yuyv422 -s 1280x720 -i test.raw -vcodec libx264 -pix_fmt yuv420p movie.mp4 -crf 13 -y

Rohvideo hat keinen Container und damit keine Metadaten wie „Pixelformat“ oder „Bildgröße“, daher muss man sie selbst angeben. Die Reihenfolge ist relevant: Alles vor -i test.raw dient dem Decoding der Eingabe, alles danach dem Schreiben der Ausgabe. Es wird nur eine winzige Pixelformat-Konvertierung durchgeführt (die ffmpeg sehr schnell erledigen kann), und die Daten werden in ein nahezu verlustfreies Format mit Container geschrieben. In den meisten Fällen war .mkv als Container am besten.

Weil ich die Kommandozeile nicht mag, habe ich am Ende ffmpeg-python verwendet und den folgenden Code die Kommandozeile zusammenbauen lassen:

self.process = (
ffmpeg.
input(
"pipe:",
format="rawvideo",
pix_fmt="yuyv422",
s="{}x{}".format(1280, 720),
threads=8
)
.output(
fname, pix_fmt="yuv422p", vcodec="libx264", crf=13
)
.overwrite_output()
.global_args("-threads", "8")
.run_async(pipe_stdin=True)
)

Und tatsächlich write() ich dann Frames auf die Standardeingabe dieses Prozesses. Da die Maschine 12 Kerne hat und für die Steuerung des Mikroskops immer mindestens 2 davon gebraucht werden, musste ich die Thread-Anzahl begrenzen.

Ich suche immer noch nach einer besseren und schnelleren verlustfreien YUV-Codierung.

  • Dass die Reihenfolge relevant ist, ist angemessen. Unix-Pipelines hängen auch von der Reihenfolge der Komponenten ab, und komplexe FFMpeg-Aufrufe tun etwas Ähnliches.
    Viele mögen die Ästhetik eines „fluent interface“ wie bei ffmpeg-python, aber in Python gilt das oft als wenig pythonisch. Soweit ich es verstehe, wurde ffmpeg-python so entworfen, dass es die Reihenfolge der Kommandozeile eng widerspiegelt.

    Die Präferenz, die durch die Standardbibliothek und das Design der eingebauten Typen verstärkt wird, ist eine starke https://en.wikipedia.org/wiki/Command%E2%80%93query_separati.... Nach diesem Prinzip sähe es grob etwa so aus:

    ffmpeg(global_args=..., overwrite_output=True).process_async(piped_input(...), output(...))

    Wenn man die Eingabe zu einem separaten Konfigurationsschritt macht, entsteht ein anderer Laufzeittyp, und auch dem Verarbeitungscode kann signalisiert werden, dass er von der Standardeingabe lesen soll.

  • Du musst nicht weiter suchen: FFV1 https://trac.ffmpeg.org/wiki/Encode/FFV1

  • Ich möchte nur ein Wort empfehlen: RAM-Disk
    Wenn du Dateien für Zwischenschritte hast, die du aber nicht aufbewahren willst, dann ist eine RAM-Disk die Lösung. Wirklich großartig.

  • Ich dachte, das wäre eine Website, die das von FFmpeg-Profis angesammelte Wissen sammelt und pflegt, aber schon das erste Beispiel, das ich angeklickt habe, hat mich sofort enttäuscht:
    https://www.ffmpegbyexample.com/examples/l1bilxyl/get_the_du...

    Man sollte nicht zwei weitere Tools aufrufen, nur um String-Verarbeitung zu machen. FFprobe allein kann die Dauer oder den gewünschten Wert direkt liefern:

    ffprobe -loglevel quiet -output_format csv=p=0 -show_entries format=duration video.mp4

    Man sollte nicht beim ersten funktionierenden Ergebnis stehen bleiben; nachdem es funktioniert, sollte man überlegen, ob es sich noch verbessern lässt.

    • Ich bin der Autor des ursprünglichen Beitrags. Es „verrückt“ zu nennen, ist vielleicht etwas übertrieben.
      Trotzdem gefällt mir die vorgeschlagene Lösung besser.
  • Schön. Das erinnert mich an mein ffmpeg-Cheatsheet. Ich glaube, jeder, der ffmpeg häufig nutzt, hat eine ähnliche Sammlung von Notizen.
    https://github.com/fastily/cheatsheet/blob/master/ffmpeg.md

  • FFmpeg ist eines dieser Tools, die ich so selten benutze, dass mir die genaue Syntax nie im Kopf bleibt. Am Ende lasse ich mir die nötige Kommandozeile von einem LLM geben.
    Das einzige ähnlich mühsame Tool war MegaCLI von LSI Logic im 1990er-Stil. Auch das benutzt man fast nie, aber wenn, dann musste es unter Druck exakt richtig sein.

    • Ich benutze FFMPEG seit über 15 Jahren, kann mir die Befehle aber immer noch kaum merken. Trotzdem sind LLMs wirklich großartig, wenn man FFMPEG verwendet.
      Wenn man ChatGPT und Claude sagt: „Remuxe das Video nach mkv, füge subtitle.srt in die Datei ein, und ich will nur den Abschnitt von 0:00:05 bis 0:01:00“, machen sie das hervorragend. Falls es interessiert, das Ergebnis war: ffmpeg -i input.mp4 -i subtitle.srt -ss 00:00:05 -to 00:01:00 -map 0 -map 1 -c copy -c:s mov_text output.mkv

      Ich frage mich, wie klein man ein LLM machen könnte, wenn das Ziel nur das Erzeugen von ffmpeg-Befehlen ist. Vielleicht könnte es klein genug werden, um auf einer statischen Webseite lokal zu laufen?

    • Seit 15 Jahren pflege ich ein persönliches Notizdokument mit der Syntax, die ich häufig benutze. Wenn das nicht reicht, greppe ich meine bash-History.

    • Geht mir genauso. Das Einzige, was hängen bleibt, ist das Umwandeln von Format X nach .mp4. Alles andere muss ich jedes Mal wieder nachschlagen.
      Passendes XKCD: https://xkcd.com/1168/

    • Vor ein paar Tagen sagte ich halb im Scherz, halb im Ernst, dass es sich vielleicht lohnen würde, den ganzen Regenwald abzubrennen, wenn mir ein LLM nur die ffmpeg-Flags nennen kann, die ich brauche.

  • Man sollte nicht vergessen, dass es auch GStreamer gibt. Da es Pipeline-basiert ist, sind Kommandozeile und Dokumentation etwas leichter zu verstehen als bei ffmpeg, und die Kombinationen wirken auch etwas vernünftiger
    Bei schweren Videoaufgaben habe ich ffmpeg komplett aufgegeben und nutze nur noch GStreamer

    • GStreamer kann einem beim programmatischen Erstellen von Pipelines mehr Kontrolle und eine freundlichere API geben
      Für einmalige Aufgaben wirkt ffmpeg aber deutlich zugänglicher. Zum Beispiel hat ffmpeg vernünftige x264-Defaults, während man bei gst-launch wirklich wissen muss, was man tut, um x264-Encoding in guter Qualität hinzubekommen
    • Ich dachte, FFmpeg sei auch Pipeline-basiert. Gibt es da nicht Filtergraphen? Übersehe ich etwas?
      Man kann komplexe Graphen aus Quellen, Senken und Transformationsfiltern zusammenstellen
    • GStreamer fühlt sich wie ein vernachlässigtes Projekt an. Es gab kürzlich auch eine große Sicherheitslücke, und die Dokumentation ist ziemlich kaputt
  • Es gibt ein GitHub-Repository zu einem ffmpeg-Buch, das diese Website gut ergänzen dürfte:
    https://github.com/jdriselvato/FFmpeg-For-Beginners-Ebook

  • ffmpeg hat sich für mich immer so angefühlt, als hätte man eine GUI-Anwendung mit Gewalt in ein TUI-Format gequetscht
    Die C-API habe ich auch ein paar Mal mit wenig Freude benutzt; sie ist in vielerlei Hinsicht zwar intuitiv, macht es aber viel zu leicht, ungültige Zustände darzustellen. Ich wünschte, es gäbe ein Echtzeit-AV1-Encoding-Framework, das „einfach funktioniert“

    • Es ist im Grunde fast das einzige Tool, bei dem ich zuerst zur GUI-Alternative HandBrake greife. Batch-Verarbeitung ist die einzige Ausnahme
      Es gibt auch ein paar reine ffmpeg-GUIs. Bei Videoarbeit gibt es etwas, das mit der Kommandozeile nicht gut zu meiner Denkweise passt

    • Als API kann ich GStreamer empfehlen. Ich habe die Rust-Bindings genutzt und bin daher mit der C-API nicht sehr vertraut, aber sie sah gut aus
      Durch GObject wird es stellenweise wortreich, aber sobald man es verstanden hat, kann man mit allen Objekten der API konsistent interagieren. Es gibt wirklich viel notwendige Komplexität (Video ist schwer), aber Design, Implementierung und Dokumentation sind ziemlich gut gemacht

      Für gängige Anwendungsfälle machen es Bins (decodebin, transcodebin, playbin) ziemlich einfach. Auch komplexere Anwendungsfälle sind dank der Flexibilität des Designs möglich

    • Die Einsicht gefällt mir, aber TUI ist etwas Grafisches, und ffmpeg ist einfach eine CLI
      Ein TUI-Tool wäre schön. So etwas wie https://github.com/Twinklebear/fbed, nur mit vollständigerem Funktionsumfang

  • Auf Linux-Systemen baue ich ffmpeg gern als statischen Build, weil die Distributionsversion manchmal zu alt ist oder bevorzugte Module fehlen
    Diese containerisierte Version war sehr nützlich: https://github.com/wader/static-ffmpeg