do not use video in opengraph
deploy / build-and-deploy (push) Successful in 36s

This commit is contained in:
bytedream committed 2026-10-31 04:44:11 +01:00
1 parent 80fde5a94b
commit e5e26222ce
2 files changed
+7 -32

No files matched your search

+3 -12
View File
@@ -12,26 +12,17 @@ if (!video) return new Response(null, { status: 404 });
const metadata = await getVideoMetadata(video);
if (!metadata) return new Response(null, { status: 404 });
const { title, description, width, height, duration } = metadata;
const { title, description } = metadata;
const streamUrl = siteUrl(`video/${encodeURIComponent(video.name)}/stream`);
const thumbnailUrl = siteUrl(`video/${encodeURIComponent(video.name)}/thumbnail.jpg`);
const thumbnailWidth = 1280;
const thumbnailHeight = width && Math.round((height / width) * thumbnailWidth);
---
<WebsiteLayout title={`${title} - Video`} description={description ?? undefined} openGraph="minimal">
<Fragment slot="head">
<meta property="og:type" content="video.other" />
<meta property="og:type" content="website" />
<meta property="og:image" content={thumbnailUrl} />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content={thumbnailWidth.toString()} />
<meta property="og:image:height" content={thumbnailHeight.toString()} />
<meta property="og:video" content={streamUrl} />
{streamUrl.startsWith('https') && <meta property="og:video:secure_url" content={streamUrl} />}
<meta property="og:video:type" content={video.contentType} />
{width && <meta property="og:video:width" content={width.toString()} />}
{height && <meta property="og:video:height" content={height.toString()} />}
{duration && <meta property="og:video:duration" content={duration.toString()} />}
<meta property="og:image:alt" content={title} />
</Fragment>
<section class="mx-auto flex w-full max-w-6xl flex-col gap-5 px-4 py-8 lg:py-12">
+4 -20
View File
@@ -35,22 +35,16 @@ export interface VideoThumbnail {
export interface VideoMetadata {
title: string;
description: string | null;
width: number;
height: number;
duration: number;
}
interface FFprobeStream {
codec_type?: string;
width?: number;
height?: number;
tags?: Record<string, string>;
}
interface FFprobeResult {
streams?: FFprobeStream[];
format?: {
duration?: string;
tags?: Record<string, string>;
};
}
@@ -113,9 +107,8 @@ export async function getVideoMetadata(video: ResolvedVideo): Promise<VideoMetad
'ffprobe',
// prettier-ignore
[
'-v',
'error', '-show_entries',
'format=duration:format_tags=title,description,synopsis:stream=codec_type,width,height:stream_tags=title,description,synopsis',
'-v', 'error',
'-show_entries', 'format_tags=title,description,synopsis:stream=codec_type:stream_tags=title,description,synopsis',
'-of', 'json',
video.path
],
@@ -123,21 +116,12 @@ export async function getVideoMetadata(video: ResolvedVideo): Promise<VideoMetad
);
const parsed = JSON.parse(stdout) as FFprobeResult;
if (!parsed.format) throw new Error('invalid video stream');
const videoStream = parsed.streams?.find((stream) => stream.codec_type === 'video');
if (!videoStream) throw new Error('no video stream');
else if (!videoStream.width || !videoStream.height) throw new Error('invalid video stream height');
const tags = { ...videoStream.tags, ...parsed.format.tags };
const duration = Number(parsed.format.duration);
const tags = { ...videoStream?.tags, ...parsed.format?.tags };
metadata = {
title: tags['title'] || video.name,
description: (tags['synopsis'] || tags['longdescription'] || tags['description']) ?? null,
width: videoStream.width,
height: videoStream.height,
duration: Math.round(duration)
description: (tags['synopsis'] || tags['longdescription'] || tags['description']) ?? null
};
} catch (e) {
logger.warn({ error: e instanceof Error ? e.message : String(e) }, 'error while reading video metadata');