diff --git a/server/bunny.ts b/server/bunny.ts index d01406b..93ab345 100644 --- a/server/bunny.ts +++ b/server/bunny.ts @@ -52,9 +52,8 @@ export class BunnyService { } private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video { - // For private videos, use iframe embed or proxy approach - // Generate thumbnail URL from CDN (thumbnails are usually public) - const thumbnailUrl = `https://${this.hostname}/${bunnyVideo.guid}/thumbnail.jpg`; + // Use server-side proxy for thumbnails since they are private + const thumbnailUrl = `/thumbnail/${bunnyVideo.guid}`; // For private videos, we'll use an iframe embed URL which handles authentication const videoUrl = `https://iframe.mediadelivery.net/embed/${this.libraryId}/${bunnyVideo.guid}`; diff --git a/server/routes.ts b/server/routes.ts index ff022c8..94cc468 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -47,6 +47,44 @@ export async function registerRoutes(app: Express): Promise { } }); + // Proxy endpoint for thumbnails (since they are private) + app.get("/thumbnail/:id", async (req, res) => { + try { + const { id } = req.params; + const apiKey = process.env.BUNNY_API_KEY; + const libraryId = process.env.BUNNY_LIBRARY_ID; + + if (!apiKey || !libraryId) { + return res.status(500).json({ message: "Bunny.net configuration missing" }); + } + + // Try to get thumbnail from Bunny API + const thumbnailUrl = `https://video.bunnycdn.com/library/${libraryId}/videos/${id}/thumbnail`; + + const response = await fetch(thumbnailUrl, { + method: 'POST', + headers: { + 'AccessKey': apiKey, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ time: 10 }) // Get thumbnail at 10 seconds + }); + + if (response.ok) { + const thumbnailData = await response.arrayBuffer(); + res.set('Content-Type', 'image/jpeg'); + res.set('Cache-Control', 'public, max-age=3600'); // Cache for 1 hour + res.send(Buffer.from(thumbnailData)); + } else { + // If thumbnail generation fails, return a placeholder + res.redirect('https://via.placeholder.com/480x270/1a1a1a/ffffff?text=Video'); + } + } catch (error) { + console.error('Error proxying thumbnail:', error); + res.redirect('https://via.placeholder.com/480x270/1a1a1a/ffffff?text=Video'); + } + }); + const httpServer = createServer(app);