UNPKG

@aidenlx/vidstack-react

Version:

UI component library for building high-quality, accessible video and audio experiences on the web.

192 lines (185 loc) 6.08 kB
"use client" import * as React from 'react'; import { RadioGroupController, useMediaContext, menuContext, MediaRemoteControl, MediaPlayerInstance, sortVideoQualities } from './vidstack-CkT8sP15.js'; import { useMediaContext as useMediaContext$1 } from './vidstack-p9VvwQcz.js'; import { useSignal } from 'maverick.js/react'; import { isString } from 'maverick.js/std'; import { prop, method, Component, hasProvidedContext, useContext, effect } from 'maverick.js'; const DEFAULT_PLAYBACK_RATES = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; class SpeedRadioGroup extends Component { static props = { normalLabel: "Normal", rates: DEFAULT_PLAYBACK_RATES }; #media; #menu; #controller; get value() { return this.#controller.value; } get disabled() { const { rates } = this.$props, { canSetPlaybackRate } = this.#media.$state; return !canSetPlaybackRate() || rates().length === 0; } constructor() { super(); this.#controller = new RadioGroupController(); this.#controller.onValueChange = this.#onValueChange.bind(this); } onSetup() { this.#media = useMediaContext(); if (hasProvidedContext(menuContext)) { this.#menu = useContext(menuContext); } } onConnect(el) { effect(this.#watchValue.bind(this)); effect(this.#watchHintText.bind(this)); effect(this.#watchControllerDisabled.bind(this)); } getOptions() { const { rates, normalLabel } = this.$props; return rates().map((rate) => ({ label: rate === 1 ? normalLabel : rate + "\xD7", value: rate.toString() })); } #watchValue() { this.#controller.value = this.#getValue(); } #watchHintText() { const { normalLabel } = this.$props, { playbackRate } = this.#media.$state, rate = playbackRate(); this.#menu?.hint.set(rate === 1 ? normalLabel() : rate + "\xD7"); } #watchControllerDisabled() { this.#menu?.disable(this.disabled); } #getValue() { const { playbackRate } = this.#media.$state; return playbackRate().toString(); } #onValueChange(value, trigger) { if (this.disabled) return; const rate = +value; this.#media.remote.changePlaybackRate(rate, trigger); this.dispatch("change", { detail: rate, trigger }); } } const speedradiogroup__proto = SpeedRadioGroup.prototype; prop(speedradiogroup__proto, "value"); prop(speedradiogroup__proto, "disabled"); method(speedradiogroup__proto, "getOptions"); function useMediaRemote(target) { const media = useMediaContext$1(), remote = React.useRef(null); if (!remote.current) { remote.current = new MediaRemoteControl(); } React.useEffect(() => { const ref = target && "current" in target ? target.current : target, isPlayerRef = ref instanceof MediaPlayerInstance, player = isPlayerRef ? ref : media?.player; remote.current.setPlayer(player ?? null); remote.current.setTarget(ref ?? null); }, [media, target && "current" in target ? target.current : target]); return remote.current; } function useVideoQualityOptions({ auto = true, sort = "descending" } = {}) { const media = useMediaContext$1(), { qualities, quality, autoQuality, canSetQuality } = media.$state, $qualities = useSignal(qualities); useSignal(quality); useSignal(autoQuality); useSignal(canSetQuality); return React.useMemo(() => { const sortedQualities = sortVideoQualities($qualities, sort === "descending"), options = sortedQualities.map((q) => { return { quality: q, label: q.height + "p", value: getQualityValue(q), bitrateText: q.bitrate && q.bitrate > 0 ? `${(q.bitrate / 1e6).toFixed(2)} Mbps` : null, get selected() { return q === quality(); }, get autoSelected() { return autoQuality(); }, select(trigger) { const index = qualities().indexOf(q); if (index >= 0) media.remote.changeQuality(index, trigger); } }; }); if (auto) { options.unshift({ quality: null, label: isString(auto) ? auto : "Auto", value: "auto", bitrateText: null, get selected() { return autoQuality(); }, get autoSelected() { return autoQuality(); }, select(trigger) { media.remote.requestAutoQuality(trigger); } }); } Object.defineProperty(options, "disabled", { get() { return !canSetQuality() || $qualities.length <= 1; } }); Object.defineProperty(options, "selectedQuality", { get() { return quality(); } }); Object.defineProperty(options, "selectedValue", { get() { const $quality = quality(); return !autoQuality() && $quality ? getQualityValue($quality) : "auto"; } }); return options; }, [$qualities, sort]); } function getQualityValue(quality) { return quality.height + "_" + quality.bitrate; } function usePlaybackRateOptions({ rates = DEFAULT_PLAYBACK_RATES, normalLabel = "Normal" } = {}) { const media = useMediaContext$1(), { playbackRate, canSetPlaybackRate } = media.$state; useSignal(playbackRate); useSignal(canSetPlaybackRate); return React.useMemo(() => { const options = rates.map((opt) => { const label = typeof opt === "number" ? opt === 1 && normalLabel ? normalLabel : opt + "x" : opt.label, rate = typeof opt === "number" ? opt : opt.rate; return { label, value: rate.toString(), rate, get selected() { return playbackRate() === rate; }, select(trigger) { media.remote.changePlaybackRate(rate, trigger); } }; }); Object.defineProperty(options, "disabled", { get() { return !canSetPlaybackRate() || !options.length; } }); Object.defineProperty(options, "selectedValue", { get() { return playbackRate().toString(); } }); return options; }, [rates]); } export { DEFAULT_PLAYBACK_RATES, useMediaRemote, usePlaybackRateOptions, useVideoQualityOptions };