UNPKG

@aidenlx/player

Version:

Headless web components that make integrating media on the a web a breeze.

428 lines (427 loc) 12.5 kB
import { __decorateClass } from "../../chunks/chunk.S6UZ27SZ.js"; import { clampNumber, createIntersectionController, discover, DisposalBin, FullscreenController, get, hostRequestQueue, isUndefined, listen, LogDispatcher, notEqual, RequestQueue, ScreenOrientationController, vdsEvent } from "@vidstack/foundation"; import { LitElement } from "lit"; import { property, state } from "lit/decorators.js"; import { CanPlay } from "../CanPlay"; import { MediaController } from "../controller"; import { MediaType } from "../MediaType"; import { mediaStoreContext } from "../store"; import { ViewType } from "../ViewType"; class MediaProviderElement extends LitElement { constructor() { super(); this._disconnectDisposal = new DisposalBin(); this._logger = true ? new LogDispatcher(this) : void 0; this.controls = false; this.loop = false; this.playsinline = false; this.loading = "eager"; this._autoplayAttemptPending = false; this._shouldSkipNextSrcChangeReset = true; this._mediaController = new MediaController(this); this._mediaStoreConsumer = mediaStoreContext.consume(this); this.mediaState = new Proxy(() => this._mediaStoreConsumer.value, { get(target, key) { return get(target()[key]); }, has(target, key) { return Reflect.has(target(), key); }, ownKeys(target) { return Reflect.ownKeys(target()); }, getOwnPropertyDescriptor(target, key) { return Reflect.getOwnPropertyDescriptor(target(), key); } }); this._connectedQueue = hostRequestQueue(this); this.mediaRequestQueue = new RequestQueue(); this.screenOrientationController = new ScreenOrientationController(this); this.fullscreenController = new FullscreenController(this, this.screenOrientationController); discover(this, "vds-media-provider-connect"); const controller = createIntersectionController(this, { threshold: 0 }, (entries) => { if (this.loading !== "lazy") { controller.hostDisconnected(); return; } if (entries[0]?.isIntersecting) { this.handleMediaCanLoad(); controller.hostDisconnected(); } }); } connectedCallback() { super.connectedCallback(); this._logMediaEvents(); window.requestAnimationFrame(() => { if (isUndefined(this.__canLoadPoster)) { this.__canLoadPoster = true; } }); } updated(changedProperties) { super.updated(changedProperties); if (changedProperties.has("controls")) { this.dispatchEvent(vdsEvent("vds-controls-change", { detail: this.controls ?? false })); } if (changedProperties.has("loop")) { this.dispatchEvent(vdsEvent("vds-loop-change", { detail: this.loop ?? false })); } if (changedProperties.has("playsinline")) { this.dispatchEvent(vdsEvent("vds-playsinline-change", { detail: this.playsinline ?? false })); } } firstUpdated(changedProperties) { super.firstUpdated(changedProperties); this.dispatchEvent(vdsEvent("vds-fullscreen-support-change", { detail: this.canFullscreen })); if (this.loading === "eager") { this.handleMediaCanLoad(); } } disconnectedCallback() { super.disconnectedCallback(); this.mediaRequestQueue.destroy(); this._shouldSkipNextSrcChangeReset = false; this._disconnectDisposal.empty(); } _logMediaEvents() { if (true) { const mediaEvents = [ "vds-abort", "vds-can-play", "vds-can-play-through", "vds-duration-change", "vds-emptied", "vds-ended", "vds-error", "vds-fullscreen-change", "vds-loaded-data", "vds-loaded-metadata", "vds-load-start", "vds-media-type-change", "vds-pause", "vds-play", "vds-playing", "vds-progress", "vds-seeked", "vds-seeking", "vds-stalled", "vds-started", "vds-suspend", "vds-replay", "vds-view-type-change", "vds-volume-change", "vds-waiting" ]; mediaEvents.forEach((eventType) => { const dispose = listen(this, eventType, (event) => { this._logger?.infoGroup(`\u{1F4E1} dispatching \`${eventType}\``).labelledLog("State", { ...this.mediaState }).labelledLog("Event", event).labelledLog("Engine", this.engine).dispatch(); }); this._disconnectDisposal.add(dispose); }); } } get autoplay() { return this.mediaState.autoplay; } set autoplay(shouldAutoplay) { this._connectedQueue.queue("autoplay-change", () => { if (this.autoplay !== shouldAutoplay) { this.dispatchEvent(vdsEvent("vds-autoplay-change", { detail: shouldAutoplay })); } if (this.canPlay && !this._autoplayAttemptPending && shouldAutoplay) { this._autoplayAttemptPending = true; const onAttemptEnd = () => { this._autoplayAttemptPending = false; }; this.attemptAutoplay().then(onAttemptEnd).catch(onAttemptEnd); } }); } get volume() { return this.mediaState.volume; } set volume(requestedVolume) { this.mediaRequestQueue.queue("volume", () => { const volume = clampNumber(0, requestedVolume, 1); if (notEqual(this.volume, volume)) { this._setVolume(volume); this.requestUpdate("volume"); } }); } get paused() { return this.mediaState.paused; } set paused(shouldPause) { this.mediaRequestQueue.queue("paused", () => { if (this.paused === shouldPause) return; try { if (!shouldPause) { this.play(); } else { this.pause(); } } catch (e) { this._logger?.error("paused-change-fail", e); } this.requestUpdate("paused"); }); } get currentTime() { return this._getCurrentTime(); } set currentTime(requestedTime) { this.mediaRequestQueue.queue("time", () => { if (notEqual(this.currentTime, requestedTime)) { this._setCurrentTime(requestedTime); this.requestUpdate("currentTime"); } }); } _getCurrentTime() { return Math.min(this.mediaState.currentTime, this.duration); } get muted() { return this.mediaState.muted; } set muted(shouldMute) { this.mediaRequestQueue.queue("muted", () => { if (notEqual(this.muted, shouldMute)) { this._setMuted(shouldMute); this.requestUpdate("muted"); } }); } get autoplayError() { return this.mediaState.autoplayError; } get buffered() { return this.mediaState.buffered; } get canPlay() { return this.mediaState.canPlay; } get currentPoster() { return this.mediaState.currentPoster; } get currentSrc() { return this.mediaState.currentSrc; } get duration() { return this.mediaState.duration; } get ended() { return this.mediaState.ended; } get error() { return this.mediaState.error; } get live() { return this.mediaState.mediaType === MediaType.LiveVideo; } get mediaType() { return this.mediaState.mediaType; } get played() { return this.mediaState.played; } get playing() { return this.mediaState.playing; } get seekable() { return this.mediaState.seekable; } get seeking() { return this.mediaState.seeking; } get started() { return this.mediaState.started; } get viewType() { return this.mediaState.viewType; } get waiting() { return this.mediaState.waiting; } shouldPlayType(type) { const canPlayType = this.canPlayType(type); return canPlayType === CanPlay.Maybe || canPlayType === CanPlay.Probably; } get canLoad() { return this.mediaState.canLoad; } async handleMediaCanLoad() { this.dispatchEvent(vdsEvent("vds-can-load")); } _throwIfNotReadyForPlayback() { if (!this.canPlay) { throw Error(`Media is not ready - wait for \`vds-can-play\` event.`); } } async _resetPlaybackIfEnded() { if (!this.ended || this.currentTime === 0) return; return this._setCurrentTime(0); } _throwIfNotVideoView() { if (this.viewType !== ViewType.Video) { throw Error("Player is currently not in a video view."); } } async _handleMediaReady({ event, duration }) { if (this.canPlay) return; this.dispatchEvent(vdsEvent("vds-can-play", { triggerEvent: event, detail: { duration } })); await this.mediaRequestQueue.start(); if (true) { this._logger?.infoGroup("-~-~-~-~-~-~-~-~- \u2705 MEDIA READY -~-~-~-~-~-~-~-~-").labelledLog("State", { ...this.mediaState }).labelledLog("Event", event).labelledLog("Engine", this.engine).dispatch(); } await this.attemptAutoplay(); } get canAttemptAutoplay() { return this.autoplay && !this.started; } async attemptAutoplay() { if (!this.canPlay || !this.canAttemptAutoplay) return; this._autoplayAttemptPending = true; try { await this.play(); this.dispatchEvent(vdsEvent("vds-autoplay", { detail: { muted: this.muted } })); } catch (error) { this.dispatchEvent(vdsEvent("vds-autoplay-fail", { detail: { muted: this.muted, error } })); this.requestUpdate(); } this._autoplayAttemptPending = false; } _handleMediaSrcChange(src) { this._store.currentSrc.set(src); if (!this.hasUpdated) { return; } if (this._shouldSkipNextSrcChangeReset) { this._shouldSkipNextSrcChangeReset = false; return; } if (true) { this._logger?.infoGroup("\u{1F4FC} media src change").labelledLog("Current src", this.currentSrc).labelledLog("Engine", this.engine).dispatch(); } this.mediaRequestQueue.stop(); this.dispatchEvent(vdsEvent("vds-src-change", { detail: src })); } get logLevel() { return this._mediaController.logLevel; } set logLevel(level) { if (true) { this._mediaController.logLevel = level; } } get idleDelay() { return this._mediaController.idleDelay; } set idleDelay(delay) { this._mediaController.idleDelay = delay; } get store() { return this._mediaStoreConsumer.value; } get _store() { return this._mediaStoreConsumer.value; } get canFullscreen() { return this.fullscreenController.isSupported; } get fullscreen() { return this.mediaState.fullscreen; } get fullscreenOrientation() { return this.fullscreenController.screenOrientationLock; } set fullscreenOrientation(lockType) { this.fullscreenController.screenOrientationLock = lockType; } async requestFullscreen() { if (this.fullscreenController.isRequestingNativeFullscreen) { return super.requestFullscreen(); } return this.fullscreenController.requestFullscreen(); } exitFullscreen() { return this.fullscreenController.exitFullscreen(); } } __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "autoplay", 1); __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "controls", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "loop", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "playsinline", 2); __decorateClass([ property({ type: Number, reflect: true }) ], MediaProviderElement.prototype, "volume", 1); __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "paused", 1); __decorateClass([ property({ attribute: "current-time", type: Number }) ], MediaProviderElement.prototype, "currentTime", 1); __decorateClass([ property({ type: Boolean, reflect: true }) ], MediaProviderElement.prototype, "muted", 1); __decorateClass([ state() ], MediaProviderElement.prototype, "__canLoadPoster", 2); __decorateClass([ property({ attribute: "loading" }) ], MediaProviderElement.prototype, "loading", 2); __decorateClass([ property({ attribute: "log-level" }) ], MediaProviderElement.prototype, "logLevel", 1); __decorateClass([ property({ attribute: "idle-delay", type: Number }) ], MediaProviderElement.prototype, "idleDelay", 1); __decorateClass([ property({ attribute: "fullscreen-orientation" }) ], MediaProviderElement.prototype, "fullscreenOrientation", 1); export { MediaProviderElement }; //# sourceMappingURL=MediaProviderElement.js.map