Enhance video metadata for better social sharing and search engine visibility

Implement detailed Open Graph and Twitter Card meta tags, including video duration, release date, and site name. Update structured data for Google search results to include comprehensive video object information. Modify the thumbnail generation process to directly resize the original thumbnail to social media dimensions (1200x630) without applying a branding overlay.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ab9cd02a-d0b2-4288-9ceb-1964d0059648
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/ab9cd02a-d0b2-4288-9ceb-1964d0059648/xVB32z7
This commit is contained in:
sebastjanartic 2025-08-31 21:12:08 +00:00
parent c43057ec77
commit 4297267681
2 changed files with 35 additions and 25 deletions

View File

@ -115,11 +115,40 @@ app.use((req, res, next) => {
`<meta name="twitter:description" content="${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}"`
);
// Dodamo dodatne OG oznake za video (samo tiste, ki jih ni v osnovnem template-u)
// Dodamo dodatne OG oznake za video z detajlnimi informacijami
const duration = Math.floor(video.duration / 60) + ':' + (video.duration % 60).toString().padStart(2, '0');
const additionalMeta = `
<meta property="og:url" content="${videoUrl}">
<meta property="og:type" content="video.other">
<meta property="og:video:duration" content="${video.duration}">`;
<meta property="og:video:duration" content="${video.duration}">
<meta property="og:site_name" content="go4.video">
<meta property="video:duration" content="${video.duration}">
<meta property="video:release_date" content="${video.createdAt?.toISOString()}">
<!-- Dodatni Twitter Card meta podatki -->
<meta name="twitter:player:width" content="1200">
<meta name="twitter:player:height" content="630">
<meta name="twitter:creator" content="@go4video">
<!-- Strukturirani podatki za Google -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "${escapeHtml(video.title)}",
"description": "${escapeHtml(video.description || `Watch ${video.title} on go4.video`)}",
"thumbnailUrl": "${thumbnailUrl}",
"uploadDate": "${video.createdAt?.toISOString()}",
"duration": "PT${Math.floor(video.duration / 60)}M${video.duration % 60}S",
"contentUrl": "${videoUrl}",
"embedUrl": "${videoUrl}",
"publisher": {
"@type": "Organization",
"name": "go4.video",
"url": "${baseUrl}"
}
}
</script>`;
template = template.replace('</head>', `${additionalMeta}\n</head>`);

View File

@ -767,7 +767,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
return res.status(404).send('Video not found');
}
// Najprej poskušamo uporabiti dejanski video thumbnail iz Bunny.net
// Uporabimo čisti thumbnail iz Bunny.net
if (video.thumbnailUrl) {
try {
// Prenesemo dejanski thumbnail iz Bunny.net
@ -775,34 +775,15 @@ export async function registerRoutes(app: Express): Promise<Server> {
if (response.ok) {
const thumbnailBuffer = await response.arrayBuffer();
// Povečamo thumbnail na social media velikost (1200x630) z dodano go4.video branding overlay
const overlayedBuffer = await sharp(Buffer.from(thumbnailBuffer))
// Preprosto povečamo thumbnail na social media velikost (1200x630) brez overlay-a
const resizedBuffer = await sharp(Buffer.from(thumbnailBuffer))
.resize(1200, 630, { fit: 'cover', position: 'center' })
.composite([
// Dodamo temno overlay za boljši kontrast teksta
{
input: Buffer.from(
`<svg width="1200" height="630">
<rect width="1200" height="630" fill="rgba(0,0,0,0.3)"/>
<!-- go4.video branding v spodnjem desnem kotu -->
<rect x="900" y="480" width="280" height="130" rx="15" fill="rgba(0,0,0,0.7)"/>
<text x="1040" y="515" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="white" text-anchor="middle">go4.video</text>
<text x="1040" y="540" font-family="Arial, sans-serif" font-size="14" fill="rgba(255,255,255,0.8)" text-anchor="middle">Professional Video Platform</text>
<!-- Video trajanje -->
<rect x="970" y="555" width="140" height="30" rx="15" fill="rgba(255,255,255,0.9)"/>
<text x="1040" y="575" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="black" text-anchor="middle">${Math.floor(video.duration / 60)}:${(video.duration % 60).toString().padStart(2, '0')}</text>
</svg>`
),
top: 0,
left: 0,
}
])
.png({ quality: 90, compressionLevel: 6 })
.toBuffer();
res.setHeader('Content-Type', 'image/png');
res.setHeader('Cache-Control', 'public, max-age=3600'); // Cache za 1 uro
return res.send(overlayedBuffer);
return res.send(resizedBuffer);
}
} catch (fetchError) {
console.log('Failed to fetch real thumbnail, falling back to generated:', fetchError);