Ein MP4 ist eine Box aus Boxen
Eine MP4-Datei ist aus Boxen aufgebaut. (Der ältere Name, den die Spezifikation ihnen gibt, Atome, ist der, der sich in Fehlermeldungen gehalten hat.) Jede Box beginnt mit demselben 8-Byte-Header: 4 Bytes, die angeben, wie groß die Box ist, dann 4 Zeichen, die angeben, um welche Art von Box es sich handelt. Das ist die ganze Grammatik. Boxen können andere Boxen enthalten, und ein Parser läuft durch die Datei, indem er einen Header liest, entscheidet, ob er hineinschaut, und um die angegebene Größe zur nächsten vorspringt.
Öffne irgendeine fertige Aufnahme (von einem Smartphone, einer GoPro, OBS, einer Drohne) und auf der obersten Ebene findest du dieselben drei Boxen, die die ganze Arbeit machen:
Deklariert „das ist ein MP4“ und welche Variante des Formats Player erwarten sollen. Das Erste in der Datei.
Die komprimierten Audio- und Video-Frames, dicht an dicht in der Reihenfolge gepackt, in der sie aufgenommen wurden. Keine Beschriftungen, keine Zeitstempel, keine von außen sichtbaren Frame-Grenzen, nur Nutzlast.
Die Landkarte von allem darüber: wo jeder Frame beginnt, wie groß er ist, wann er abspielt. Boxen in Boxen:
MOV-Dateien, das QuickTime-Format, von dem MP4 abgeleitet wurde, teilen genau diese Struktur, und deshalb sind ein MOV, das sich nicht öffnen lässt und ein MP4, das sich nicht öffnen lässt, fast immer dasselbe Problem in unterschiedlichen Dateiendungen.
Das moov-Atom ist die Landkarte
Hier kommt der Teil, der die Leute überrascht: der Datenblock istundurchsichtig. Komprimierte Frames sitzen in mdat dicht an dicht, ohne dass etwas sie trennt, ohne Markierungen, die sagen „Frame 412 beginnt hier“. Jede Frage, die ein Player beantwortet haben muss, wohnt stattdessen im moov-Atom, in einer Reihe von Strukturen namens Sample-Tabellen:
- Wo ist jeder Frame? Die Chunk-Offset-Tabelle (
stco) hält die Byte-Positionen innerhalb der Datei fest. - Wie groß ist jeder Frame? Die Sample-Größen-Tabelle (
stsz) listet die Länge jedes Frames auf, ein Eintrag pro Frame. - Wann spielt jeder Frame? Die Time-to-Sample-Tabelle (
stts) bildet die Frames auf die Uhr des Films ab, damit Audio und Video im Gleichschritt bleiben. - Wohin kann die Wiedergabe springen? Die Sync-Sample-Tabelle (
stss) listet die Keyframes auf, die einzigen Frames, von denen ein Decoder starten kann, und genau das macht das Spulen möglich.
Sogar die Konfiguration des Decoders (die Parameter, die ihm sagen, wie das Video komprimiert wurde) ist im moov-Atom gespeichert, nicht im Stream. Einem Player ohne das moov-Atom fehlen nicht bloß die Kapitelmarken; er weiß nicht, wo auch nur ein einziger Frame beginnt, wie lang das Video ist oder wie er seinen Decoder einrichten soll. Stell dir eine Bibliothek vor, in der die Bücher ohne Buchrücken, ohne Titel und ohne Katalog im Regal stehen: die Information ist vollständig vorhanden, und nichts davon ist erreichbar. Das ist mdatohne moov, und deshalb geben Player komplett auf, statt „das meiste“ einer beschädigten Datei abzuspielen.
Warum der Index zuletzt geschrieben wird
Das moov-Atom beschreibt jeden Frame: seine Position, seine Größe, sein Timing. Während du aufnimmst, lässt sich nichts davon wissen: Die Kamera hat keine Ahnung, ob du in zehn Sekunden oder in zwei Stunden aufhörst, und der Byte-Offset eines Frames lässt sich nicht festhalten, bevor der Frame existiert. Also macht jeder Recorder das Einzige, was er kann. Er streamt komprimierte Frames in mdat, sobald sie codiert sind, führt die laufende Buchhaltung im Speicher und schreibt den Index in einem Durchgang in dem Moment, in dem du auf Stopp drückst.
Während der Aufnahme: Frames werden angehängt, sobald sie codiert sind. Der Index kann noch nicht existieren; sein Inhalt steht erst fest, wenn der letzte Frame geschrieben ist.
Finalisierung: Der Recorder misst alles, was er geschrieben hat, und hängt das moov-Atom an. Erst jetzt ist die Datei abspielbar.
Dieses Design ist effizient und sicher, genau bis zu dem Punkt, an dem die Aufnahme den Finalisierungsschritt nicht erreicht. Ein leerer Akku, ein OBS-Absturz, eine Drohne im See: Der Prozess, der die Datei schreibt, hält an, und der Index wird nie geschrieben. Was auf der Platte übrig bleibt, ist eine Datei mit gesunder Größe, Stunden intakten Materials in mdat und keine Landkarte. Jeder Player weist sie ab; ffmpeg gibt moov atom not found aus. Das Material ist nicht weg; es ist gestrandet. (Die allerletzten Sekunden, noch im Speicherpuffer der Kamera und noch nicht auf den Datenträger geschrieben, sind weg. Ehrliche Tools sagen das.) Genau für diesen gestrandet-aber-intakt-Zustand gibt es diemoov-Atom-Reparatur, und es ist der typische Fehlerfall bei abgestürzten OBS-Aufnahmen.
faststart und fragmentiertes MP4
Das Design mit Index am Ende hat zwei bekannte Konsequenzen, und die Branche hat für jede eine Lösung gebaut.
faststart: den Index nachträglich nach vorne verschieben
Ein Browser, der ein Video aus dem Web streamt, liest die Datei von vorne nach hinten. Steht das moov-Atom am Ende, kann die Wiedergabe erst beginnen, wenn die ganze Datei heruntergeladen ist; der Player hält das Buch in der Hand und wartet auf den Katalog. Die Lösung ist ein Nachbearbeitungsdurchgang (ffmpegs -movflags +faststart), der die fertige Datei mit nach vorne verschobenem moov-Atom neu schreibt:
Eine „faststart“-Datei: zuerst der Index, damit die Streaming-Wiedergabe sofort beginnen kann. Deshalb starten manche Web-Videos sofort und andere stocken.
Beachte, was faststart nicht ist: ein Schutz vor Abstürzen. Es läuft auf einer vollständigen, gesunden Datei, nachdem die Codierung beendet ist. Eine Aufnahme, die mitten im Schreiben stirbt, erreicht diesen Schritt nie.
Fragmentiertes MP4: viele kleine Indizes statt eines großen
Die zweite Konsequenz (verliere die Finalisierung, verliere die Datei) adressiert das fragmentierte MP4. Statt einemmdat und einem moov am Ende wird die Datei als eine Kette kurzer, selbstbeschreibender Segmente geschrieben, jedes ein Stück Daten mit seinem eigenen Mini-Index (einer moof-Box). In ffmpeg-Begriffen: -movflags frag_keyframe+empty_moov – ein Skelett-moov vorne, dann Fragment für Fragment. Stirbt der Recorder, verlierst du höchstens das letzte Fragment, und alles davor ist bereits indiziert und abspielbar. Streaming-Dienste liefern Video aus demselben Grund so aus. Der Preis dafür ist die Kompatibilität: Manche Editoren und ältere Player kommen mit fragmentierten Dateien schlecht zurecht, und deshalb schreiben Kameras weiterhin das klassische Layout. Die Antwort von OBS (in OBS 30.2 und neuer) heißt „Hybrid MP4“ und bewahrt die Absturzresistenz im Fragment-Stil, während sie in eine breit kompatible Datei finalisiert, lohnt sich zu aktivieren, wenn dich OBS-Abstürze schon einmal erwischt haben.
Wie die moov-Rekonstruktion funktioniert
Ein Absturz hat dich also mit ftyp, einem riesigenmdat und keinem Index zurückgelassen. Ihn wiederaufzubauen ist möglich, weil der „undurchsichtige“ Datenblock für einen Parser, der die Codecs kennt, nicht vollkommen undurchsichtig ist. Inmdat sind Video-Frames als längenpräfixierte Einheiten gespeichert, und der Bitstream jedes Codecs hat erkennbare Muster: Header, die Typ, Abmessungen und Grenzen eines Frames markieren. Rekonstruktions-Tools (das Open-Source-Projekt untrunc hat den Ansatz etabliert, und es ist die Art von Reparatur, die die Video-Engine von IntactFile durchführt) laufen Byte für Byte durch die Rohdaten:
- Die Frame-Grenzen finden.
mdatscannen und anhand der Längenpräfixe und Codec-Signaturen bestimmen, wo jeder Video- und Audio-Frame beginnt und endet. - Klassifizieren und messen. Jeden Frame seinem Stream zuordnen und seine Größe und Position festhalten, so wird Sample für Sample das Rohmaterial von
stszundstcowieder aufgebaut. - Das Timing rekonstruieren. Die Frame-Dauern aus den Einstellungen des Encoders ableiten. Deshalb verlangt
untrunceine gesunde Referenzdatei, die mit denselben Einstellungen aufgenommen wurde, um zu lernen, wie „normal“ für dein Gerät aussieht. - Ein neues moov schreiben und finalisieren. Die Sample-Tabellen zu einem frischen Index zusammensetzen und eine spezifikationskonforme Datei ausgeben.
Das Ergebnis spielt alles ab, was physisch überlebt hat, und endet dort, wo die Daten enden. Die ehrlichen Grenzen ergeben sich direkt aus dem Mechanismus: Aufnahmen mit stark unregelmäßigem Frame-Timing können mit einem leichten Versatz zwischen Audio und Video zurückkommen, und wenn mdat selbst nur Nullen enthält (der Speicher hat versagt, nicht der Recorder) gibt es keine Frames zu finden, und kein Tool kann sie herbeizaubern. Für das größere Bild, welcher Schaden welcher ist, siehe wie Videodateien beschädigt werden und was wirklich reparierbar ist.
Häufige Fragen
Was ist das moov-Atom in einer MP4-Datei?
Das moov-Atom ist der Index des MP4: ein strukturierter Block, der festhält, wo jeder Video- und Audio-Frame in der Datei sitzt, wie groß jeder ist, wann er angezeigt werden soll und wie die Streams synchronisiert werden. Er trägt außerdem die Decoder-Konfiguration. Ein Player liest zuerst das moov-Atom und nutzt es als Landkarte in die Mediendaten. Ohne ein gültiges moov-Atom lässt sich die Datei nicht öffnen, selbst wenn das Material selbst intakt ist.
Warum steht das moov-Atom am Ende der Datei?
Weil sein Inhalt erst feststeht, wenn die Aufnahme endet. Das moov-Atom listet Größe, Position und Timing jedes Frames auf, Informationen, die erst existieren, wenn der letzte Frame geschrieben ist. Also hängen Recorder die Frames laufend an und schreiben den Index in einem Durchgang beim Finalisieren, wodurch er hinter den Mediendaten landet. Bei Dateien, die fürs Web-Streaming vorbereitet werden, wird das moov hinterher oft nach vorne verschoben („faststart“), aber das ist ein Nachbearbeitungsschritt und nicht die Art, wie die Datei entsteht.
Lässt sich ein fehlendes moov-Atom wiederaufbauen?
In der Regel ja, sofern die Mediendaten (der mdat-Block) überlebt haben. Rekonstruktions-Tools scannen den rohen Stream, erkennen die Grenzen jedes Frames, messen Größen und Positionen und bauen die Sample-Tabellen wieder auf, die das moov-Atom enthalten hätte. Das Ergebnis ist eine abspielbare Datei, die alles bis zum Zeitpunkt der Unterbrechung abdeckt. Fehlt der mdat-Block, ist er auf Null gesetzt oder überschrieben, gibt es nichts zu indizieren, und kein Tool kann die Datei wiederaufbauen. Du kannst eine Datei in deinem Browser prüfen, um zu sehen, welcher Fall bei dir vorliegt.
Was ist der Unterschied zwischen moov und mdat?
mdat enthält die Nutzlast: die komprimierten Audio- und Video-Frames, dicht an dicht gepackt, typischerweise 99 % der Dateigröße. moov enthält die Metadaten: den Index, der beschreibt, wo jeder Frame in mdat beginnt, wie groß er ist, sein Timing und die Decoder-Einstellungen, die zum Abspielen nötig sind. mdat ohne moov ist Material ohne Landkarte: die Daten sind da, aber kein Player kann sich darin bewegen. moov ohne mdat ist die Landkarte eines Gebiets, das es nicht mehr gibt.
Was bewirkt movflags faststart?
In ffmpeg verschiebt -movflags +faststart das moov-Atom vom Ende einer fertigen Datei nach vorne, direkt hinter den Dateityp-Header. Player können dann die Wiedergabe starten, während der Rest der Datei noch heruntergeladen wird, und deshalb ist es Standard für Web-Video. Es erfordert, die Datei neu zu schreiben (ffmpeg macht einen zweiten Durchgang), und funktioniert nur bei einer gesunden, vollständigen Datei. Es schützt eine Aufnahme nicht vor Abstürzen und kann eine Datei nicht reparieren, deren moov nie geschrieben wurde.
Ebenfalls in dieser Reihe: wie Videodateien beschädigt werden – und was wirklich reparierbar ist.