Display video previews correctly for videos with restricted access
Implements a thumbnail proxy to fetch private BunnyCDN video thumbnails. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aa92e7e2-ec62-4c92-b21b-02ef78a664c2 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/aa92e7e2-ec62-4c92-b21b-02ef78a664c2/PiJtjmP
This commit is contained in:
parent
645fa51028
commit
0458b42937
@ -52,9 +52,8 @@ export class BunnyService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video {
|
private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video {
|
||||||
// For private videos, use iframe embed or proxy approach
|
// Use server-side proxy for thumbnails since they are private
|
||||||
// Generate thumbnail URL from CDN (thumbnails are usually public)
|
const thumbnailUrl = `/thumbnail/${bunnyVideo.guid}`;
|
||||||
const thumbnailUrl = `https://${this.hostname}/${bunnyVideo.guid}/thumbnail.jpg`;
|
|
||||||
|
|
||||||
// For private videos, we'll use an iframe embed URL which handles authentication
|
// For private videos, we'll use an iframe embed URL which handles authentication
|
||||||
const videoUrl = `https://iframe.mediadelivery.net/embed/${this.libraryId}/${bunnyVideo.guid}`;
|
const videoUrl = `https://iframe.mediadelivery.net/embed/${this.libraryId}/${bunnyVideo.guid}`;
|
||||||
|
|||||||
@ -47,6 +47,44 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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);
|
const httpServer = createServer(app);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user