Первое, что вам нужно сделать, это настроить канал связи между двумя клиентами, которые будут синхронизированы. Учитывая ваши требования к задержке, я предполагаю, что эти клиенты физически находятся рядом друг с другом и, вероятно, находятся в одной сети. В этом случае вам будет полезно создать одноранговое соединение WebRTC с каналом передачи данных между ними. Как правило, клиенты могут договариваться о соединении через сеть, к которой они совместно, вместо того, чтобы отправлять данные на сервер и обратно, что уменьшает задержку этого канала данных.
Далее, буферизируйте носитель, как обычно. Вы можете использовать .buffered
, чтобы определить, какие временные диапазоны были буферизованы. Как правило, вы можете положиться на событие canplaythrough
, чтобы определить, достаточно ли у игрока буферизовано, чтобы играть без необходимости повторного буфера.
Затем решите, какой конец будет «основным», откуда будут поступать все данные синхронизации. Начните воспроизведение с обеих сторон.
Регулярно, когда воспроизведение продолжается, мастер должен отправить свои currentTime
другим клиентам. Получив эти клиенты, они должны проверить свои currentTime
, чтобы узнать, как далеко они находятся. Оттуда они должны сделать расчет относительно того, как наверстать упущенное. Например, если ведущий находится на 100.100
, а подчиненный клиент на 100.000
, то он должен составлять 100 миллисекунд. Если вы установите playbackRate
на 1.01
, это время будет превышать 10 секунд. Или 1.02
, и вы сделаете это за 5 секунд.
Вы захотите придумать формулу, которая определяет серьезность десинхронизации и облегчает ее исправление. Вам также понадобятся некоторые разумные ограничения на эту скорость воспроизведения. (Например, вы, вероятно, не хотите идти быстрее / медленнее для синхронизации более, чем на 10%.) Кроме того, если они достаточно плохо разделены, вы можете приостановить один, установите currentTime
для другого ( который обычно вызывает некоторое отклонение) и начинается снова.
Улучшение, которое вы можете сделать, - это также определить задержку между ведущим / ведомым. Если мастер говорит: «Сейчас 12,345 с», а спустя 100 миллисекунд вы получите эту метку времени, то на самом деле это 12,445. Вы можете реализовать «пинг», когда задержка постоянно измеряется. А еще лучше добавьте это в каждое сообщение о времени.
Это должно помочь вам приблизиться по времени, достаточное для большинства случаев использования.