@aidenlx/player
Version:
Headless web components that make integrating media on the a web a breeze.
428 lines (427 loc) • 12.5 kB
JavaScript
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