diff --git a/materialious/src/lib/Player.svelte b/materialious/src/lib/Player.svelte index c20385bd..75f41b2f 100644 --- a/materialious/src/lib/Player.svelte +++ b/materialious/src/lib/Player.svelte @@ -231,7 +231,6 @@ title={data.video.title} streamType={data.video.hlsUrl ? 'live' : 'on-demand'} viewType={audioMode ? 'audio' : 'video'} - playsInline={true} keep-alive {src} > diff --git a/materialious/src/lib/player.ts b/materialious/src/lib/player.ts index f42651bf..f25f3624 100644 --- a/materialious/src/lib/player.ts +++ b/materialious/src/lib/player.ts @@ -2,4 +2,9 @@ export interface PlayerEvent { type: "pause" | "seek" | "change-video" | "play"; time?: number; videoId?: string; +} + +export interface PlayerEvents { + events: PlayerEvent[]; + timestamp: Date; } \ No newline at end of file diff --git a/materialious/src/routes/watch/[slug]/+page.svelte b/materialious/src/routes/watch/[slug]/+page.svelte index f6f75043..de1fa760 100644 --- a/materialious/src/routes/watch/[slug]/+page.svelte +++ b/materialious/src/routes/watch/[slug]/+page.svelte @@ -13,7 +13,7 @@ import Player from '$lib/Player.svelte'; import Thumbnail from '$lib/Thumbnail.svelte'; import { cleanNumber, numberWithCommas } from '$lib/misc.js'; - import type { PlayerEvent } from '$lib/player'; + import type { PlayerEvents } from '$lib/player'; import type { DataConnection } from 'peerjs'; import Peer from 'peerjs'; import { onDestroy, onMount } from 'svelte'; @@ -40,54 +40,93 @@ let peer: Peer | null = null; function playerSyncEvents(conn: DataConnection) { - conn.on('data', (data) => { - const events = data as PlayerEvent[]; + let disableEvents = false; - events.forEach((event) => { + conn.on('data', (data) => { + const events = data as PlayerEvents; + + disableEvents = true; + + events.events.forEach((event) => { if (event.type === 'pause') { player.pause(); } else if (event.type === 'play') { player.play(); } else if (event.type === 'seek' && event.time) { - player.currentTime = event.time; + player.currentTime = + event.time + + Math.abs(new Date(events.timestamp).getTime() - new Date().getTime()) / 1000; } }); + + setTimeout(() => { + disableEvents = false; + }, 500); }); player.addEventListener('pause', () => { - conn.send([ - { - type: 'pause' - }, - { - type: 'seek', - time: player.currentTime - } - ] as PlayerEvent[]); + if (disableEvents) return; + + conn.send({ + events: [ + { + type: 'pause' + }, + { + type: 'seek', + time: player.currentTime + } + ], + timestamp: new Date() + } as PlayerEvents); }); player.addEventListener('playing', () => { - conn.send([ - { - type: 'play' - }, - { - type: 'seek', - time: player.currentTime - } - ] as PlayerEvent[]); + if (disableEvents) return; + + conn.send({ + events: [ + { + type: 'seek', + time: player.currentTime + }, + { + type: 'play' + } + ], + timestamp: new Date() + } as PlayerEvents); }); player.addEventListener('waiting', () => { - conn.send([ - { - type: 'pause' - }, - { - type: 'seek', - time: player.currentTime - } - ] as PlayerEvent[]); + if (disableEvents) return; + + conn.send({ + events: [ + { + type: 'pause' + }, + { + type: 'seek', + time: player.currentTime + } + ], + timestamp: new Date() + } as PlayerEvents); + }); + + player.addEventListener('seeked', () => { + if (disableEvents) return; + + conn.send({ + events: [ + { + type: 'seek', + time: player.currentTime + } + ], + timestamp: new Date() + } as PlayerEvents); }); } @@ -198,7 +237,7 @@ {data} {audioMode} {playlistVideos} - isSyncing={!peer} + isSyncing={peer !== null} bind:seekTo bind:currentTime bind:player