Give a video its shape before it has any data
CI / Typecheck, test, build (pull_request) Successful in 26s
CI / Typecheck, test, build (pull_request) Successful in 26s
A Reddit video sat in the wrong box until you pressed play, for two reasons that looked like one. The renderer put only `aspect-ratio` on the `<video>`. A video with no data has a natural size of 300x150, and WebKit sizes a replaced element from that rather than from the ratio, so a portrait video got a squat landscape box and kept it until playback supplied real dimensions. Chromium stretch-fits instead and gets it right, which is why this only showed on Safari. A video's size before its data arrives is its poster's, so one with no poster of its own now gets an empty SVG of the right shape as a stand-in: a data URI, so it costs no request. Measured in both engines across portrait, landscape, square and small. And Reddit's videos with sound had no poster to be sized by, because `fromRedditVideo` attached the still from `preview.images` to the MP4 branch alone. The still belongs to the video, not to the format it is served in, so every post with sound showed an empty box where a silent one showed a frame. It now goes on both. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PLkmgp1fWbA4XbarxKdRKt
This commit is contained in:
@@ -96,6 +96,10 @@ Things worth knowing before editing:
|
||||
`src/media/registry.ts` and served from `/m/<id>` with the `Referer`/`Cookie` the CDN
|
||||
demands. `Range` is forwarded — without it the native video scrubber cannot seek.
|
||||
The exception is HLS (`direct: true`), because proxying would mean rewriting playlists.
|
||||
- **A video is sized by its poster**, not by the ratio the renderer puts on it. A
|
||||
`<video>` with no data has a natural size of 300x150, and WebKit sizes it from that —
|
||||
so one with no poster of its own gets an empty SVG of the right shape as a stand-in,
|
||||
without which a portrait video sits in a squat landscape box until you press play.
|
||||
- **Never a bare error page.** A failed resolve renders a card carrying the platform, the
|
||||
original URL and the copy button. A broken adapter must still leave the link one tap
|
||||
away.
|
||||
@@ -144,8 +148,10 @@ Things worth knowing before editing:
|
||||
Video: `fallback_url` is the *video track alone* whenever `has_audio` is true, so a
|
||||
post with sound has to use `hls_url`, direct and unproxied; a silent one gets the
|
||||
proxied MP4. `scrubber_media_url` is not a poster — it is a second MP4 for the
|
||||
timeline thumbnails, and the still is in `preview.images`. A gallery's pictures are in
|
||||
`media_metadata`, keyed and unordered; their order is only in `gallery_data`. Comment
|
||||
timeline thumbnails, and the still is in `preview.images` — which belongs to both
|
||||
forms: the HLS one used to go without, and showed an empty box where a silent post
|
||||
showed a frame. A gallery's pictures are in `media_metadata`, keyed and unordered;
|
||||
their order is only in `gallery_data`. Comment
|
||||
bodies are Markdown, rendered by `src/render/markdown.ts` — escape first, then put
|
||||
back the constructs we chose to support, never `body_html`. An image in a comment is
|
||||
written as a token rather than an address — ``,
|
||||
|
||||
Reference in New Issue
Block a user