Skip to content

Commit 0b4f540

Browse files
committed
perf(media): reduce first-frame startup data
1 parent 77bf2cc commit 0b4f540

3 files changed

Lines changed: 51 additions & 2 deletions

File tree

apps/site/app/embed-fast/[assetId]/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,11 @@ export function renderFastEmbedHtml(options: FastEmbedRenderOptions) {
860860
const contentType = selection?.contentType
861861
? ` type="${html(selection.contentType)}"`
862862
: "";
863-
const preload = inlineStartup ? null : preloadablePlaybackSelection(selection);
863+
const videoPreload = options.autoPlay ? "auto" : "metadata";
864+
const preload =
865+
options.autoPlay && !inlineStartup
866+
? preloadablePlaybackSelection(selection)
867+
: null;
864868
const preloadContentType = preload?.contentType ?? "video/mp4";
865869
const crossOrigin = playbackCrossOrigin(options.bootstrap);
866870
const crossOriginAttribute = crossOrigin
@@ -925,7 +929,7 @@ body{overflow:hidden}
925929
</head>
926930
<body>
927931
<main class="rend-fast" aria-label="Video player" data-rend-player-state="${html(state)}" data-rend-player-selected="${html(selectedLabel)}" data-rend-player-artifact="${html(selectedArtifact)}" data-rend-ready-status="${html(ready?.status ?? options.bootstrap?.status ?? state)}" data-rend-source-state="${html(ready?.source_state ?? "")}" data-rend-playable-state="${html(ready?.playable_state ?? "")}" data-rend-manifest-content-type="${html(ready?.manifest_content_type ?? "")}" data-rend-opener-content-type="${html(ready?.opener_content_type ?? "")}" data-rend-poster="${html(ready?.poster_url ?? "")}" data-rend-prefetch-hint-count="${html(ready?.prefetch_hints.length ?? 0)}" data-rend-playback-engine="${html(playbackEngine)}" data-rend-document-start-ms="0"${bootstrapMs}${bootstrapHttpStatus} data-rend-asset-id="${html(options.assetId)}" data-rend-organization-id="${html(ready?.organization_id ?? "")}" data-rend-autoplay="${options.autoPlay ? "true" : "false"}" data-rend-muted="${options.muted ? "true" : "false"}" data-rend-startup-mode="${html(options.startupMode)}">
928-
<video class="rend-fast__video"${source}${contentType}${poster}${autoPlay}${controls}${muted} playsinline preload="auto"${crossOriginAttribute}></video>
932+
<video class="rend-fast__video"${source}${contentType}${poster}${autoPlay}${controls}${muted} playsinline preload="${videoPreload}"${crossOriginAttribute}></video>
929933
<div class="rend-fast__message" role="status" aria-live="polite">${html(message)}</div>
930934
</main>
931935
<script>

apps/site/app/embed-fast/route.test.mts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ test("fast embed falls back to the real opener when inline startup is unavailabl
103103
assert.doesNotMatch(html, /playback_token|set-cookie|authorization/i);
104104
});
105105

106+
test("paused fast embeds avoid eagerly downloading the full opener", () => {
107+
const html = renderFastEmbedHtml({
108+
assetId: ASSET_ID,
109+
autoPlay: false,
110+
bootstrap: readyBootstrap(),
111+
bootstrapUrl: `/api/player/${ASSET_ID}`,
112+
bootstrapMs: 42,
113+
controls: true,
114+
muted: false,
115+
playbackOriginHint: null,
116+
startupMode: "progressive",
117+
});
118+
119+
assert.match(html, /<video[^>]+preload="metadata"/);
120+
assert.doesNotMatch(html, /<link rel="preload" as="video"/);
121+
});
122+
106123
test("fast embed uses the real opener for anonymous public playback", () => {
107124
const base = readyBootstrap();
108125
if (base.status !== "ready") throw new Error("expected ready bootstrap");

services/rend-api/src/media.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ async fn generate_and_upload_opener(
686686
fn opener_ffmpeg_args(source_path: &Path, source_probe: &SourceProbe) -> Vec<OsString> {
687687
let copy_video = source_probe.video_codec.as_deref() == Some("h264")
688688
&& source_probe.width.max(source_probe.height) <= OPENER_MAX_DIMENSION;
689+
let keyframe_interval = hls_keyframe_interval_frames(source_probe).to_string();
689690
let mut args = vec![
690691
os("-y"),
691692
os("-i"),
@@ -712,6 +713,17 @@ fn opener_ffmpeg_args(source_path: &Path, source_probe: &SourceProbe) -> Vec<OsS
712713
os(OPENER_VIDEO_CRF),
713714
os("-pix_fmt"),
714715
os("yuv420p"),
716+
os("-g"),
717+
os(&keyframe_interval),
718+
os("-keyint_min"),
719+
os(&keyframe_interval),
720+
os("-sc_threshold"),
721+
os("0"),
722+
os("-force_key_frames"),
723+
os(&format!(
724+
"expr:gte(t,n_forced*{})",
725+
HLS_TARGET_SEGMENT_SECONDS
726+
)),
715727
]);
716728
}
717729
if source_probe.has_audio {
@@ -724,6 +736,8 @@ fn opener_ffmpeg_args(source_path: &Path, source_probe: &SourceProbe) -> Vec<OsS
724736
args.extend([
725737
os("-movflags"),
726738
os("+frag_keyframe+empty_moov+default_base_moof"),
739+
os("-frag_duration"),
740+
os("1000000"),
727741
os("-f"),
728742
os("mp4"),
729743
os("pipe:1"),
@@ -3004,6 +3018,16 @@ mod tests {
30043018
assert!(args.windows(2).any(|pair| pair == ["-b:a", "96k"]));
30053019
assert!(args.iter().any(|value| value.contains("min(640,iw)")));
30063020
assert!(args.iter().any(|value| value.contains("min(640,ih)")));
3021+
assert!(args.windows(2).any(|pair| pair == ["-g", "30"]));
3022+
assert!(args.windows(2).any(|pair| pair == ["-keyint_min", "30"]));
3023+
assert!(
3024+
args.windows(2)
3025+
.any(|pair| pair == ["-force_key_frames", "expr:gte(t,n_forced*1)"])
3026+
);
3027+
assert!(
3028+
args.windows(2)
3029+
.any(|pair| pair == ["-frag_duration", "1000000"])
3030+
);
30073031
assert!(
30083032
args.iter()
30093033
.any(|value| value == "+frag_keyframe+empty_moov+default_base_moof")
@@ -3031,6 +3055,10 @@ mod tests {
30313055
assert!(args.windows(2).any(|pair| pair == ["-c:v", "copy"]));
30323056
assert!(args.windows(2).any(|pair| pair == ["-c:a", "copy"]));
30333057
assert!(!args.iter().any(|value| value == "-vf"));
3058+
assert!(
3059+
args.windows(2)
3060+
.any(|pair| pair == ["-frag_duration", "1000000"])
3061+
);
30343062
}
30353063

30363064
#[test]

0 commit comments

Comments
 (0)