diff --git a/package.json b/package.json index 9e6ab76..bbb7025 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ui", - "version": "6.4.27", + "version": "6.4.28", "license": "BUSL-1.1", "private": true, "packageManager": "pnpm@9.14.4", diff --git a/src/lib/components/ui/player/player.svelte b/src/lib/components/ui/player/player.svelte index c66a978..d59af49 100644 --- a/src/lib/components/ui/player/player.svelte +++ b/src/lib/components/ui/player/player.svelte @@ -791,7 +791,9 @@ {/if} {#if seeking} {#await thumbnailer.getThumbnail(seekIndex) then src} - thumbnail + {#if src} + thumbnail + {/if} {/await} {/if} {#if stats} diff --git a/src/lib/components/ui/player/seekbar.svelte b/src/lib/components/ui/player/seekbar.svelte index e0b5d9b..06d6dcc 100644 --- a/src/lib/components/ui/player/seekbar.svelte +++ b/src/lib/components/ui/player/seekbar.svelte @@ -160,11 +160,18 @@ {/if}
{toTS(seekTime)}
{:then src} - thumbnail - {#if title} -
{title}
+ {#if src} + thumbnail + {#if title} +
{title}
+ {/if} +
{toTS(seekTime)}
+ {:else} + {#if title} +
{title}
+ {/if} +
{toTS(seekTime)}
{/if} -
{toTS(seekTime)}
{/await} diff --git a/src/lib/components/ui/player/thumbnailer.ts b/src/lib/components/ui/player/thumbnailer.ts index 9d13746..bc18ecb 100644 --- a/src/lib/components/ui/player/thumbnailer.ts +++ b/src/lib/components/ui/player/thumbnailer.ts @@ -16,7 +16,7 @@ export default class Thumbnailer { src constructor (src?: string) { - this.video.preload = 'none' + this.video.preload = 'metadata' this.video.playbackRate = 0 this.video.muted = true this.video.crossOrigin = 'anonymous' @@ -38,19 +38,31 @@ export default class Thumbnailer { }, { signal: this.timeUpdateCtrl.signal }) } + _nextTask () { + this.currentTask = undefined + if (this.nextTask) { + this.currentTask = this.nextTask + this.nextTask = undefined + this.currentTask.run() + } + } + _createTask (index: number): RenderItem { const { promise, resolve } = Promise.withResolvers() const run = () => { - this.video.requestVideoFrameCallback(async (_now, meta) => { + const vfc = this.video.requestVideoFrameCallback(async (_now, meta) => { + clearTimeout(timeout) resolve(await this._paintThumbnail(this.video, index, meta.width, meta.height)) - this.currentTask = undefined - if (this.nextTask) { - this.currentTask = this.nextTask - this.nextTask = undefined - this.currentTask.run() - } + this._nextTask() }) + const timeout = setTimeout(() => { + this.video.cancelVideoFrameCallback(vfc) + // this cancels the current load request, in case something bad is happening like long loads or mass seeking + this.video.load() + resolve(undefined) + this._nextTask() + }, 3000) this.video.currentTime = index * this.interval } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index bb275b0..6f4ab2c 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -304,3 +304,7 @@ export const safefetch = async (_fetch: typeof fetch, ...args: Parameters (a: T[], b: T[]) { return a.length === b.length && a.every((v, i) => v === b[i]) } + +export function nextTick () { + return new Promise(resolve => queueMicrotask(resolve)) +}