Estoy desarrollando BlaTube, una web para ver videos con amigos, comentarlos por chat o llamada y reaccionar juntos a lo que pasa en pantalla.
Con el proyecto fui viendo que compartir las reacciones también importa: reírse del mismo momento, bromear con un amigo o comentar algo mientras ocurre. De esas observaciones nacieron las reacciones animadas y, después, un lanzador de tomates.
Eso trajo dos problemas de sincronización: que todos vieran el mismo momento del video y que los efectos interactivos aparecieran en la misma zona de la imagen. En este artículo cuento cómo abordé ambos.
«¿Y tú en qué segundo vas?»
La primera versión de la sincronización era sencilla. El anfitrión iniciaba la reproducción, pausaba o adelantaba el video. El comando pasaba por el servidor y llegaba a los demás participantes. En esa versión no tenía en cuenta el tiempo de entrega.
Después la gente empezó a preguntarse: «¿En qué segundo vas?». Agregué la posición de cada participante a la interfaz. Las diferencias se veían sin tener que escribirlas en el chat, y empecé a investigar los retrasos.
La posición que recibe el espectador corresponde a un momento anterior. Por ejemplo, el anfitrión envía la posición de 120 segundos mientras el video sigue reproduciéndose. Si el mensaje tarda 300 ms en llegar, el anfitrión ya estará cerca del segundo 120,3. Si el espectador aplica la posición recibida sin corregirla, empieza atrasado.
Ahora el cliente mide periódicamente el RTT (Round-Trip Time): el tiempo que pasa desde que envía una solicitud al servidor hasta que recibe la respuesta. Entre varias mediciones elegimos la de menor RTT y estimamos la diferencia entre el reloj del cliente y el del servidor. Combinamos la estimación nueva con la anterior para que la corrección no cambie de golpe.
Cuando el servidor recibe la posición del anfitrión, estima cuándo se midió: a la hora de recepción le resta la mitad del RTT del anfitrión. Esa marca de tiempo está expresada en el reloj del servidor.
El espectador recibe la posición junto con esa marca de tiempo. Con el desfase estimado, convierte su marca de tiempo actual a la misma escala y calcula cuánto tiempo pasó desde la medición. El tiempo de procesamiento del servidor queda incluido en ese intervalo; no hay que sumarlo otra vez.
Si el video se está reproduciendo, el cálculo es:
posición actual ≈ posición recibida
+ tiempo desde la medición × velocidad de reproducción
Si está pausado, no sumamos ese avance.
Por ejemplo, un RTT de 200 ms para el anfitrión y de 400 ms para el espectador nos da unos 100 ms de recorrido hasta el servidor y otros 200 ms hasta el espectador. La actualización ya acumula unos 300 ms de viaje, además del procesamiento en el servidor.
Dividir el RTT entre dos es una aproximación: el camino de ida puede ser distinto al de vuelta. Además, cada reproductor necesita tiempo para cargar el video y ejecutar un salto. La corrección de red ayuda, pero todavía hay que tener en cuenta el comportamiento de cada reproductor.
Para intercambiar las actualizaciones usamos servidores regionales y así acortamos el recorrido de red. El anfitrión sigue siendo la referencia del estado de reproducción; el servidor valida y transmite las actualizaciones.
Todavía pienso en una versión en la que el propio servidor determine el estado común de reproducción. Podría simplificar el control de la sala y los permisos de los participantes. Por ahora mantuve al anfitrión como referencia.
Los tomates también necesitaban sincronización
Las reacciones animadas añadieron otra forma de participar durante el video, además del chat y las llamadas. Después hice un lanzador de tomates: alguien apunta a la imagen y dispara, y el resto de la sala ve los impactos.
Añadí eventos para registrar su uso y vi que la gente disparaba tomates. También hubo comentarios en Telegram. Eso me dio ganas de probar otras cosas, como un lanzador de palomitas.
Varias personas pueden disparar a la vez. Una tiene un monitor grande y otra un teléfono. El tamaño del video y la frecuencia de renderizado son distintos, pero los impactos tienen que coincidir.
No hace falta transmitir por la red la posición de cada tomate. Enviamos la activación, la dirección y los eventos de presionar y soltar el disparador. Los clientes crean los proyectiles localmente a partir de parámetros comunes: la semilla, la cadencia y el número de la salva. El servidor controla la munición y la duración de la sesión.
El punto de mira se expresa con relación al rectángulo del video. Cada cliente lo convierte a sus propias coordenadas de pantalla. El impacto debe caer en la misma zona de la imagen tanto en la computadora como en el teléfono.
Todos los lanzadores activos en un cliente comparten el mismo renderizador. No hace falta un ciclo de renderizado por persona.
Pueden probarlo en BlaTube.
Si han trabajado con reproductores sincronizados o efectos compartidos entre varios dispositivos, ¿cómo manejan los retrasos y las diferencias de tamaño de pantalla?


Top comments (0)