2015-06-16 10 views
8

Ich bin ein fragmentiertes mp4 für html5-Streaming erstellen, mit dem folgenden Befehl:Flush & Latency Ausgabe mit fragmentierten MP4 Creation in FFMPEG

-i rtsp://172.20.28.52:554/h264 -vcodec copy -an -f mp4 -reset_timestamps 1 -movflags empty_moov+default_base_moof+frag_keyframe -loglevel quiet - 
  1. „-i rtsp: //172.20.28.52: 554/h264 "weil die Quelle h264 im rtp-Paketstrom von einer IP-Kamera ist. Zu Testzwecken wird die Kamera mit GOP von 1 gesetzt (d. H. Alle Rahmen sind Schlüsselrahmen)
  2. "-vcodec copy", weil ich keine Umcodierung benötige, nur Remuxen zu MP4.
  3. "-movflags empty_moov + default_base_moof + frag_keyframe" zum Erstellen eines fragmentierten mp4 gemäß der Spezifikation der Medienquellenerweiterungen.
  4. "-" am Ende, um die mp4 auf stdout auszugeben. Ich nehme die Ausgabe und sende sie über Web-Sockets an den Webclient.

Alles funktioniert gut, erwarten Sie ein Latenzproblem, das ich versuche zu lösen. Wenn ich jedes Mal eine Daten kommen aus stdout, mit dem Zeitstempel der Ankunft anmelden, erhalte ich diese Ausgabe:

16/06/2015 15: 40: 45,239 Datengröße = 24

bekam

16/06/2015 15: 40: 45,240 bekam Datengröße = 7197

16/06/2015 15: 40: 45,241 Datengröße bekam = 32768

16/06/2015 15: 40: 45,241 hat Datengröße = 4941

16/06/2015 15 40: 45,241 bekam Datengröße = 12606

16/06/2015 15: 40: 45,241 bekam Datengröße = 6345

16/06/2015 15: 40: 45,241 Daten bekam size = 6339

16/06/2015 15: 40: 45,242 bekam Datengröße = 6336

16/06/2015 15: 40: 45,242 Datengröße bekam = 6361

16/06/2015 15: 40: 45,242 bekam Datengröße = 6337

16/06/2015 15: 40: 45,242 bekam Datengröße = 6331

16/06/2015 15: 40: 45,242 Datengröße bekam = 6359

16/06/2015 15: 40: 45,243 Daten size = 6346

bekam

16/06/2015 15: 40: 45,243 bekam Datengröße = 6336

16/06/2015 15: 40: 45,243 Datengröße bekam = 6338

16/06/2015 15: 40: 45,243 hat Datengröße = 6357

16/06/20 15 15: 40: 45,243 bekam Datengröße = 6357

16/06/2015 15: 40: 45,243 Datengröße = 6322 bekam

16/06/2015 15:40:45.erhielt 243 Datengrße = 6359

16/06/2015 15: 40: 45,244 Datengrße erhielt = 6349

16/06/2015 15: 40: 45,244 erhielt Datengrße = 6353

16/06/2015 15: 40: 45,244 bekam Datengröße = 6382

16/06/2015 15: 40: 45,244 Datengröße bekam = 6403

16/06/2015 15: 40: 45,304 Datengröße bekam = 6393

16.06.2015 15: 40: 4 erhielt 5.371 Datengrße = 6372

16/06/2015 15: 40: 45,437 Datengrße erhielt = 6345

16/06/2015 15: 40: 45,504 erhielt Datengrße = 6352

16/06/2015 15: 40: 45,571 bekam Datengröße = 6340

16/06/2015 15: 40: 45,637 Datengröße bekam = 6331

16/06/2015 15: 40: 45,704 Datengröße bekam = 6326

16/06/2015 15:40 erhielt 45,771 Datengrße = 6360

16/06/2015 15: 40: 45,838 Datengrße erhielt = 6294

16/06/2015 15: 40: 45,904 Datengrße = 6328

16 erhielt/06/2015 15: 40: 45,971 erhielt Größe data = 6326

16/06/2015 15: 40: 46,038 erhielt Datengrße = 6326

16/06/2015 15: 40: 46,105 Datengrße bekam = 6340

16/06/2015 15: 40: 46,171 bekam Größe data = 6341

16/06/2015 15: 40: 46,238 bekam Datengröße = 6332

