Skip to content

feat(spf): Added autoplay support - #1880

Merged
spuppo-mux merged 5 commits into
videojs:mainfrom
spuppo-mux:fix/spf-adapter-autoplay
Jul 30, 2026
Merged

feat(spf): Added autoplay support#1880
spuppo-mux merged 5 commits into
videojs:mainfrom
spuppo-mux:fix/spf-adapter-autoplay

Conversation

@spuppo-mux

@spuppo-mux spuppo-mux commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

autoplay had no effect on the SPF HLS adapter unless preload was also set.

Root cause: the adapter never bridged autoplay to the engine's load activation. With preload unset or none, the engine loads nothing until loadActivated flips true — but loadActivated only flips on a DOM play/seeking event, and nothing plays until data has loaded. Setting preload sidestepped it by loading independently, which is why autoplay only "worked" alongside a preload value.

Part of #1795 (media API extensions on the SPF adapter).

Fix

trackLoadTriggers now treats el.autoplay as an upfront commitment to load, alongside the existing "already playing / mid-seek on entry" checks. When the attached media element has autoplay on entry to monitoring, loadActivated is set to true immediately (no play / seeking listeners attached) rather than waiting for a play event that preload="none" would never let fire.

if (el.autoplay || !el.paused || el.seeking) {
  setLoadActivated();
  return;
}

The browser's autoplay policy (muted-gating, unmuted blocking) is untouched. SPF just gets far enough for the browser to make its own call.

Autoplay is read straight off context.mediaElement, with no state slot and no adapter/engine changes. The element is already the source of truth: <simple-hls-video autoplay> reflects the attribute onto the inner <video> (via CustomMediaElement), and the low-level engine harness sets video.autoplay directly before attach.

Repro

Go to Sandbox on /?platform=html&styling=css&preset=simple-hls-video&skin=default&source=hls-multi-audio&autoplay=1&muted=1&loop=0&preload=none&locale=en (simple-hls muted autoplay, no preload) and validate that before the changes this does not autoplay but after this changes it does.

Example: On another branch, this does not autoplay even though autoplay is on https://v10-sandbox-git-fork-spuppo-mux-feat-spf-adapter-med-3b75be-mux.vercel.app/?platform=html&styling=css&preset=simple-hls-video&skin=default&source=hls-multi-audio&autoplay=1&muted=1&loop=0&preload=none&locale=en

Go to the same path on this deployment and it should work.
https://v10-sandbox-kvd3wy019-mux.vercel.app/?platform=html&styling=css&preset=simple-hls-video&skin=default&source=hls-multi-audio&autoplay=1&muted=1&loop=0&preload=none&locale=en

Same for https://v10-sandbox-kvd3wy019-mux.vercel.app/spf-segment-loading/?muted=true&autoplay=true&preload=none

Some other cases:

  • autoplay + muted -> autoplay starts normally
  • autoplay + not muted -> autoplay doesn't start (unless hot reloading the page and you had already interacted with video); however will fetch 5 segments for both cases
  • no autoplay -> wont start, respects preload (except for the found bug in adapter, see Notes)

Testing

  • trackLoadTriggers: new case asserting autoplay on entry sets loadActivated=true and attaches no play/seeking listeners; autoplay added to the fake-video helper.
  • pnpm typecheck and pnpm -F @videojs/spf test (1044 passing) — green; Biome clean on changed files.

Notes

  • While testing noticed there is a bug with the sync-preload behavior and our Sandbox example. Essentially even if preload is set to none, it will always start as metadata. This is because sync-preload expects to read the preload attribute from the video element which never is never reached by our example. We should change either the behavior or the adapter.
  • Autoplay read off the element with no backing signal → reactivity scoped to element identity (toggling autoplay on the same attached element post-monitoring isn't picked up; fine for autoplay semantics).
  • No adapter/engine/sync-preload changes — earlier engine-slot and preload-folding iterations were reverted.

Note

Medium Risk
Changes when segment loading starts via loadActivated, which gates HLS load behavior, but the scope is narrow and covered by new unit tests.

Overview
trackLoadTriggers now treats el.autoplay like an upfront commitment to load, not only play / seeking or an already-playing element. When the attached media element has autoplay on entry, loadActivated is set to true immediately and play / seeking listeners are not attached, so preload="none" no longer blocks loading while waiting for a play event that never comes.

Tests add autoplay to the fake video helper and assert the new on-entry activation path and that listeners stay detached.

Reviewed by Cursor Bugbot for commit 87df1aa. Bugbot is set up for automated code reviews on this repo. Configure here.

@spuppo-mux
spuppo-mux requested a review from cjpillsbury July 28, 2026 16:41
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

@spuppo-mux is attempting to deploy a commit to the Mux Team on Vercel.

A member of the Team first needs to authorize it.

@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 87df1aa
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a6a794dc11a3a0008ae769d
😎 Deploy Preview https://deploy-preview-1880--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview Jul 29, 2026 10:28pm

Request Review

Comment thread packages/spf/src/playback/engines/hls/adapter.ts Outdated

@cjpillsbury cjpillsbury left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Ship it.

Comment thread packages/spf/src/playback/behaviors/dom/track-load-triggers.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5f7ccb1. Configure here.

Comment thread packages/spf/src/playback/behaviors/sync-preload.ts Outdated
Comment thread packages/spf/src/playback/behaviors/sync-preload.ts Outdated

@cjpillsbury cjpillsbury left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm down. We may want to revisit this, but this also may be good enough for now (and maybe even the "right" solution overall).

@spuppo-mux
spuppo-mux merged commit b16f28f into videojs:main Jul 30, 2026
26 of 27 checks passed
@luwes luwes mentioned this pull request Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants