Skip to content

Commit

Permalink
fix(player): do not load hls src on dom connect
Browse files Browse the repository at this point in the history
  • Loading branch information
mihar-22 committed Oct 16, 2023
1 parent d2f4c84 commit 92fa791
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
35 changes: 29 additions & 6 deletions packages/vidstack/src/core/state/media-state-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import debounce from 'just-debounce-it';
import throttle from 'just-throttle';
import { appendTriggerEvent, listenEvent } from 'maverick.js/std';
import { onDispose } from 'maverick.js';
import { appendTriggerEvent, DOMEvent, listenEvent } from 'maverick.js/std';

import { ListSymbol } from '../../foundation/list/symbols';
import type { MediaContext } from '../api/media-context';
Expand Down Expand Up @@ -53,11 +54,8 @@ export class MediaStateManager extends MediaPlayerController {
this._addAudioTrackListeners();
this.listen('fullscreen-change', this['fullscreen-change'].bind(this));
this.listen('fullscreen-error', this['fullscreen-error'].bind(this));
if (!this._media.$state.paused()) {
requestAnimationFrame(() => {
this._media.$provider()?.play();
});
}
this._resumePlaybackOnConnect();
onDispose(this._pausePlaybackOnDisconnect.bind(this));
}

_handle(event: Event) {
Expand All @@ -70,6 +68,27 @@ export class MediaStateManager extends MediaPlayerController {
}
}

private _isPlayingOnDisconnect = false;
private _resumePlaybackOnConnect() {
if (!this._isPlayingOnDisconnect) return;

if (this._media.$provider()?.paused) {
requestAnimationFrame(() => {
if (!this.scope) return;
this._media.remote.play(new DOMEvent<void>('dom-connect'));
});
}

this._isPlayingOnDisconnect = false;
}

private _pausePlaybackOnDisconnect() {
// It might already be set in `pause` handler.
if (this._isPlayingOnDisconnect) return;
this._isPlayingOnDisconnect = !this._media.$state.paused();
this._media.$provider()?.pause();
}

private _resetTracking() {
this._stopWaiting();
this._request._replaying = false;
Expand Down Expand Up @@ -431,6 +450,10 @@ export class MediaStateManager extends MediaPlayerController {
}

['pause'](event: ME.MediaPauseEvent) {
if (!this.el?.isConnected) {
this._isPlayingOnDisconnect = true;
}

if (this._request._looping) {
event.stopImmediatePropagation();
return;
Expand Down
8 changes: 5 additions & 3 deletions packages/vidstack/src/providers/hls/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ export class HLSProvider extends VideoProvider implements MediaProviderAdapter {
});
}

override async loadSource({ src }: MediaSrc) {
if (!isString(src)) return;
this._controller.instance?.loadSource(src);
override async loadSource(src: MediaSrc, preload?: HTMLMediaElement['preload']) {
if (!isString(src.src)) return;
this._media.preload = preload || '';
this._controller.instance?.loadSource(src.src);
this._currentSrc = src;
}

/**
Expand Down
12 changes: 9 additions & 3 deletions packages/vidstack/src/providers/html/provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { onDispose } from 'maverick.js';
import { isString, setAttribute } from 'maverick.js/std';

import type { MediaSrc } from '../../core/api/types';
Expand All @@ -13,14 +14,19 @@ import { NativeAudioTracks } from './native-audio-tracks';
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement}
*/
export class HTMLMediaProvider implements MediaProviderAdapter {
private _currentSrc: MediaSrc | null = null;
protected _currentSrc: MediaSrc | null = null;

constructor(protected _media: HTMLMediaElement) {}

setup(context: MediaSetupContext) {
new HTMLMediaEvents(this, context);
if ('audioTracks' in this.media) new NativeAudioTracks(this, context);
this.playsinline = context.$state.playsinline();
onDispose(() => {
// Dispose of media.
this._media.setAttribute('src', '');
this._media.load();
});
}

get type() {
Expand Down Expand Up @@ -87,8 +93,8 @@ export class HTMLMediaProvider implements MediaProviderAdapter {
return this._media.pause();
}

async loadSource({ src, type }: MediaSrc, preload) {
this._media.preload = preload;
async loadSource({ src, type }: MediaSrc, preload?: HTMLMediaElement['preload']) {
this._media.preload = preload || '';

if (isMediaStream(src)) {
this._media.srcObject = src;
Expand Down

0 comments on commit 92fa791

Please sign in to comment.