Wie Sie sehen können, werden die ersten 23 Zeilen (die Daten von etwa 1,5 Sekunden enthalten von Video) kommen fast sofort an, und dann ist die Verzögerung zwischen jeweils 2 aufeinanderfolgenden Zeilen ~ 70 ms, was sinnvoll ist, weil das Video 15 Bilder pro Sekunde ist. Dieses Verhalten führt zu einer Wartezeit von ca. 1,5 Sekunden.

Es sieht aus wie ein Spülungsproblem, weil ich keinen Grund sehe, warum ffmpeg die ersten 23 Bilder im Speicher halten müsste, besonders da jedes Bild ein eigenes Fragment im mp4 ist. Ich konnte jedoch keine Methode finden, die ffmpeg veranlassen würde, diese Daten schneller zu löschen.

Hat jemand einen Vorschlag?

würde Ich mag zu beachten, dass dies eine Follow-up-Frage zu dieser ist: Live streaming dash content using mp4box

+0

Es ist mir aufgefallen, dass Sie Kontrolle über die 'blocksize' haben, die für die Pufferung der Ausgabe verwendet wird. Überprüfen Sie http://www.ffmpeg.org/ffmpeg-all.html#toc-pipe und sehen Sie, ob das Optimieren dieses Wertes Ihnen dort helfen kann. –

+0

@PabloMontilla Ich habe versucht, mit verschiedenen Werten von blocksize zu spielen und obwohl es die Ausgabe in irgendeiner Weise bewirkt hat, hat es die anfängliche Verzögerung nicht gelöst. – galbarm

+0

Hallo @galbarm! Ich kann das Video nicht auf einer Seite mit den 'ffmpeg'-Parametern ausführen, wobei ich immer' Skipping unrecognized top-level box: ftyp' bekomme. (h264 ip cam). Ich habe auch versucht, '-vcodec' in' libx264' zu ändern. In diesem Fall bekomme ich 'Skipping unrecognized top-level box: mdat'. Kannst du bitte deinen Code näher beschreiben oder irgendwo angeben? Der interessanteste Teil ist der ".addSourceBuffer" -Param, d.h. die Codec-Zeichenkette. Danke im Voraus! – zarkone

Antwort

4

Der Schlüssel um die Verzögerung zu entfernen, ist das Argument -probesize zu verwenden:

probe integer (input)

Set Sondieren Größe in Bytes, dh die Größe des den Daten analysieren, um Strominformationen zu erhalten. Ein höherer Wert ermöglicht das Erkennen weiterer Informationen, falls es in den Stream verteilt ist, erhöht jedoch die Latenz. Muss eine Ganzzahl nicht kleiner als 32 sein. Standardmäßig ist es 5000000.

Standardmäßig ist der Wert 5.000.000 Bytes, was ~ 1,5 Sekunden Video entspricht. Ich konnte die Verzögerung fast vollständig eliminieren, indem ich den Wert auf 200.000 reduzierte.

0

ich das Latenzproblem gelöst, indem die Option -g mit der Anzahl der Frames in der Gruppe zu setzen. In meinem Fall habe ich -g 2 verwendet.Ich vermute, dass das Fragment entweder wartet, bis die Quelle das Schlüsselbild bereitstellt, oder verwendet einen wirklich großen Standardwert, um das Schlüsselbild zu generieren, bevor das Fragment geschlossen und auf stdout ausgegeben wird.

+0

Ich vermute, dass Sie das Video transkodieren, damit Sie die Ausgabe-GOP-Größe kontrollieren können. Ich verwende ffmpeg im Modus "vcodec copy" und remuxe es nur in fragmentierten mp4.Ich habe versucht, die Quelle meines Videos (IP-Kamera) zu setzen, um nur Schlüsselrahmen zur Verfügung zu stellen, aber es half nicht mit der Anfangswartezeit. – galbarm

0

Normalerweise ist die Pufferung für stdout im Falle einer Konsolenausgabe deaktiviert. Wenn Sie ffmpeg aus dem Code ausführen, ist die Pufferung aktiviert, sodass Sie Ihre Daten nur erhalten, wenn der Puffer voll ist oder der Befehl endet.

Sie müssen die Pufferung der stdout Ihres Betriebssystems beseitigen. Auf Windows ist es unmöglich imo, aber auf Ubuntu für ex. Es gibt http://manpages.ubuntu.com/manpages/maverick/man1/stdbuf.1.html