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