2014-04-25 5 views
13

Ich habe eine Server-Anwendung, die einen 30 FPS-Videostream rendert und dann in Echtzeit in eine WebM Byte Stream kodiert und multiplext.Wie Sie einen Live-MediaSource-Videostream synchron halten?

Auf der Client-Seite öffnet eine HTML5-Seite einen WebSocket für den Server, der mit der Generierung des Streams beginnt, wenn die Verbindung akzeptiert wird. Nachdem der Header geliefert wurde, besteht jeder nachfolgende WebSocket-Frame aus einem einzelnen WebM SimpleBlock. Ein Keyframe tritt alle 15 Frames auf und wenn dies passiert, wird ein neuer Cluster gestartet.

Der Client erstellt auch eine MediaSource, und beim Empfang eines Rahmens von der WS, hängt den Inhalt an seinen aktiven Puffer. Die <video> startet die Wiedergabe sofort nachdem das erste Bild angehängt wurde.

Alles funktioniert einigermaßen gut. Mein einziges Problem ist, dass der Netzwerkjitter dazu führt, dass die Wiedergabeposition nach einiger Zeit von der tatsächlichen Zeit abweicht. Meine aktuelle Lösung ist es, sich in das updateend Event einzuklinken, den Unterschied zwischen dem und dem Timecode des eingehenden Clusters zu überprüfen und das currentTime manuell zu aktualisieren, wenn es außerhalb eines akzeptablen Bereichs liegt. Leider verursacht dies eine merkliche Pause und einen Sprung in der Wiedergabe, der eher unangenehm ist.

Die Lösung fühlt sich auch ein bisschen seltsam an: Ich weiß genau, wo der neueste Keyframe ist, aber ich muss ihn in eine ganze Sekunde umwandeln (laut W3C-Spezifikation), bevor ich ihn in currentTime weitergeben kann, wo der Browser vermutlich muss dann umhergehen und den nächsten Keyframe finden.

Meine Frage ist: Gibt es eine Möglichkeit, dem Media Element mitzuteilen, immer nach dem neuesten verfügbaren Keyframe zu suchen oder die Wiedergabezeit mit der Systemuhrzeit synchronisiert zu halten?

+0

Haben Sie eine Lösung gefunden? –

+0

Ich habe festgestellt, dass Ihre Lösung, um currentTime zu ändern, die beste ist, die Störungen, die es verursacht, ist akzeptabel, weil zuvor ein Netzwerkfehler den Puffer erhöht hat, so ein weiterer Fehler, um es zu beheben ist normal ... es wird nur bleiben mit Störungen, wenn während des Streams fortlaufende Verbindungsprobleme auftreten. –

Antwort

3

Netzwerk-Jitter bewirkt, dass die Wiedergabeposition

treiben, das nicht Ihr Problem. Wenn Sie Dropouts im Stream haben, puffern Sie vor der Wiedergabe nicht genug Puffer, und die Wiedergabe hat nur einen Puffer in der richtigen Größe, auch wenn sie ein paar Sekunden hinter der Echtzeit liegt (was normal ist).

Meine aktuelle Lösung ist in den updateend Fall, überprüfen Sie die Differenz zwischen den video.currentTime und dem Timecode auf dem eingehenden Cluster

an Haken, der auf die richtige Methode der Nähe ist. Ich schlage vor, dass Sie den Timecode des eingehenden Clusters ignorieren und stattdessen Ihre gepufferten Zeitbereiche überprüfen. Was Sie im WebM-Cluster erhalten haben und was entschlüsselt wurde, sind zwei verschiedene Dinge.

Leider verursacht dies eine merkliche Pause und Sprung in der Wiedergabe, die ziemlich unangenehm ist.

Wie sonst würden Sie es tun? Sie können entweder zu Echtzeit springen oder Sie können die Wiedergabegeschwindigkeit erhöhen, um Echtzeit zu erreichen. So oder so, wenn Sie in Echtzeit aufholen wollen, müssen Sie rechtzeitig überspringen, um dies zu tun.

