Skip to content

Commit e188d6c

Browse files
committed
Fall back to first video frame when thumbnail is missing or fails to load
1 parent 27c7128 commit e188d6c

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

src/lib/components/download/DownloadCard.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,13 @@
313313
alt={download.title || 'Thumbnail'}
314314
onerror={() => thumbnailFailed = true}
315315
/>
316+
{:else if isPreviewable && !showPreview}
317+
<video
318+
class="thumbnail-img"
319+
src="/api/files/{download.id}#t=0.001"
320+
preload="metadata"
321+
muted
322+
></video>
316323
{/if}
317324
{#if !showPreview && download.status === 'COMPLETED'}
318325
<div class="play-overlay">

src/lib/components/download/DownloadListRow.svelte

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
let statusLabel = $derived(getDownloadStatusLabel(download.status));
1919
let thumbnailFailed = $state(false);
2020
21+
const VIDEO_EXTENSIONS = new Set(['MP4', 'WEBM', 'MKV', 'FLV', 'MOV', 'AVI']);
22+
let mediaType = $derived(download.filename?.split('.').pop()?.toUpperCase() || null);
23+
let isVideoCompleted = $derived(
24+
download.status === 'COMPLETED' && mediaType !== null && VIDEO_EXTENSIONS.has(mediaType)
25+
);
26+
2127
let formattedSize = $derived(download.filesize ? formatBytes(download.filesize) : null);
2228
let formattedDuration = $derived(download.duration ? formatDuration(download.duration) : null);
2329
@@ -44,6 +50,12 @@
4450
alt={download.title || 'Thumbnail'}
4551
onerror={() => (thumbnailFailed = true)}
4652
/>
53+
{:else if isVideoCompleted}
54+
<video
55+
src="/api/files/{download.id}#t=0.001"
56+
preload="metadata"
57+
muted
58+
></video>
4759
{:else}
4860
<div class="thumbnail-placeholder"></div>
4961
{/if}
@@ -106,7 +118,8 @@
106118
background: var(--color-bg-tertiary);
107119
}
108120
109-
.thumbnail img {
121+
.thumbnail img,
122+
.thumbnail video {
110123
width: 100%;
111124
height: 100%;
112125
object-fit: cover;

0 commit comments

Comments
 (0)