From 56ba81e983e36031449730047357074960343ab2 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Sat, 13 Apr 2024 18:54:17 +1200 Subject: [PATCH 1/5] Added video previews --- materialious/src/lib/Player.svelte | 12 -- materialious/src/lib/Thumbnail.svelte | 147 +++++++++++++----- materialious/src/lib/bookmarklet.ts | 6 + materialious/src/lib/i18n/locales/en.json | 1 + materialious/src/routes/+layout.svelte | 17 ++ .../src/routes/watch/[slug]/+page.svelte | 10 +- materialious/src/store.ts | 1 + 7 files changed, 135 insertions(+), 59 deletions(-) diff --git a/materialious/src/lib/Player.svelte b/materialious/src/lib/Player.svelte index d1faa62f..12f354ce 100644 --- a/materialious/src/lib/Player.svelte +++ b/materialious/src/lib/Player.svelte @@ -21,7 +21,6 @@ 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 player: MediaPlayerElement; export let isSyncing: boolean = false; @@ -38,13 +37,6 @@ const proxyVideos = get(playerProxyVideos); onMount(async () => { - try { - const defaultVolume = localStorage.getItem('volume'); - if (defaultVolume) { - player.volume = Number(defaultVolume); - } - } catch {} - if (!data.video.hlsUrl) { if (data.video.captions) { data.video.captions.forEach(async (caption) => { @@ -81,10 +73,6 @@ }); } - player.addEventListener('time-update', () => { - currentTime = player.currentTime; - }); - player.addEventListener('pause', () => { savePlayerPos(); }); diff --git a/materialious/src/lib/Thumbnail.svelte b/materialious/src/lib/Thumbnail.svelte index 5c97fbca..e5af7ad7 100644 --- a/materialious/src/lib/Thumbnail.svelte +++ b/materialious/src/lib/Thumbnail.svelte @@ -4,18 +4,24 @@ import { get } from 'svelte/store'; import { deArrowEnabled, + interfacePreviewVideoOnHover, + playerProxyVideos, playerSavePlaybackPosition, syncPartyConnections, syncPartyPeer } from '../store'; import { getDeArrow, getThumbnail, getVideo } from './Api'; - import type { Notification, PlaylistPageVideo, Video, VideoBase } from './Api/model'; + import type { Notification, PlaylistPageVideo, Video, VideoBase, VideoPlay } from './Api/model'; import { cleanNumber, proxyVideoUrl, truncate, videoLength } from './misc'; import type { PlayerEvents } from './player'; export let video: VideoBase | Video | Notification | PlaylistPageVideo; export let playlistId: string = ''; + let showVideoPreview: boolean = false; + let videoPreview: VideoPlay | null = null; + let videoPreviewMuted: boolean = true; + let watchUrl = new URL(`${import.meta.env.VITE_DEFAULT_FRONTEND_URL}/watch/${video.videoId}`); if (playlistId !== '') { @@ -30,7 +36,6 @@ let loading = true; let loaded = false; - let failed = false; let img: HTMLImageElement; @@ -118,7 +123,6 @@ }; img.onerror = () => { loading = false; - failed = true; }; }); @@ -139,47 +143,100 @@ }); } } + + async function previewVideo() { + if (!get(interfacePreviewVideoOnHover)) return; + + showVideoPreview = true; + try { + videoPreview = await getVideo(video.videoId, get(playerProxyVideos)); + } catch { + showVideoPreview = true; + } + } - (showVideoPreview = false)} + on:focus={() => {}} + role="region" > - {#if loading} - - {:else if loaded} - Thumbnail for video - {:else} -

{$_('thumbnail.failedToLoadImage')}

- {/if} - {#if progress} - - {/if} - {#if !('liveVideo' in video) || !video.liveVideo} - {#if video.lengthSeconds !== 0} -
-  {videoLength(video.lengthSeconds)}  + + {#if loading} + + {:else if loaded} + {#if showVideoPreview && videoPreview} +
+ +
+ {:else} + Thumbnail for video + {/if} + {:else} +

{$_('thumbnail.failedToLoadImage')}

+ {/if} + {#if progress} + + {/if} + {#if !('liveVideo' in video) || !video.liveVideo} + {#if video.lengthSeconds !== 0} +
+  {videoLength(video.lengthSeconds)}  +
+ {/if} + {:else} +
+ {$_('thumbnail.live')}
{/if} - {:else} -
- {$_('thumbnail.live')} -
+
+ {#if showVideoPreview && videoPreview} + {/if} - +
+
+ +
+ +
diff --git a/materialious/src/routes/watch/[slug]/+page.svelte b/materialious/src/routes/watch/[slug]/+page.svelte index 12b71d63..5c07109d 100644 --- a/materialious/src/routes/watch/[slug]/+page.svelte +++ b/materialious/src/routes/watch/[slug]/+page.svelte @@ -46,7 +46,6 @@ let theatreMode = get(playerTheatreModeByDefault); let audioMode = get(playerListenByDefault); - let currentTime: number; let seekTo: (time: number) => void; let player: MediaPlayerElement; @@ -357,14 +356,7 @@
{#key data.video.videoId} - + {/key}
{data.video.title}
diff --git a/materialious/src/store.ts b/materialious/src/store.ts index 6004937b..cfb8f54f 100644 --- a/materialious/src/store.ts +++ b/materialious/src/store.ts @@ -24,6 +24,7 @@ export const playerAutoplayNextByDefault = persisted('autoplayNextByDefault', fa export const returnYtDislikes = persisted('returnYtDislikes', true); export const interfaceSearchSuggestions = persisted('searchSuggestions', true); +export const interfacePreviewVideoOnHover = persisted('previewVideoOnHover', true); export const auth: Writable = persisted( 'authToken', From c526b70a6c344fda556c4cbd2064d853c041dc68 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Sat, 13 Apr 2024 19:16:05 +1200 Subject: [PATCH 2/5] Minor improvements --- materialious/src/lib/Player.svelte | 31 +++++++++++++++++++-------- materialious/src/lib/Thumbnail.svelte | 19 ++++++++++++---- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/materialious/src/lib/Player.svelte b/materialious/src/lib/Player.svelte index 12f354ce..fb17910b 100644 --- a/materialious/src/lib/Player.svelte +++ b/materialious/src/lib/Player.svelte @@ -27,6 +27,7 @@ let src: PlayerSrc = []; let categoryBeingSkipped = ''; + let playerIsLive = false; export function seekTo(time: number) { if (typeof player !== 'undefined') { @@ -38,6 +39,7 @@ onMount(async () => { if (!data.video.hlsUrl) { + playerIsLive = false; if (data.video.captions) { data.video.captions.forEach(async (caption) => { player.textTracks.add({ @@ -109,6 +111,10 @@ } if (get(playerDash)) { + player.addEventListener('dash-can-play', () => { + loadPlayerPos(); + }); + src = [{ src: data.video.dashUrl + '?local=true', type: 'application/dash+xml' }]; } else { let formattedSrc; @@ -126,17 +132,11 @@ width: Number(quality[0]) }; }); - } - if (get(playerSavePlaybackPosition)) { - try { - const playerPos = localStorage.getItem(`v_${data.video.videoId}`); - if (playerPos) { - player.currentTime = Number(playerPos); - } - } catch {} + loadPlayerPos(); } } else { + playerIsLive = true; src = [ { src: data.video.hlsUrl + '?local=true', @@ -177,7 +177,20 @@ document.documentElement.style.setProperty('--audio-bg', currentTheme['--surface']); }); + function loadPlayerPos() { + if (get(playerSavePlaybackPosition)) { + try { + const playerPos = localStorage.getItem(`v_${data.video.videoId}`); + if (playerPos) { + player.currentTime = Number(playerPos); + } + } catch {} + } + } + function savePlayerPos() { + if (data.video.hlsUrl) return; + try { if (get(playerSavePlaybackPosition) && player.currentTime) { if (player.currentTime < player.duration - 10 && player.currentTime > 10) { @@ -204,7 +217,7 @@ autoPlay={$playerAutoPlay && !isSyncing} loop={$playerAlwaysLoop} title={data.video.title} - streamType={data.video.hlsUrl ? 'live' : 'on-demand'} + streamType={playerIsLive ? 'live' : 'on-demand'} viewType={audioMode ? 'audio' : 'video'} keep-alive {src} diff --git a/materialious/src/lib/Thumbnail.svelte b/materialious/src/lib/Thumbnail.svelte index e5af7ad7..6bb08a03 100644 --- a/materialious/src/lib/Thumbnail.svelte +++ b/materialious/src/lib/Thumbnail.svelte @@ -12,7 +12,7 @@ } from '../store'; import { getDeArrow, getThumbnail, getVideo } from './Api'; import type { Notification, PlaylistPageVideo, Video, VideoBase, VideoPlay } from './Api/model'; - import { cleanNumber, proxyVideoUrl, truncate, videoLength } from './misc'; + import { cleanNumber, proxyVideoUrl, videoLength } from './misc'; import type { PlayerEvents } from './player'; export let video: VideoBase | Video | Notification | PlaylistPageVideo; @@ -150,6 +150,10 @@ showVideoPreview = true; try { videoPreview = await getVideo(video.videoId, get(playerProxyVideos)); + if (videoPreview.hlsUrl) { + showVideoPreview = false; + videoPreview = null; + } } catch { showVideoPreview = true; } @@ -178,11 +182,12 @@ style="max-width: 100%; max-height: 200px;" autoplay poster={img.src} + width="100%" + height="100%" muted={videoPreviewMuted} volume={0.5} src={videoPreview.formatStreams[0].url} > -
{:else} @@ -240,8 +245,14 @@
+ + -
- -
{#each pages as page} {#if !page.requiresAuth || isLoggedIn} @@ -783,4 +789,10 @@ form { margin: 1em 0; } + + @media screen and (max-width: 650px) { + dialog.right { + width: 100%; + } + } From bc42ae8aab4757420c95acdf894f14445bb3810a Mon Sep 17 00:00:00 2001 From: WardPearce Date: Sat, 13 Apr 2024 20:11:26 +1200 Subject: [PATCH 5/5] Fix search focus --- materialious/src/lib/Search.svelte | 83 +++++++++++++++----------- materialious/src/routes/+layout.svelte | 73 ++++++++++++---------- 2 files changed, 89 insertions(+), 67 deletions(-) diff --git a/materialious/src/lib/Search.svelte b/materialious/src/lib/Search.svelte index af23284d..74b8ce6a 100644 --- a/materialious/src/lib/Search.svelte +++ b/materialious/src/lib/Search.svelte @@ -1,9 +1,12 @@