Die Lösung fühlt sich auch ein wenig seltsam: Ich weiß genau, wo das letzte Keyframe

ist, können Sie, aber der Spieler erst, dass die Medien dekodiert wird.In jedem Fall ist Keyframe irrelevant ... Sie können nach Nicht-Keyframe-Positionen suchen. Der Browser entschlüsselt bei Bedarf die P/B-Frames.

Ich habe es in eine ganze Sekunde zu konvertieren (gemäß der W3C-Spezifikation), bevor ich es in current passieren kann

, die völlig falsch ist. Die currentTime wird als double angegeben. https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-currenttime

Meine Frage ist: Gibt es eine Möglichkeit, die Medienelemente zu sagen, um die neuesten Keyframe zur Verfügung zu immer zu suchen, oder halten Sie die Wiedergabezeit mit der Systemuhrzeit synchronisiert?

Es wird der letzte Puffer automatisch spielen. Du musst nichts tun. Sie machen Ihre Arbeit, indem Sie sicherstellen, dass die Mediendaten im Puffer landen und die Wiedergabe so nah wie möglich an die Wiedergabe anpassen. Sie können es immer weiterleiten, wenn sich ein Netzwerkzustand ändert, was Ihnen erlaubt, dies zu tun, aber ehrlich gesagt klingt es so, als hätten Sie nur kaputten Code und eine kaputte Pufferungsstrategie. Ansonsten wäre die Wiedergabe einfach flüssig.

Aufholen, wenn es zurückfällt, wird nicht automatisch passieren, und sollte es auch nicht. Wenn der Player aufgrund des Pufferverlustes pausiert, muss ein Puffer neu aufgebaut werden, bevor die Wiedergabe fortgesetzt werden kann. Das ist der springende Punkt des Puffers.

Darüber hinaus ist Ihre Erwartung, etwas in der Zeit mit der Systemuhr zu halten, keine gute Idee und ist unvernünftig. Verschiedene Geräte haben unterschiedliche Bildwiederholraten und können Videos mit unterschiedlichen Geschwindigkeiten verarbeiten. Drücken Sie einfach auf Play und lassen Sie es spielen. Wenn Sie mehrere Sekunden Pause haben, gehen Sie voran und setzen Sie currentTime, aber seien Sie sehr zuversichtlich, was Sie vorher gepuffert haben.

+0

Nicht sicher, wenn Sie das Problem haben, aber wenn Sie eine MP3-Datei zum Beispiel von Knoten mit Sockets in Paketen von 2,7 Sekunden z. B. liefern, startet der Player wie es sollte, aber wenn Sie es manuell anhalten, beginnt der Puffer zu erhöhen und wenn du wieder spielst, beginnt es dort, wo du es gestoppt hast. Dies führt dazu, dass die Wiedergabe nicht mit dem Nodejs-Stream synchronisiert ist. Das passiert, wenn Sie die Wiedergabe für mehrere Stunden zulassen, wird sie aufgrund von Störimpulsen automatisch angehalten und der Puffer beginnt sich zu erhöhen. –

+0

Der Nodejs sendet 2,7 Sekunden, warten Sie auf die Wiedergabe und senden Sie dann das nächste Paket. Aber mit steigendem Puffer können Sie nicht mehr kontrollieren, ob die gestreamten Daten abgespielt wurden oder nicht. Ich habe versucht, eine "Bestätigung" zu senden, die besagt, dass das Paket abgespielt wurde, so dass der nächste geliefert werden kann, aber andere Probleme bekommen hat. Wie die Wiedergabe stoppt. Die Frage ist also, Daten zu streamen und sie kontinuierlich stundenlang abzuspielen. –

+0

@KeyneViana Warum würden Sie warten, um den nächsten Datenblock zu senden? Sende es einfach weiter. Außerdem sollten Sie nicht 2,7 Sekunden warten ... MP3-Frames können so klein wie 576 Samples sein. – Brad