UNPKG

@vime/core

Version:

Customizable, extensible, accessible and framework agnostic media player.

529 lines (528 loc) 17.2 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Component, h, Prop, State, Watch } from '@stencil/core'; import { Disposal } from '../../../../utils/Disposal'; import { isUndefined } from '../../../../utils/unit'; import { findPlayer } from '../../../core/player/findPlayer'; import { createDispatcher, } from '../../../core/player/PlayerDispatcher'; import { getPlayerFromRegistry, withComponentRegistry, } from '../../../core/player/withComponentRegistry'; import { withPlayerContext } from '../../../core/player/withPlayerContext'; /** * Creates a settings menu with options for changing the audio track, playback rate, quality and * captions of the current media. This component is provider aware. For example, it will only show * options for changing the playback rate if the current provider allows changing it * (`player.canSetPlaybackRate()`). In addition, you can extend the settings with more options * via the default `slot`. * * ## Visual * * <img * src="https://raw.githubusercontent.com/vime-js/vime/master/packages/core/src/components/ui/settings/default-settings/default-settings.png" * alt="Vime default settings component" * /> * * @slot - Used to extend the settings with additional menu options (see `vm-submenu` or * `vm-menu-item`). */ export class DefaultSettings { constructor() { this.textTracksDisposal = new Disposal(); this.canSetPlaybackRate = false; this.canSetPlaybackQuality = false; this.canSetTextTrack = false; this.canSetAudioTrack = false; /** * Pins the settings to the defined position inside the video player. This has no effect when * the view is of type `audio`, it will always be `bottomRight`. */ this.pin = 'bottomRight'; /** @internal */ this.i18n = {}; /** @internal */ this.playbackReady = false; /** @internal */ this.playbackRate = 1; /** @internal */ this.playbackRates = [1]; /** @internal */ this.isVideoView = false; /** @internal */ this.playbackQualities = []; /** @internal */ this.textTracks = []; /** @internal */ this.currentTextTrack = -1; /** @internal */ this.audioTracks = []; /** @internal */ this.currentAudioTrack = -1; /** @internal */ this.isTextTrackVisible = true; withComponentRegistry(this); withPlayerContext(this, [ 'i18n', 'playbackReady', 'playbackRate', 'playbackRates', 'playbackQuality', 'playbackQualities', 'isVideoView', 'textTracks', 'currentTextTrack', 'isTextTrackVisible', 'audioTracks', 'currentAudioTrack', ]); } onPlaybackReady() { return __awaiter(this, void 0, void 0, function* () { const player = yield findPlayer(this); if (isUndefined(player)) return; this.canSetPlaybackQuality = yield player.canSetPlaybackQuality(); this.canSetPlaybackRate = yield player.canSetPlaybackRate(); }); } onAudioTracksChange() { var _a; return __awaiter(this, void 0, void 0, function* () { const player = getPlayerFromRegistry(this); this.canSetAudioTrack = (_a = (yield (player === null || player === void 0 ? void 0 : player.canSetAudioTrack()))) !== null && _a !== void 0 ? _a : false; }); } onTextTracksChange() { var _a; return __awaiter(this, void 0, void 0, function* () { const player = getPlayerFromRegistry(this); this.canSetTextTrack = (_a = (yield (player === null || player === void 0 ? void 0 : player.canSetTextTrack()))) !== null && _a !== void 0 ? _a : false; }); } connectedCallback() { this.dispatch = createDispatcher(this); } componentDidLoad() { this.onTextTracksChange(); } disconnectedCallback() { this.textTracksDisposal.empty(); } onPlaybackRateSelect(event) { const radio = event.target; this.dispatch('playbackRate', parseFloat(radio.value)); } buildPlaybackRateSubmenu() { if (this.playbackRates.length <= 1 || !this.canSetPlaybackRate) { return (h("vm-menu-item", { label: this.i18n.playbackRate, hint: this.i18n.normal })); } const formatRate = (rate) => rate === 1 ? this.i18n.normal : `${rate}`; return (h("vm-submenu", { label: this.i18n.playbackRate, hint: formatRate(this.playbackRate) }, h("vm-menu-radio-group", { value: `${this.playbackRate}`, onVmCheck: this.onPlaybackRateSelect.bind(this) }, this.playbackRates.map(rate => (h("vm-menu-radio", { label: formatRate(rate), value: `${rate}` })))))); } onPlaybackQualitySelect(event) { const radio = event.target; this.dispatch('playbackQuality', radio.value); } buildPlaybackQualitySubmenu() { var _a; if (this.playbackQualities.length <= 1 || !this.canSetPlaybackQuality) { return (h("vm-menu-item", { label: this.i18n.playbackQuality, hint: (_a = this.playbackQuality) !== null && _a !== void 0 ? _a : this.i18n.auto })); } // @TODO this doesn't account for audio qualities yet. const getBadge = (quality) => { const verticalPixels = parseInt(quality.slice(0, -1), 10); if (verticalPixels >= 2160) return 'UHD'; if (verticalPixels >= 1080) return 'HD'; return undefined; }; return (h("vm-submenu", { label: this.i18n.playbackQuality, hint: this.playbackQuality }, h("vm-menu-radio-group", { value: this.playbackQuality, onVmCheck: this.onPlaybackQualitySelect.bind(this) }, this.playbackQualities.map(quality => (h("vm-menu-radio", { label: quality, value: quality, badge: getBadge(quality) })))))); } onTextTrackSelect(event) { const radio = event.target; const trackId = parseInt(radio.value, 10); const player = getPlayerFromRegistry(this); if (trackId === -1) { player === null || player === void 0 ? void 0 : player.setTextTrackVisibility(false); return; } player === null || player === void 0 ? void 0 : player.setTextTrackVisibility(true); player === null || player === void 0 ? void 0 : player.setCurrentTextTrack(trackId); } buildTextTracksSubmenu() { var _a, _b, _c; if (this.textTracks.length <= 1 || !this.canSetTextTrack) { return (h("vm-menu-item", { label: this.i18n.subtitlesOrCc, hint: (_b = (_a = this.textTracks[this.currentTextTrack]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : this.i18n.none })); } return (h("vm-submenu", { label: this.i18n.subtitlesOrCc, hint: this.isTextTrackVisible ? (_c = this.textTracks[this.currentTextTrack]) === null || _c === void 0 ? void 0 : _c.label : this.i18n.off }, h("vm-menu-radio-group", { value: `${!this.isTextTrackVisible ? -1 : this.currentTextTrack}`, onVmCheck: this.onTextTrackSelect.bind(this) }, [h("vm-menu-radio", { label: this.i18n.off, value: "-1" })].concat(this.textTracks.map((track, i) => (h("vm-menu-radio", { label: track.label, value: `${i}` }))))))); } onAudioTrackSelect(event) { const radio = event.target; const trackId = parseInt(radio.value, 10); const player = getPlayerFromRegistry(this); player === null || player === void 0 ? void 0 : player.setCurrentAudioTrack(trackId); } buildAudioTracksMenu() { var _a, _b, _c; if (this.audioTracks.length <= 1 || !this.canSetAudioTrack) { return (h("vm-menu-item", { label: this.i18n.audio, hint: (_b = (_a = this.audioTracks[this.currentAudioTrack]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : this.i18n.default })); } return (h("vm-submenu", { label: this.i18n.audio, hint: (_c = this.audioTracks[this.currentAudioTrack]) === null || _c === void 0 ? void 0 : _c.label }, h("vm-menu-radio-group", { value: `${this.currentAudioTrack}`, onVmCheck: this.onAudioTrackSelect.bind(this) }, this.audioTracks.map((track, i) => (h("vm-menu-radio", { label: track.label, value: `${i}` })))))); } render() { return (h("vm-settings", { pin: this.pin }, this.buildAudioTracksMenu(), this.buildPlaybackRateSubmenu(), this.buildPlaybackQualitySubmenu(), this.isVideoView && this.buildTextTracksSubmenu(), h("slot", null))); } static get is() { return "vm-default-settings"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["default-settings.css"] }; } static get styleUrls() { return { "$": ["default-settings.css"] }; } static get properties() { return { "pin": { "type": "string", "mutable": false, "complexType": { "original": "'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'", "resolved": "\"bottomLeft\" | \"bottomRight\" | \"topLeft\" | \"topRight\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Pins the settings to the defined position inside the video player. This has no effect when\nthe view is of type `audio`, it will always be `bottomRight`." }, "attribute": "pin", "reflect": true, "defaultValue": "'bottomRight'" }, "i18n": { "type": "unknown", "mutable": false, "complexType": { "original": "PlayerProps['i18n']", "resolved": "Translation | { [x: string]: string; }", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "defaultValue": "{}" }, "playbackReady": { "type": "boolean", "mutable": false, "complexType": { "original": "PlayerProps['playbackReady']", "resolved": "boolean", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "playback-ready", "reflect": false, "defaultValue": "false" }, "playbackRate": { "type": "number", "mutable": false, "complexType": { "original": "PlayerProps['playbackRate']", "resolved": "number", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "playback-rate", "reflect": false, "defaultValue": "1" }, "playbackRates": { "type": "unknown", "mutable": false, "complexType": { "original": "PlayerProps['playbackRates']", "resolved": "number[]", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "defaultValue": "[1]" }, "isVideoView": { "type": "boolean", "mutable": false, "complexType": { "original": "PlayerProps['isAudioView']", "resolved": "boolean", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "is-video-view", "reflect": false, "defaultValue": "false" }, "playbackQuality": { "type": "string", "mutable": false, "complexType": { "original": "PlayerProps['playbackQuality']", "resolved": "string | undefined", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": true, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "playback-quality", "reflect": false }, "playbackQualities": { "type": "unknown", "mutable": false, "complexType": { "original": "PlayerProps['playbackQualities']", "resolved": "string[]", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "defaultValue": "[]" }, "textTracks": { "type": "unknown", "mutable": false, "complexType": { "original": "PlayerProps['textTracks']", "resolved": "TextTrack[]", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "defaultValue": "[]" }, "currentTextTrack": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "current-text-track", "reflect": false, "defaultValue": "-1" }, "audioTracks": { "type": "unknown", "mutable": false, "complexType": { "original": "PlayerProps['audioTracks']", "resolved": "any[]", "references": { "PlayerProps": { "location": "import", "path": "../../../core/player/PlayerProps" } } }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "defaultValue": "[]" }, "currentAudioTrack": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "current-audio-track", "reflect": false, "defaultValue": "-1" }, "isTextTrackVisible": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "text": undefined, "name": "internal" }], "text": "" }, "attribute": "is-text-track-visible", "reflect": false, "defaultValue": "true" } }; } static get states() { return { "canSetPlaybackRate": {}, "canSetPlaybackQuality": {}, "canSetTextTrack": {}, "canSetAudioTrack": {} }; } static get watchers() { return [{ "propName": "playbackReady", "methodName": "onPlaybackReady" }, { "propName": "audioTracks", "methodName": "onAudioTracksChange" }, { "propName": "playbackReady", "methodName": "onAudioTracksChange" }, { "propName": "textTracks", "methodName": "onTextTracksChange" }, { "propName": "playbackReady", "methodName": "onTextTracksChange" }]; } }