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:
parent
c43057ec77
commit
4297267681
@ -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>`);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user