FFmpeg für überlegene Encoding-Leistung verbessern
Historischer Hinweis: Dieser Artikel aus dem Jahr 2015 beschreibt den FFmpeg-Stack
v2.2.3. Dieser Stack hat am 1. Februar 2020 sein End of Life erreicht und wird nicht mehr akzeptiert. In der Robot-Dokumentation finden Sie den aktuell empfohlenen Wert fürffmpeg_stack.
Transloadit ist ein kleines Team von Ingenieuren, es ist Code, es ist eine hochskalierbare Plattform, es ist eine Reihe eigenwilliger Robots, die Sie anweisen können, Medien zu importieren und zu konvertieren. Im Herzen dieser Robots stecken oft Open-Source-Tools, die die Schwerstarbeit erledigen. Ein Tool sticht dabei besonders hervor: FFmpeg.

Geschichte
Wir setzen FFmpeg ein, seit wir 2009 gestartet sind. Damals hatten wir nur eine Version, die wir
heute v0.0.1 nennen. 2011 haben wir den FFmpeg-Kernentwickler Stefano
Sabatini gesponsert, damit er eine maßgeschneiderte neue Version für
uns baut, denn wir wollten, dass unsere Kunden Wasserzeichen in webm-Dateien nutzen können, was zu
diesem Zeitpunkt nicht möglich war.
Die Technik entwickelt sich immer schnell weiter, und das Medien-Encoding bildet da keine Ausnahme. Um auf dem aktuellen Stand zu bleiben, müssen wir FFmpeg fortlaufend aktualisieren. Gleichzeitig wollen wir jedoch bestehende Setups unserer Kunden nicht wegen Problemen mit der Abwärtskompatibilität brechen. Transloadit bietet praktische Voreinstellungen, etwa um ein Video für das iPad zu optimieren, die sich relativ leicht portieren lassen, aber wir bieten Power-Usern auch feingranulare Kontrolle über das Verhalten von FFmpeg. Gerade diese letzte Kundengruppe wäre verständlicherweise verärgert, wenn ihre feingranularen Anweisungen aufgrund eines Upgrades plötzlich nicht mehr unterstützt würden.
Mehrere Versionen
Der Wunsch, uns weiterzuentwickeln, ohne bestehende Setups zu brechen, hat uns dazu gebracht, ein System zu entwickeln, in dem neue Versionen unserer Encoding-Tools nebeneinander existieren können und vollständig optional sind.
Bisher haben wir die folgenden Stack-Versionen eingeführt:
v0.0.1am 13. Juli 2009v1.0.0am 27. April 2011v2.0.0am 7. Juli 2013v2.1.0am 12. November 2013v2.2.3am 3. Juni 2014
Wir haben schon immer eigene Builds verwendet, weshalb wir eine eigene Seite bereitstellen, die alle unterstützten Formate und Codecs pro Stack aufführt.
Soft Launches
Im Laufe der Jahre haben wir 9905 automatisierte Tests angesammelt, von denen viele visuelle Diffs nutzen, um sicherzustellen, dass unser Encoding wie erwartet funktioniert. Trotzdem gibt es immer dieses eine seltsame Szenario, in dem ein seltsamer Endnutzer eine seltsame mp4-Datei mit einem seltsamen zweiten Videostream erzeugt, die Probleme verursacht, für die wir noch keine Tests hatten. Am Ende dieses Tages werden wir diese Tests natürlich haben. 😄
Aus diesem Grund haben wir uns bisher immer für Soft Launches unserer Stack-Versionen entschieden. Typischerweise arbeiten wir mit einer Handvoll Kunden zusammen, und sobald das Vertrauen in den neuen Build wächst, empfehlen wir ihn immer mehr Kunden.
Letztendlich empfiehlt unsere Dokumentation die Version dann als Stack der Wahl. Organisches Upgraden.
Da wir bisher nie einen Stack abgekündigt haben, hat dieser Ansatz für uns und unsere Kunden gut funktioniert. Das könnte sich jedoch ändern, und wir erklären Ihnen, warum.
Abkündigung
Bisher haben wir noch nie einen Stack abgekündigt. Tatsache ist jedoch: Mit jedem Stack, den wir hinzufügen, werden unsere Deploys ein wenig langsamer und unsere Support-Last steigt leicht an. Außerdem lassen sich uralte Stacks mit jedem Upgrade des Betriebssystems, das wir auf unseren Clustern ausrollen, schwerer kompilieren und laufen weniger reibungslos. Zwar stellen wir gerade auf Container um, was bei diesen Kompatibilitätsproblemen hilft, doch das verringert unsere Deploy-, Support- und Wartungslast nicht.
Deshalb erwägen wir nun, unseren FFmpeg-Stack v1.0.0 aus dem Jahr 2009 im
kommenden Jahr abzukündigen. Wir hielten es für das Beste, Sie so früh wie möglich darüber zu
informieren. Wir werden ganz sicher nichts überstürzen. Nur weil wir heute darüber nachgedacht
haben, teilen wir es Ihnen zu diesem Zeitpunkt mit.
FFmpeg-Stack v2.2.3
Hinweis: Unsere Versionierung sieht vielleicht wie SemVer aus, ist es aber nicht. Es handelt sich um eine interne Transloadit-Versionierung ohne öffentliche semantische Bedeutung. Jede Version kann die Abwärtskompatibilität brechen und sollte beim Upgrade entsprechend behandelt werden.
Auf unsere neueste Stack-Version sind wir am stolzesten. Sicher, v1.0.0 war
länger in Produktion und war ihrer Zeit definitiv voraus 😄, aber in
v2.2.3 haben wir mehr Aufwand gesteckt als in jede andere Version. Sie ist
bereits seit mehr als einem Jahr in Produktion. Sie hat mehr Traffic gesehen als alle ihre
Vorgänger. Nur ganz selten (nie ist ein gefährliches Wort, von dem wir uns lieber fernhalten)
sehen wir Probleme, die sich darauf zurückführen lassen, dass sie ein schlechter Build ist.
Da einige unserer größten Enterprise-Kunden ihn mit den ausgefallensten Anwendungsfällen einsetzen, haben wir das Vertrauen, diesen Build allen Kunden uneingeschränkt für sämtliche Audio- und Video-Encoding-Anforderungen zu empfehlen.
Upgrade
Betrachten Sie diese Beispiel-Instructions, in denen eingehende Uploads ins iPad-Format konvertiert werden, Vorschau-Thumbnails extrahiert werden und alle Ergebnisse anschließend per SFTP auf Ihren privaten Server exportiert werden:
steps:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
thumbnails:
use : "ipad"
robot : "/video/thumbs"
store:
use : [ ":original", "ipad", "thumbnails" ]
robot : "/sftp/store"
user : "transloadit-uploader"
host : "my.website.com"
path : "./transloadit-uploads"
url_template: "https://my.website.com/transloadit-uploads/${file.url_name}"
Diese Instructions wurden zur besseren Lesbarkeit aufbereitet, sollten aber als gültiges JSON codiert werden, wenn Sie sie an unseren Dienst übergeben.
Um diese Instructions auf unseren neuesten Stack umzustellen, fügen Sie in den
Steps für das Encoding den Parameter
ffmpeg_stack hinzu:
steps:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
thumbnails:
use : "ipad"
robot : "/video/thumbs"
ffmpeg_stack: "v2.2.3"
store:
use : [ ":original", "ipad", "thumbnails" ]
robot : "/sftp/store"
user : "transloadit-uploader"
host : "my.website.com"
path : "./transloadit-uploads"
url_template: "https://my.website.com/transloadit-uploads/${file.url_name}"
Das war's! 😄
Sie können den Parameter ffmpeg_stack auf die folgenden Robots anwenden:
Ihr Encoding läuft nicht nur schneller, Sie profitieren auch von höherer Qualität und können mehr Eingabeformate unterstützen als mit jeder früheren Version.
Einschränkungen
Zu schön, um wahr zu sein? Nun, nein, aber es gibt ein paar Dinge zu beachten: das Mapping und geänderte Parameternamen.
Mapping
Alle Voreinstellungen von v2.2.3 (wie android oder
iphone) wurden so angepasst, dass sie sämtliche Daten- und
Untertitel-Streams verwerfen. Nur sehr wenige Kunden haben diese Streams genutzt, aber weil wir
zuvor versucht haben, ihnen einen Platz in den Ausgabedateien zu geben, was uns manchmal misslang,
haben wir der Mehrheit unserer Kunden, die „einfach nur Ergebnisse wollen“, versehentlich viel
Kopfzerbrechen bereitet.
Wenn Sie auf Daten- oder Untertitel-Streams angewiesen sind, können Sie weiterhin die
Voreinstellungen von v2.2.3 nutzen und von den übrigen Verbesserungen dieses
Releases profitieren, müssen dann aber den Parameter map mit
0 überschreiben. Auf diese Weise finden alle Eingabe-Streams ihren
Platz in der Ausgabedatei, allerdings um den Preis, dass einige Dateien FFmpeg zum Scheitern
bringen, da es versucht, nicht unterstützte Datenstreams zu interpretieren.
Ein Kunde meldete ein Problem mit einer Eingabedatei, die zwei Videostreams enthielt. Unsere
Voreinstellungen von v2.2.3 versuchen, allen Video- und Audiostreams einen
Platz in der neuen Datei zu geben. Wenn Sie nur an einem einzelnen Video- und Audiostream
interessiert sind, setzen Sie das Mapping auf:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
ffmpeg:
map: [
"0:v:0?"
"0:a:0?"
"-0:d"
"-0:s"
]
Dies liefert Ihnen zwar das robusteste Mapping, beachten Sie aber, dass ein zweiter Stream desselben Medientyps verworfen würde.
Ehrlich gesagt scheint das für Endnutzer in 99 % der Fälle, die wir sehen, kein Problem zu sein. Deshalb erwägen wir, dies zum Standard für die Voreinstellungen unseres nächsten Stacks zu machen, die auf Handhelds abzielen.
Wir empfehlen immer, zusammen mit den Encoding-Ergebnissen auch Dateien vom Typ
:original zu exportieren, damit Sie die
Assembly bei Unzufriedenheit mit Ihren Einstellungen
einfach mit neuen Encoding-Parametern erneut ausführen können.
Geänderte Parameternamen
Wo FFmpeg früher mit einem Parameter -b für die Video-Bitrate und
-ab für die Audio-Bitrate gearbeitet hat, bewegt es sich nun in Richtung
einer Syntax mit -b:v und -b:a. Das gilt auch
für viele andere Parameter wie -codec:v gegenüber
-codec:a.
Das ist nicht nur konsistenter, sondern erlaubt Ihnen auch mehr Ausdruckskraft. Wenn Sie
beispielsweise nur den Codec für den zweiten Audiostream angeben möchten, können Sie
-codec:a:1 schreiben (der erste Stream hat den Index
0, der zweite also 1).
Wenn Sie also die Audio-Bitrate der ipad-high-Voreinstellung von v2.2.3
überschreiben möchten, müssen Sie wissen, dass aus ab nun
b:a geworden ist, sonst riskieren Sie, dass Ihre Änderungen an der
Voreinstellung keine Wirkung haben:
ipad:
use : ":original"
robot : "/video/encode"
preset : "ipad-high"
ffmpeg_stack: "v2.2.3"
ffmpeg:
"b:a": 144000
Fazit
Wir sehen große Verbesserungen mit unserem neuesten FFmpeg-Stack. Er ist schneller, liefert höhere Qualität, unterstützt adaptives Live-Streaming (HLS) und vieles mehr.
Wir empfehlen allen unseren Kunden, ihn einzusetzen, auch wenn zunächst nur für einen kleinen Prozentsatz ihrer Assemblies, und uns alle Probleme zu melden, die über die genannten Einschränkungen hinausgehen.
Später in diesem Jahr planen wir, hauptsächlich abhängig von Ihrem Feedback, unseren dann 7 Jahre
alten Stack v1.0.0 abzukündigen, worauf wir sicher gemeinsam anstoßen
werden! 😄






