mirror of
https://github.com/zoriya/v10.git
synced 2026-08-13 09:30:38 +00:00
feat(spf): Added autoplay support (#1880)
This commit is contained in:
@@ -21,9 +21,18 @@ function setupTrackLoadTriggers(initialState: LoadTriggersState = {}, initialCon
|
||||
return { state, context, reactor };
|
||||
}
|
||||
|
||||
/** Creates a video element with controllable `paused` and `seeking` state. */
|
||||
function makeMediaElement({ paused = true, seeking = false }: { paused?: boolean; seeking?: boolean } = {}) {
|
||||
/** Creates a video element with controllable `paused`, `seeking`, and `autoplay` state. */
|
||||
function makeMediaElement({
|
||||
paused = true,
|
||||
seeking = false,
|
||||
autoplay = false,
|
||||
}: {
|
||||
paused?: boolean;
|
||||
seeking?: boolean;
|
||||
autoplay?: boolean;
|
||||
} = {}) {
|
||||
const el = document.createElement('video');
|
||||
el.autoplay = autoplay;
|
||||
let pausedFlag = paused;
|
||||
let seekingFlag = seeking;
|
||||
Object.defineProperty(el, 'paused', { get: () => pausedFlag, configurable: true });
|
||||
@@ -104,6 +113,24 @@ describe('trackLoadTriggers', () => {
|
||||
reactor.destroy();
|
||||
});
|
||||
|
||||
it('sets loadActivated to true immediately if element has autoplay on entry', async () => {
|
||||
const { el } = makeMediaElement({ autoplay: true });
|
||||
const addEventListenerSpy = vi.spyOn(el, 'addEventListener');
|
||||
const { state, reactor } = setupTrackLoadTriggers(
|
||||
{ presentation: { url: 'http://example.com/stream.m3u8' } },
|
||||
{ mediaElement: el }
|
||||
);
|
||||
|
||||
await flush();
|
||||
|
||||
// Autoplay commits to loading up front (it can't wait for a `play` event
|
||||
// that preload='none' would never let fire), so it activates on entry and
|
||||
// never attaches play/seeking listeners.
|
||||
expect(state.loadActivated.get()).toBe(true);
|
||||
expect(addEventListenerSpy.mock.calls.some(([type]) => type === 'play' || type === 'seeking')).toBe(false);
|
||||
reactor.destroy();
|
||||
});
|
||||
|
||||
it('preserves pre-existing true write (adapter wrote before setup)', async () => {
|
||||
const { el } = makeMediaElement();
|
||||
const addEventListenerSpy = vi.spyOn(el, 'addEventListener');
|
||||
|
||||
@@ -66,9 +66,9 @@ function deriveState(
|
||||
*
|
||||
* Writes `state.loadActivated = true` the first time a `play` or `seeking`
|
||||
* event fires on the attached media element for the current source — or
|
||||
* immediately on entry if the element is already in such a state
|
||||
* (`!el.paused` or `el.seeking`), mirroring autoplay / native-controls /
|
||||
* direct-DOM-`play()` scenarios.
|
||||
* immediately on entry if the element is already committed to loading
|
||||
* (`el.autoplay`, `!el.paused`, or `el.seeking`), covering autoplay,
|
||||
* native-controls, and direct-DOM-`play()` scenarios.
|
||||
*
|
||||
* Sticky-true *within a source identity*: subsequent play/pause/seek
|
||||
* cycles don't flip back. Source identity = (mediaElement, presentation
|
||||
@@ -125,7 +125,7 @@ function trackLoadTriggersSetup({
|
||||
const el = context.mediaElement.get()!;
|
||||
|
||||
const setLoadActivated = () => state.loadActivated.set(true);
|
||||
if (!el.paused || el.seeking) {
|
||||
if (el.autoplay || !el.paused || el.seeking) {
|
||||
setLoadActivated();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user