Von FFMPEG konvertiertes Video hat eine andere Dauer, warum?

Ich konvertiere Videos mit FFMPEG. Mein Ziel ist es, sie in das MP4-Containerformat ( MPEG-4 Part 14 ) mit AAC - codiertem Audiostream und MPEG-4 Part 10- codiertem Videostream zu konvertieren.

Ich verwende die folgende Zeile, um die Videos zu konvertieren:

ffmpeg -y -i "{inputFile}" "{outputFile}"

Das konvertierte Video sieht gut aus, jedoch stimmt die Dauer der Streams in der konvertierten Datei und der Eingabedatei nicht immer überein.

Ich habe einige Experimente gemacht und der Unterschied in der Dauer ist zweifellos da, aber es ist nicht so viel - ich teste sowieso mit kleinen Videos. Hier sind meine Ergebnisse:

| InputFile  | InputAudio | InputVideo | OutputAudio | OutputVideo  |
|------------|------------|------------|-------------|--------------|
| h.avi      | 3s 631ms   | 3s 567ms   | 3s 668ms    | 3s 567ms     |
| h.flv      | 3s 631ms   | 3s 558ms   | 3s 668ms    | 3s 567ms     |
| h.mov      | 3s 532ms   | 3s 533ms   | 3s 682ms    | 3s 534ms     |
| h.mp4      | 3s 605ms   | 3s 534ms   | 3s 682ms    | 3s 567ms     |
| h.mpg      | 3s 605ms   | 3s 533ms   | 3s 563ms    | 3s 534ms     |
| h.wmv      | 3s 620ms   | 3s 633ms   | 3s 659ms    | 3s 567ms     |

Da ich eine Software auf FFMPEG aufbauen würde, wäre ich glücklicher, wenn ich zumindest den Grund für diesen Unterschied verstehen könnte. Liegt es an einer unnötigen Transcodierung?

Kann ich in diesem Fall diese Transcodierung deaktivieren, um zu verhindern, dass FFMPEG meine Eingabevideodatei neu berechnet?

Wenn ich es nicht ausschalten kann, wie kann ich (außer dem Testen) sicher sein, dass dieser Unterschied nicht proportional zur Größe des Videos ist?

Konvertiere ich beispielsweise ein 10-Stunden-Video, ist ein Unterschied von mehreren Sekunden oder gar Minuten für mich nicht geeignet.

Ich würde denken, dass es von deinen Ein- und Ausgabe-Codecs abhängt. Lange GOP-Codecs können die Dauer des Videostreams ändern, um Keyframes dort zu platzieren, wo sie sein müssen, und GOPs zu schließen. Dieses Problem sollte bei der Transcodierung von Intra-Codecs zu Intra-Codecs nicht auftreten. Wenn Sie das Video nicht neu codieren müssen, verwenden Sie die Option „c:v copy“, wenn der Zielcontainer diesen Codec unterstützt.
Ich gehe davon aus, dass die Längenunterschiede bei längeren Videos nicht schlimmer werden. Es ist eher ein Start/End-Problem, kein Geschwindigkeitsdrift oder so etwas. Wenn ich Sachen mit ffmpeg xcodiere, bleiben die Anzahl der Frames, die Framerate und die Länge in Sekunden immer gleich. (es sei denn, ich möchte, dass es sich ändert!).
@audionuma: Kein vernünftiger Codec wird Frames hinzufügen/entfernen. mencoder tut dies aufgrund der A/V-Synchronisation manchmal, BEVOR er Frames an den Video-Codec weiterleitet. Ein Codec platziert Keyframes dort, wo er es für richtig hält (festes Intervall oder bei Szenenschnitten), und wenn der Encoder dem Codec mitteilt, dass dies der letzte Frame ist, schließt er diese letzte GOP, egal wie lang sie ist. Selbst bei nicht adaptiver Keyframe-Platzierung fügt kein Codec zusätzliche Frames hinzu, nur um die letzte GOP auf die gleiche Länge zu bringen!

Antworten (1)

