Merge pull request #91 from WardPearce/update/sync-party-playlist

Update/sync party playlist
This commit is contained in:
Ward
2024-04-11 13:03:02 +12:00
committed by GitHub
4 changed files with 94 additions and 44 deletions
+1 -18
View File
@@ -1,7 +1,6 @@
<script lang="ts">
import 'vidstack/bundle';
import { goto } from '$app/navigation';
import { SponsorBlock, type Category } from 'sponsorblock-api';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
@@ -17,14 +16,13 @@
sponsorBlockCategories,
sponsorBlockUrl
} from '../store';
import type { PlaylistPageVideo, VideoPlay } from './Api/model';
import type { VideoPlay } from './Api/model';
import { proxyVideoUrl, videoLength, type PhasedDescription } from './misc';
import { getDynamicTheme } from './theme';
export let data: { video: VideoPlay; content: PhasedDescription; playlistId: string | null };
export let currentTime: number = 0;
export let audioMode = false;
export let playlistVideos: PlaylistPageVideo[] | null = null;
export let player: MediaPlayerElement;
export let isSyncing: boolean = false;
@@ -47,21 +45,6 @@
}
} catch {}
if (playlistVideos) {
player.addEventListener('end', () => {
if (!playlistVideos) return;
const playlistVideoIds = playlistVideos.map((value) => {
return value.videoId;
});
const currentVideoIndex = playlistVideoIds.indexOf(data.video.videoId);
const newIndex = currentVideoIndex + 1;
if (currentVideoIndex !== -1 && newIndex <= playlistVideoIds.length) {
goto(`/watch/${playlistVideos[newIndex].videoId}?playlist=${data.playlistId}`);
}
});
}
if (!data.video.hlsUrl) {
if (data.video.captions) {
data.video.captions.forEach(async (caption) => {
+11 -3
View File
@@ -120,10 +120,18 @@
function syncChangeVideo() {
if ($syncPartyConnections) {
const events = {
events: [{ type: 'change-video', videoId: video.videoId }]
} as PlayerEvents;
if (playlistId) {
events.events.unshift({
type: 'playlist',
playlistId: playlistId
});
}
$syncPartyConnections.forEach((conn) => {
conn.send({
events: [{ type: 'change-video', videoId: video.videoId }]
} as PlayerEvents);
conn.send(events);
});
}
}
+2 -1
View File
@@ -1,7 +1,8 @@
export interface PlayerEvent {
type: "pause" | "seek" | "change-video" | "play";
type: "pause" | "seek" | "change-video" | "play" | "playlist";
time?: number;
videoId?: string;
playlistId?: string;
}
export interface PlayerEvents {
@@ -47,16 +47,29 @@
let player: MediaPlayerElement;
function playerSyncEvents(conn: DataConnection) {
conn.send({
events: [{ type: 'seek', time: player.currentTime }]
} as PlayerEvents);
if (player) {
conn.send({
events: [{ type: 'seek', time: player.currentTime }]
} as PlayerEvents);
}
conn.on('data', (data) => {
const events = data as PlayerEvents;
if (data.playlistId) {
conn.send({
events: [
{
type: 'playlist',
playlistId: data.playlistId
}
]
} as PlayerEvents);
}
if (!player) return;
conn.on('data', (rawData) => {
const events = rawData as PlayerEvents;
events.events.forEach(async (event) => {
if (!player) return;
events.events.forEach((event) => {
if (event.type === 'pause') {
player.pause();
} else if (event.type === 'play') {
@@ -67,10 +80,20 @@
if (timeDiff > 3 || timeDiff < -3) {
player.currentTime = event.time;
}
} else if (
event.type === 'playlist' &&
event.playlistId &&
event.playlistId !== data.playlistId
) {
data.playlistId = event.playlistId;
await loadPlaylist(event.playlistId);
goToCurrentPlaylistItem();
}
});
});
if (!player) return;
player.addEventListener('auto-play-fail', () => {
conn.send({
events: [
@@ -82,6 +105,7 @@
});
player.addEventListener('auto-play', () => {
if (!player) return;
conn.send({
events: [
{
@@ -106,6 +130,7 @@
});
player.addEventListener('playing', () => {
if (!player) return;
conn.send({
events: [
{
@@ -120,6 +145,7 @@
});
player.addEventListener('play', () => {
if (!player) return;
conn.send({
events: [
{
@@ -144,6 +170,7 @@
});
player.addEventListener('seeked', () => {
if (!player) return;
conn.send({
events: [
{
@@ -167,20 +194,54 @@
});
}
player.addEventListener('end', () => {
if ($playerAutoplayNextByDefault && !playlist) {
goto(`/watch/${data.video.recommendedVideos[0].videoId}`);
}
if (player) {
player.addEventListener('end', () => {
if ($playerAutoplayNextByDefault && !playlist) {
goto(`/watch/${data.video.recommendedVideos[0].videoId}`);
}
if (data.playlistId) {
setTimeout(goToCurrentPlaylistItem, 1000);
}
});
if (data.playlistId) {
goToCurrentPlaylistItem();
}
});
}
if (!data.playlistId) return;
await loadPlaylist(data.playlistId);
goToCurrentPlaylistItem();
if (playlistVideos && player) {
player.addEventListener('end', () => {
if (!playlistVideos) return;
const playlistVideoIds = playlistVideos.map((value) => {
return value.videoId;
});
const currentVideoIndex = playlistVideoIds.indexOf(data.video.videoId);
const newIndex = currentVideoIndex + 1;
if (currentVideoIndex !== -1 && newIndex <= playlistVideoIds.length) {
if ($syncPartyConnections) {
$syncPartyConnections.forEach((conn) => {
conn.send({
events: [
{ type: 'change-video', videoId: playlistVideos[newIndex].videoId },
{ type: 'playlist', playlistId: data.playlistId }
]
} as PlayerEvents);
});
}
goto(`/watch/${playlistVideos[newIndex].videoId}?playlist=${data.playlistId}`);
}
});
}
});
async function loadPlaylist(playlistId: string) {
for (let page = 1; page < Infinity; page++) {
const newPlaylist = await getPlaylist(data.playlistId, page);
const newPlaylist = await getPlaylist(playlistId, page);
if (page === 1) {
playlist = newPlaylist;
}
@@ -194,9 +255,7 @@
}
);
}
goToCurrentPlaylistItem();
});
}
function goToCurrentPlaylistItem() {
const playlistCurrentVideo = document.getElementById(data.video.videoId);
@@ -250,7 +309,6 @@
<Player
{data}
{audioMode}
{playlistVideos}
isSyncing={$syncPartyPeer !== null}
bind:seekTo
bind:currentTime
@@ -448,7 +506,7 @@
</div>
{#if !theatreMode}
<div class="s12 m12 l2">
{#if !data.playlistId}
{#if !playlist}
{#if data.video.recommendedVideos}
{#each data.video.recommendedVideos as recommendedVideo}
<article class="no-padding">
@@ -458,7 +516,7 @@
</article>
{/each}
{/if}
{:else if playlist}
{:else}
<article
style="height: 75vh; position: relative;"
id="playlist"