Improve video thumbnail loading and display with fallback options

Refactor thumbnail loading logic in VideoCard and VideoPage components to directly display a placeholder on error. Update BunnyService to prioritize custom thumbnail filenames from Bunny.net.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d7424866-83d1-4486-a212-ac12b4c7becf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/d7424866-83d1-4486-a212-ac12b4c7becf/eJ5eRgX
This commit is contained in:
sebastjanartic 2025-08-28 11:49:18 +00:00
parent 67be8e7cc7
commit 886475de42
5 changed files with 24 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -60,17 +60,16 @@ export default function VideoCard({ video, onClick }: VideoCardProps) {
decoding="async"
onError={(e) => {
const target = e.target as HTMLImageElement;
// Try backup thumbnail URL
const backupUrl = `https://iframe.mediadelivery.net/embed/476412/${video.id}/thumbnail.jpg`;
if (!target.src.includes('iframe.mediadelivery.net')) {
target.src = backupUrl;
} else {
// If both fail, show placeholder
target.style.display = 'none';
if (target.parentElement) {
target.parentElement.style.background = 'linear-gradient(45deg, #374151, #4b5563)';
target.parentElement.innerHTML += '<div class="absolute inset-0 flex items-center justify-center text-white text-sm">Video</div>';
}
console.log('Thumbnail failed to load:', target.src);
// Show placeholder immediately instead of trying multiple URLs
target.style.display = 'none';
if (target.parentElement && !target.parentElement.querySelector('.thumbnail-placeholder')) {
target.parentElement.style.background = 'linear-gradient(135deg, #1f2937, #374151)';
const placeholder = document.createElement('div');
placeholder.className = 'thumbnail-placeholder absolute inset-0 flex flex-col items-center justify-center text-white';
placeholder.innerHTML = '<div style="font-size: 28px; margin-bottom: 4px;">🎬</div><div style="font-size: 10px; opacity: 0.7;">Video</div>';
target.parentElement.appendChild(placeholder);
}
}}
/>

View File

@ -244,16 +244,15 @@ export default function VideoPage() {
className="w-full h-full object-cover"
onError={(e) => {
const target = e.target as HTMLImageElement;
// Try backup thumbnail URL
const backupUrl = `https://iframe.mediadelivery.net/embed/476412/${video.id}/thumbnail.jpg`;
if (!target.src.includes('iframe.mediadelivery.net')) {
target.src = backupUrl;
} else {
target.style.display = 'none';
if (target.parentElement) {
target.parentElement.style.background = 'linear-gradient(45deg, #374151, #4b5563)';
target.parentElement.innerHTML += '<div class="absolute inset-0 flex items-center justify-center text-white text-xs">Video</div>';
}
console.log('Sidebar thumbnail failed:', target.src);
target.style.display = 'none';
if (target.parentElement && !target.parentElement.querySelector('.thumbnail-placeholder')) {
target.parentElement.style.background = 'linear-gradient(135deg, #1f2937, #374151)';
const placeholder = document.createElement('div');
placeholder.className = 'thumbnail-placeholder absolute inset-0 flex items-center justify-center text-white text-xs';
placeholder.innerHTML = '<div>🎬</div>';
target.parentElement.appendChild(placeholder);
}
}}
/>

View File

@ -52,9 +52,11 @@ export class BunnyService {
}
private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video {
// Generate multiple thumbnail URL options
const thumbnailUrl = `https://${this.hostname}/${bunnyVideo.guid}/thumbnail.jpg`;
const backupThumbnailUrl = `https://iframe.mediadelivery.net/embed/${this.libraryId}/${bunnyVideo.guid}/thumbnail.jpg`;
// Generate thumbnail URL from Bunny CDN - try multiple formats
// Some videos may have custom thumbnails, others auto-generated
const thumbnailUrl = bunnyVideo.thumbnailFileName
? `https://${this.hostname}/${bunnyVideo.guid}/${bunnyVideo.thumbnailFileName}`
: `https://${this.hostname}/${bunnyVideo.guid}/thumbnail.jpg`;
// Generate signed HLS URL for private video access
const hlsUrl = this.generateSignedUrl(bunnyVideo.guid);