diff --git a/server/routes.ts b/server/routes.ts index 3ddc034..3e37268 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -118,29 +118,64 @@ export async function registerRoutes(app: Express): Promise { } }); - // Public thumbnail endpoint for social media sharing + // Public thumbnail endpoint that generates SVG thumbnails app.get("/thumbnail/:videoId", async (req, res) => { try { const { videoId } = req.params; // Get video info for generating proper thumbnail const video = await storage.getVideo(videoId); + + let title = "Video"; + let duration = "0:00"; + if (video) { - // Clean up title for display - const title = video.title.replace('.mp4', '').substring(0, 45); - - // Generate a high-quality video thumbnail using a more reliable service - // Use a video-themed background with proper social media dimensions - const thumbnailUrl = `https://via.placeholder.com/400x225/1a1a1a/ffffff.png?text=${encodeURIComponent(title)}`; - - res.redirect(thumbnailUrl); - } else { - // Video not found - use generic placeholder - res.redirect(`https://via.placeholder.com/400x225/1a1a1a/ffffff.png?text=Video+Not+Found`); + title = video.title.replace('.mp4', '').substring(0, 35); + const minutes = Math.floor(video.duration / 60); + const seconds = video.duration % 60; + duration = `${minutes}:${seconds.toString().padStart(2, '0')}`; } + + // Generate SVG thumbnail with video title and duration + const svg = ` + + + + + + + + + + + + ${title.split(' ').map((word, i) => `${word}`).join('')} + + + ${duration} + + + `; + + res.setHeader('Content-Type', 'image/svg+xml'); + res.setHeader('Cache-Control', 'public, max-age=86400'); + res.send(svg); + } catch (error) { - console.error("Error serving thumbnail:", error); - res.redirect(`https://via.placeholder.com/400x225/1a1a1a/ffffff.png?text=Error+Loading+Video`); + console.error("Error generating thumbnail:", error); + + // Fallback SVG + const fallbackSvg = ` + + + + + Video Thumbnail + + `; + + res.setHeader('Content-Type', 'image/svg+xml'); + res.send(fallbackSvg); } });