From 0481251559feb5d01c95f2264b315b5bfe32690c Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 5 Sep 2025 23:53:02 +0800 Subject: [PATCH] fix: more reliable video thumbnail generator --- src/lib/store/index.svelte.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/lib/store/index.svelte.ts b/src/lib/store/index.svelte.ts index 52d123a..4d9f697 100644 --- a/src/lib/store/index.svelte.ts +++ b/src/lib/store/index.svelte.ts @@ -50,7 +50,10 @@ class Files { }); const cover = selectCover(common.picture); if (cover) { - const blob = new Blob([cover.data], { + const arrayBuffer = cover.data.buffer instanceof ArrayBuffer + ? cover.data.buffer + : new Uint8Array(cover.data).buffer; + const blob = new Blob([new Uint8Array(arrayBuffer)], { type: cover.format, }); file.blobUrl = URL.createObjectURL(blob); @@ -84,11 +87,19 @@ class Files { : new Image(); mediaElement.src = URL.createObjectURL(file); - await new Promise((resolve) => { + await new Promise((resolve, reject) => { if (isVideo) { - (mediaElement as HTMLVideoElement).onloadeddata = resolve; + const video = mediaElement as HTMLVideoElement; + // seek to 10% of video time or 2 seconds in + video.onloadeddata = () => { + const seekTime = Math.min(video.duration * 0.1, 2); + video.currentTime = seekTime; + }; + video.onseeked = resolve; + video.onerror = reject; } else { (mediaElement as HTMLImageElement).onload = resolve; + (mediaElement as HTMLImageElement).onerror = reject; } }); @@ -103,6 +114,11 @@ class Files { ? (mediaElement as HTMLVideoElement).videoHeight : (mediaElement as HTMLImageElement).height; + if (width === 0 || height === 0) { + URL.revokeObjectURL(mediaElement.src); + return undefined; + } + const scale = Math.max(maxSize / width, maxSize / height); canvas.width = width * scale; canvas.height = height * scale;