Clips unfurl: share cards, faststart video, a share button
Each clip page already carried its own title, blurb, poster and og:video — but the assets behind the tags let the unfurl down. The mp4s were tail-indexed, so previewers in iMessage, Discord, Slack and Facebook gave up before finding a player; the tags carried no video dimensions, without which those same sites refuse to embed one; and the poster was a 736x578 screenshot of the workshop chrome, cropped to nothing by any share sheet. deploy/clips-prep.mjs fixes the set before clips-publish.sh ships it: a lossless faststart remux of every take, a 1200x630 card per clip cut from the poster's first-person viewport with the title set over it (an HTML card screenshot through the harness's chromium — ffmpeg here has no drawtext), and the fpv frame size stamped into clips.json. The page emits the card with its dimensions, og:video:width/height, and a Share button that opens the phone's share sheet or copies the link. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
bea8a2e1e1
commit
8488e9a8d1
@@ -227,6 +227,10 @@ export interface ClipMeta {
|
||||
title: string;
|
||||
blurb: string;
|
||||
seconds: number;
|
||||
/** Frame size of the first-person take, stamped by deploy/clips-prep.mjs;
|
||||
* unfurlers won't embed a player without it. Absent on an unprepped set. */
|
||||
width?: number;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
const clipsDir = () => join(DATA_DIR, "..", "clips");
|
||||
@@ -244,9 +248,9 @@ export function readClips(): ClipMeta[] {
|
||||
|
||||
/** Resolve a clip asset request to its path — or null for any name that
|
||||
* is not exactly a published clip file shape. The gate IS the security:
|
||||
* nothing outside <slug>(-fpv|-board).mp4 / <slug>.jpg can be named. */
|
||||
* nothing outside <slug>(-fpv|-board).mp4 / <slug>(-card)?.jpg can be named. */
|
||||
export function clipAssetPath(file: string): string | null {
|
||||
if (!/^[a-z0-9-]{1,60}(-fpv|-board)\.mp4$/.test(file) && !/^[a-z0-9-]{1,60}\.jpg$/.test(file)) {
|
||||
if (!/^[a-z0-9-]{1,60}(-fpv|-board)\.mp4$/.test(file) && !/^[a-z0-9-]{1,60}(-card)?\.jpg$/.test(file)) {
|
||||
return null;
|
||||
}
|
||||
const path = join(clipsDir(), file);
|
||||
|
||||
Reference in New Issue
Block a user