Improvements to sync

This commit is contained in:
WardPearce
2024-04-05 13:35:18 +13:00
parent c2bed95243
commit 58f5ac9896
3 changed files with 74 additions and 45 deletions
+8
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { get } from 'svelte/store';
import { deArrowEnabled, playerSavePlaybackPosition } from '../store';
@@ -8,9 +9,15 @@
export let video: VideoBase | Video | Notification | PlaylistPageVideo;
export let playlistId: string = '';
export let onClick: (input: string) => void = (input: string) => {};
let watchUrl = `/watch/${video.videoId}` + (playlistId ? `?playlist=${playlistId}` : '');
const syncId = $page.url.searchParams.get('sync');
if (syncId) {
watchUrl += (playlistId ? '&' : '?') + `sync=${syncId}`;
}
let loading = true;
let loaded = false;
let failed = false;
@@ -110,6 +117,7 @@
class="wave"
style="width: 100%; overflow: hidden;min-height:100px;"
href={watchUrl}
on:click={() => onClick(video.videoId)}
data-sveltekit-preload-data="off"
>
{#if loading}
-1
View File
@@ -6,5 +6,4 @@ export interface PlayerEvent {
export interface PlayerEvents {
events: PlayerEvent[];
timestamp: Date;
}
@@ -1,4 +1,5 @@
<script lang="ts">
import { goto } from '$app/navigation';
import {
addPlaylistVideo,
deleteUnsubscribe,
@@ -38,52 +39,42 @@
let player: MediaPlayerElement;
let peer: Peer | null = null;
let peerConnection: DataConnection | null = null;
function onVideoChange(videoId: string) {
if (!peerConnection) return;
peerConnection.send({
events: [
{
type: 'change-video',
videoId: videoId
}
]
} as PlayerEvents);
}
function playerSyncEvents(conn: DataConnection) {
let disableEvents = false;
peerConnection = conn;
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 +
Math.abs(new Date(events.timestamp).getTime() - new Date().getTime()) / 1000;
player.currentTime = event.time;
} else if (event.type === 'change-video' && event.videoId) {
currentUrl.pathname = `/watch/${event.videoId}`;
goto(currentUrl);
}
});
setTimeout(() => {
disableEvents = false;
}, 500);
});
player.addEventListener('pause', () => {
if (disableEvents) return;
conn.send({
events: [
{
type: 'pause'
},
{
type: 'seek',
time: player.currentTime
}
],
timestamp: new Date()
} as PlayerEvents);
});
player.addEventListener('playing', () => {
if (disableEvents) return;
player.addEventListener('auto-play', () => {
conn.send({
events: [
{
@@ -93,39 +84,66 @@
{
type: 'play'
}
],
timestamp: new Date()
]
} as PlayerEvents);
});
player.addEventListener('waiting', () => {
if (disableEvents) return;
player.addEventListener('pause', () => {
conn.send({
events: [
{
type: 'pause'
},
}
]
} as PlayerEvents);
});
player.addEventListener('playing', () => {
conn.send({
events: [
{
type: 'seek',
time: player.currentTime
},
{
type: 'play'
}
],
timestamp: new Date()
]
} as PlayerEvents);
});
player.addEventListener('play', () => {
conn.send({
events: [
{
type: 'seek',
time: player.currentTime
},
{
type: 'play'
}
]
} as PlayerEvents);
});
player.addEventListener('waiting', () => {
conn.send({
events: [
{
type: 'pause'
}
]
} as PlayerEvents);
});
player.addEventListener('seeked', () => {
if (disableEvents) return;
conn.send({
events: [
{
type: 'seek',
time: player.currentTime
}
],
timestamp: new Date()
]
} as PlayerEvents);
});
}
@@ -436,7 +454,7 @@
{#each data.video.recommendedVideos as recommendedVideo}
<article class="no-padding">
{#key recommendedVideo.videoId}
<Thumbnail video={recommendedVideo} />
<Thumbnail onClick={onVideoChange} video={recommendedVideo} />
{/key}
</article>
{/each}
@@ -459,7 +477,11 @@
id={playlistVideo.videoId}
class:border={playlistVideo.videoId === data.video.videoId}
>
<Thumbnail video={playlistVideo} playlistId={data.playlistId} />
<Thumbnail
onClick={onVideoChange}
video={playlistVideo}
playlistId={data.playlistId}
/>
</article>
{/each}
</article>