Ich möchte die Wiedergabe eines Videos auf mehreren Clients synchronisieren. Ein Client gibt dem Server eine URL zu einem Video, das gestreamt werden kann, und klickt auf Wiedergabe. Dann soll jeder Client das Video genau zur gleichen Zeit abspielen. Und während des Spielens muss sichergestellt sein, dass jeder Client noch synchron ist. Wenn jemand plötzlich aufhört zu spielen, müssen auch alle anderen so schnell wie möglich aufhören. (Zu diesem Zeitpunkt würde der Client, der gestoppt hat, ungefähr 1 Sekunde zurückliegen.) Wenn dieselbe Person wieder zu spielen beginnt, müssten alle anderen offensichtlich eine Sekunde warten, bis der eine Client aufgeholt hat, und dann auch anfangen zu spielen.

Mein erster Versuch war, eine mySQL-Datenbank einzurichten und jedem Client ständig seine aktuelle Videozeit zu melden. Der Server berechnete dann, ob ein Client in der Datenbank im Rückstand ist, und wenn ja, berechnete er für jeden Client, wie lange er pausieren müsste, damit er aufholt.

Aber das hat nicht wirklich gut funktioniert. Es hing stark von Ihrer Latenz ab und ich konnte es nicht mit einer Verzögerung von <300 ms zuverlässig zum Laufen bringen (dafür war eine wirklich gute Latenz erforderlich).

Was könnte ich also tun, um es zu verbessern? Sollte ich mein Setup ändern (Javascript <-> Ajax <-> PHP <-> MySQL)?

Wie kann ich die Reisezeit der Antwort, die der Server an einen Client sendet, zuverlässig berechnen? Ich kann nicht einfach davon ausgehen, dass die Systemzeit des Clients dieselbe ist wie die des Servers ... Das Beste, was ich mir einfallen lassen könnte, wäre etwa Folgendes:

var start = new Date().getTime()
$.post( "sync.php", "")
.done(function(data) {
    var end = new Date().getTime()/1000;
    var clientServerClientTravelTime = (end-start);
    var estimatedServerClientTravelTime = clientServerClientTravelTime/2;
});

Irgendeine Idee, wie ich dieses ganze Konzept verbessern könnte?
Übrigens kann Video nicht auf meinem eigenen Server sein.

12
Forivin 16 Aug. 2015 im 12:26

4 Antworten

Beste Antwort

Ich schlage vor, NodeJS und Sockets zu programmieren. Außerdem können Sie http://www.webrtc.org verwenden

3
Atul Jindal 25 Aug. 2015 im 06:07

Wie jemand anderes sagte, würde ich wahrscheinlich einen kleinen Websocket-Server in NodeJS einrichten. Die Idee ist, eine Liste von Ereignissen wie "Wiedergabe", "Pause" zu erstellen. Wenn ein Client eine Verbindung herstellt, fragt er den Server, wo er mit der Wiedergabe beginnen soll (da der andere Client möglicherweise zuvor gestartet wurde), oder wenn Sie möchten, können Sie bei jeder Verbindung ein "StartAgain" -Ereignis an alle Clients senden. Sobald das Video gestartet wurde, können Sie die HTML-Audio- / Video-Ereignisse anhören, um festzustellen, ob ein Client-Video nicht mehr abgespielt werden kann. In diesem Fall senden Sie ein "Pause" -Ereignis an Ihren Server, das es an alle anderen Clients sendet, um die Wiedergabe ebenfalls anzuhalten. Wenn das Video fortgesetzt wird, können Sie das Ereignis "Abspielen" senden.

1
Alekos Filini 25 Aug. 2015 im 08:20

Haben Sie versucht, WebRTC zu verwenden, wird es für Peer-to-Peer-Verbindungen und auch für Streaming verwendet. Mit WebRTC können Sie Multy-Streams von einem Client zu anderen erstellen. Ich habe damit Videos an andere Personen gestreamt, und jeder, der eine Verbindung herstellt, erhält das Video, aber ich streame es nicht auf dem Server. Ich habe nur das Video gesteuert. Pause , Klang, .....

Sie können es versuchen, aber in Ihrem Fall kann jeder Client den Stream steuern. Persönlich habe ich so etwas noch nicht ausprobiert, aber auf diese Weise haben Sie keine Probleme mit Latenz, Pausen usw.

0
Nermin 21 Aug. 2015 im 13:10

Der genaueste Weg wäre wahrscheinlich die Verwendung von Sockets: Auf diese Weise können Sie anderen Systemen signalisieren, was erforderlich ist, und müssen nicht auf Ajax-Abfragen warten. Sie können die Latenz nicht genau kompensieren, können jedoch die Durchschnittswerte ermitteln, indem Sie den Roundtrip mit einigen Testmeldungen messen.

Der Plan wäre also:

  1. Alle Clients laden das vorbereitete Video vor
  2. Alle Clients öffnen den Socket für den Server und geben an, dass sie bereit sind zu rumpeln
  3. Der Server führt einige schnelle Testnachrichten aus, um die Latenz zu messen.
  4. Der Server sendet die "go" -Nachricht an alle Clients und verzögert möglicherweise die Berücksichtigung der Latenz (oder gibt die Zeit an, zu der der Client stattdessen pausieren muss. In beiden Fällen funktioniert dies).
  5. Wenn ein Client stoppt, sendet er eine Nachricht an den Server. Der Server sendet sofort eine Nachricht an einen anderen Client, um den Vorgang zu beenden.
  6. Kunden antworten mit, wo sie angehalten werden
  7. Passen Sie beim Neustart die Startmeldungen an, um sowohl die Latenz als auch die Tatsache zu berücksichtigen, dass einige Clients später geringfügig angehalten werden.

Ich habe etwas sehr Ähnliches verwendet, um 18 Projektoren in 3 Autos für ein AV-Anzeigesystem zu synchronisieren. (https://vimeo.com/97191170). Trotz der Kommentare von Xorifelse in seiner Antwort war PHP perfekt in der Lage, bis zu 100 Socket-Befehle pro Sekunde von einem Controller (jquery-basierte Anwendung in einem Browser, verbunden durch Sockets) zu empfangen, zu verarbeiten und zu verarbeiten, Duplikate herauszufiltern und alle bei mySQL zu protokollieren Ein zweiter Vorgang zum Abrufen bei Bedarf (ca. 10 Mal pro Sekunde, ausgelöst durch eine Socket-Anforderung aus einem Flash-Skript (Adobe Air) und Weiterleiten von Lichtanweisungen an die Beleuchtung unter dem Auto (auch über Sockets) oder an andere Autos (auch über) Sockets). Tatsächlich war die PHP / MySQL-Lösung weitaus robuster als der Versuch, Socket-Anweisungen direkt in Flash zu pumpen. Dies ist sehr gut möglich. Technische Details für das Projekt finden Sie hier: http://labs.soapcreative.com/cars-that-feel-vivid-sydney/

4
Robbie 22 Aug. 2015 im 13:53