Ich hoffe, diese Erklärung ist das, wonach Sie suchen:

  • Wenn Sie in eine Kodierung wie H.264 (MPEG-4 Teil 10) transcodieren, müssen Sie das Video zwangsläufig auch neu abtasten, das ist Teil der H.264-Komprimierungstechnik. Trotzdem bezweifle ich, dass dies der Grund für eine Timing-Lücke ist, da das Resampling nicht unbedingt die Taktrate der Medien beeinflusst. Ich würde mir also keine allzu großen Gedanken über das Resampling machen, es kann zu Abweichungen führen, ist aber wahrscheinlich sehr gering.

  • Die von Ihnen aufgelisteten Containerformate sind irgendwie irrelevant, da sie definieren, wie der komprimierte Stream gepackt wird, während die Quelle des Zeitunterschieds die Komprimierung selbst ist. Die .flvDatei kann beispielsweise einen Stream enthalten, der mit dem alten Flash-Sorenson-Codec oder dem neueren H.264 codiert ist. Im ersten Fall würden Sie den Videostream transcodieren, im letzteren ist es jedoch möglich, dass Sie dies nicht tun - abhängig vom verwendeten Audio-Codec. Die Container .aviund .wmvsind Codec-unabhängig, sodass es nicht einmal möglich ist, die Codierung ihres Inhalts zu erraten.

  • Sie haben nicht erwähnt, wie die Dauer getestet wurde. Beachten Sie, dass ffmpeg Ihnen standardmäßig die Dauer anzeigt, die in den Metadaten der Datei und nicht als berechneter Wert angezeigt wird. Wenn Ihre Liste auf den Daten basiert, die ffmpeg als Teil seiner Splash-Benachrichtigungen ausgibt, sollten Sie beachten, dass dies explizit Metadaten und kein tatsächlich gemessener Wert sind.

  • Das Delta in der von Ihnen präsentierten Dauer liegt im Bereich von einem oder zwei Frames in einem Bereich von 25 oder 30 fps. Es ist für Codecs vernünftig, Streams gemäß ihrem Algorithmus (oder der Sauberkeit des Entwicklers ...) mit leeren Frames aufzufüllen oder daraus zu entfernen. Es sollte keinen Einfluss auf die Zeitstempelung haben, wenn Sie Streams richtig verketten.

  • Mir fallen nur zwei Gründe ein, die die Dauer Ihrer Medien wesentlich ändern können, die in Ihrem speziellen Fall nicht zutreffen:

    1. Neucodierung mit einer anderen Zielgeschwindigkeit. Manchmal geschieht dies unbeabsichtigt aufgrund fehlerhafter Metadaten in der Eingabedatei. Aber nicht in Ihrem Fall, die, wie oben erwähnt, einem einzelnen verlorenen oder gewonnenen Frame entsprechen.

    2. Wenn Sie einen Codec anwenden, der einen der beiden Streams neu erstellt. Beispiele hierfür sind Ad-Stripping, Stilleerkennung, Rauschunterdrückung usw.

Fazit: Wenn Sie sich Sorgen machen, was mit einem 10-Stunden-Video passieren wird, führen Sie einfach einen tatsächlichen Test durch. Wenn Sie auf Probleme stoßen und Hilfe suchen, denken Sie daran, die Codec-Details der Eingabedatei und die Methode, mit der Sie die Stream-Dauer gemessen haben, zu posten.

Hoffe das hilft.

Tatsächlich ist das Containerformat wahrscheinlich relevant. Unterschiedliche Container speichern Zeitstempel/Frame-Dauern unterschiedlich. Und Längenrechner benötigen unterschiedlichen Code für unterschiedliche Containerformate, und dieser Code kann sich unterschiedlich verhalten. B. die Dauer zu zählen, für die der letzte Frame in einem angezeigt wird, in einem anderen jedoch nicht.
@PeterCordes, was meinst du mit "Länge" in deinem Kommentar? Wenn Sie "Dauer" meinen wollten, dann liegen Sie falsch, die Dauer ist immer die Anzahl der Frames mal der Zeitbasis. Wenn Sie etwas anderes meinen, geben Sie bitte an, was Sie mit "Länge" meinen.
Ich meinte Dauer. Nicht alle Videos haben eine konstante Framerate. Und die Art und Weise, wie Frame-Dauern gespeichert werden (als Bruchteil oder was auch immer, normalerweise Vielfache einer Zeitbasis), ist für verschiedene Container unterschiedlich. Das ist von meiner Seite irgendwie handgewellt und erfunden, da ich mir die Details nicht angesehen habe, aber ich bin mir ziemlich sicher, dass es nicht so einfach ist, wie wir es uns wünschen.
@PeterCordes, okay, aber das ist so selten und gehört nicht wirklich hierher, es wird nur in einigen Randfällen wie Bildschirmaufzeichnung, Diashows usw. verwendet Ein prägnanterer Begriff in ihrem Fall ist Hybridvideo (d. h. Streams mit unterschiedlichen Raten oder Zeitbasen, die ihre ursprünglichen konstanten Raten beibehalten, wenn sie gemuxt werden). Bei einem "normalen Film" gibt es fast immer eine bekannte Framerate, unabhängig davon, wie der Container sie in seinen Metadaten darstellt.