From 8f2c7992355e2d52be27aa34d290dd75ee16798d Mon Sep 17 00:00:00 2001 From: Stanislav Ulegin Date: Fri, 27 Feb 2026 09:50:13 +0300 Subject: [PATCH] feat: release v0.0.1 --- .gitignore | 3 + .storybook/main.ts | 15 + .storybook/preview.css | 25 + .storybook/preview.ts | 22 + README.md | 193 +- dist/angular/index.d.ts | 26 + dist/angular/index.d.ts.map | 1 + dist/angular/index.js | 43 + dist/angular/index.js.map | 1 + dist/core/engine-selector.d.ts | 12 + dist/core/engine-selector.d.ts.map | 1 + dist/core/engine-selector.js | 24 + dist/core/engine-selector.js.map | 1 + dist/core/format-time.d.ts | 2 + dist/core/format-time.d.ts.map | 1 + dist/core/format-time.js | 11 + dist/core/format-time.js.map | 1 + dist/core/index.d.ts | 4 + dist/core/index.d.ts.map | 1 + dist/core/index.js | 4 + dist/core/index.js.map | 1 + dist/core/player-runtime.d.ts | 137 + dist/core/player-runtime.d.ts.map | 1 + dist/core/player-runtime.js | 707 ++ dist/core/player-runtime.js.map | 1 + dist/core/plugins/big-play-pause-button.d.ts | 4 + .../plugins/big-play-pause-button.d.ts.map | 1 + dist/core/plugins/big-play-pause-button.js | 26 + .../core/plugins/big-play-pause-button.js.map | 1 + dist/core/plugins/register.d.ts | 4 + dist/core/plugins/register.d.ts.map | 1 + dist/core/plugins/register.js | 4 + dist/core/plugins/register.js.map | 1 + .../tach-video-menu-button/index.d.ts | 38 + .../tach-video-menu-button/index.d.ts.map | 1 + .../tach-video-menu-button/index.js | 90 + .../tach-video-menu-button/index.js.map | 1 + .../tach-video-menu-item/index.d.ts | 33 + .../tach-video-menu-item/index.d.ts.map | 1 + .../components/tach-video-menu-item/index.js | 45 + .../tach-video-menu-item/index.js.map | 1 + .../components/tach-video-menu/index.d.ts | 33 + .../components/tach-video-menu/index.d.ts.map | 1 + .../components/tach-video-menu/index.js | 56 + .../components/tach-video-menu/index.js.map | 1 + dist/core/plugins/settings/index.d.ts | 53 + dist/core/plugins/settings/index.d.ts.map | 1 + dist/core/plugins/settings/index.js | 141 + dist/core/plugins/settings/index.js.map | 1 + .../selectors/audio-track-selector/index.d.ts | 27 + .../audio-track-selector/index.d.ts.map | 1 + .../selectors/audio-track-selector/index.js | 125 + .../audio-track-selector/index.js.map | 1 + .../playback-rate-selector/index.d.ts | 30 + .../playback-rate-selector/index.d.ts.map | 1 + .../selectors/playback-rate-selector/index.js | 35 + .../playback-rate-selector/index.js.map | 1 + .../quality-rate-selector/index.d.ts | 39 + .../quality-rate-selector/index.d.ts.map | 1 + .../selectors/quality-rate-selector/index.js | 125 + .../quality-rate-selector/index.js.map | 1 + .../selectors/text-track-selector/index.d.ts | 26 + .../text-track-selector/index.d.ts.map | 1 + .../selectors/text-track-selector/index.js | 49 + .../text-track-selector/index.js.map | 1 + dist/core/plugins/settings/settings.css | 93 + dist/core/plugins/settings/types.d.ts | 10 + dist/core/plugins/settings/types.d.ts.map | 1 + dist/core/plugins/settings/types.js | 2 + dist/core/plugins/settings/types.js.map | 1 + dist/core/plugins/skip-buttons.css | 126 + dist/core/plugins/skip-buttons.d.ts | 8 + dist/core/plugins/skip-buttons.d.ts.map | 1 + dist/core/plugins/skip-buttons.js | 150 + dist/core/plugins/skip-buttons.js.map | 1 + dist/core/token-provider.d.ts | 5 + dist/core/token-provider.d.ts.map | 1 + dist/core/token-provider.js | 11 + dist/core/token-provider.js.map | 1 + dist/react/index.d.ts | 3 + dist/react/index.d.ts.map | 1 + dist/react/index.js | 2 + dist/react/index.js.map | 1 + .../components/player-extension/index.d.ts | 10 + .../player-extension/index.d.ts.map | 1 + .../components/player-extension/index.js | 8 + .../components/player-extension/index.js.map | 1 + .../components/qr-scanner/index.d.ts | 25 + .../components/qr-scanner/index.d.ts.map | 1 + .../components/qr-scanner/index.js | 209 + .../components/qr-scanner/index.js.map | 1 + .../components/video-js/default.css | 2226 ++++++ .../video-js/hls-or-videojs-player.d.ts | 4 + .../video-js/hls-or-videojs-player.d.ts.map | 1 + .../video-js/hls-or-videojs-player.js | 89 + .../video-js/hls-or-videojs-player.js.map | 1 + .../components/video-js/index.d.ts | 3 + .../components/video-js/index.d.ts.map | 1 + .../video-player/components/video-js/index.js | 3 + .../components/video-js/index.js.map | 1 + .../plugins/big-play-pause-button/index.d.ts | 4 + .../big-play-pause-button/index.d.ts.map | 1 + .../plugins/big-play-pause-button/index.js | 26 + .../big-play-pause-button/index.js.map | 1 + .../tach-video-menu-button/index.d.ts | 38 + .../tach-video-menu-button/index.d.ts.map | 1 + .../tach-video-menu-button/index.js | 90 + .../tach-video-menu-button/index.js.map | 1 + .../tach-video-menu-item/index.d.ts | 33 + .../tach-video-menu-item/index.d.ts.map | 1 + .../components/tach-video-menu-item/index.js | 45 + .../tach-video-menu-item/index.js.map | 1 + .../components/tach-video-menu/index.d.ts | 33 + .../components/tach-video-menu/index.d.ts.map | 1 + .../components/tach-video-menu/index.js | 56 + .../components/tach-video-menu/index.js.map | 1 + .../video-js/plugins/settings/index.d.ts | 52 + .../video-js/plugins/settings/index.d.ts.map | 1 + .../video-js/plugins/settings/index.js | 141 + .../video-js/plugins/settings/index.js.map | 1 + .../selectors/audio-track-selector/index.d.ts | 27 + .../audio-track-selector/index.d.ts.map | 1 + .../selectors/audio-track-selector/index.js | 125 + .../audio-track-selector/index.js.map | 1 + .../playback-rate-selector/index.d.ts | 30 + .../playback-rate-selector/index.d.ts.map | 1 + .../selectors/playback-rate-selector/index.js | 35 + .../playback-rate-selector/index.js.map | 1 + .../quality-rate-selector/index.d.ts | 39 + .../quality-rate-selector/index.d.ts.map | 1 + .../selectors/quality-rate-selector/index.js | 125 + .../quality-rate-selector/index.js.map | 1 + .../selectors/text-track-selector/index.d.ts | 22 + .../text-track-selector/index.d.ts.map | 1 + .../selectors/text-track-selector/index.js | 49 + .../text-track-selector/index.js.map | 1 + .../video-js/plugins/settings/settings.css | 93 + .../video-js/plugins/skip-buttons/index.d.ts | 8 + .../plugins/skip-buttons/index.d.ts.map | 1 + .../video-js/plugins/skip-buttons/index.js | 145 + .../plugins/skip-buttons/index.js.map | 1 + .../plugins/skip-buttons/skip-backward.svg | 15 + .../plugins/skip-buttons/skip-buttons.css | 115 + .../plugins/skip-buttons/skip-forward.svg | 15 + .../video-js/plugins/types/index.d.ts | 10 + .../video-js/plugins/types/index.d.ts.map | 1 + .../video-js/plugins/types/index.js | 2 + .../video-js/plugins/types/index.js.map | 1 + .../components/video-js/types.d.ts | 51 + .../components/video-js/types.d.ts.map | 1 + .../video-player/components/video-js/types.js | 2 + .../components/video-js/types.js.map | 1 + .../components/video-js/utils.d.ts | 2 + .../components/video-js/utils.d.ts.map | 1 + .../video-player/components/video-js/utils.js | 11 + .../components/video-js/utils.js.map | 1 + .../components/video-js/videojs.module.scss | 5 + .../components/with-blur/index.d.ts | 7 + .../components/with-blur/index.d.ts.map | 1 + .../components/with-blur/index.js | 72 + .../components/with-blur/index.js.map | 1 + .../components/with-blur/with-blur.css | 9 + .../with-blur/with-blur.module.scss | 22 + .../components/with-cover/index.d.ts | 9 + .../components/with-cover/index.d.ts.map | 1 + .../components/with-cover/index.js | 74 + .../components/with-cover/index.js.map | 1 + .../with-cover/with-cover.module.scss | 10 + .../components/with-duration-badge/index.d.ts | 7 + .../with-duration-badge/index.d.ts.map | 1 + .../components/with-duration-badge/index.js | 71 + .../with-duration-badge/index.js.map | 1 + .../with-duration-badge.module.scss | 22 + .../components/with-errors/index.d.ts | 7 + .../components/with-errors/index.d.ts.map | 1 + .../components/with-errors/index.js | 9 + .../components/with-errors/index.js.map | 1 + .../with-errors/video-error/index.d.ts | 7 + .../with-errors/video-error/index.d.ts.map | 1 + .../with-errors/video-error/index.js | 16 + .../with-errors/video-error/index.js.map | 1 + .../video-error/video-error-icon.svg | 6 + .../video-error/video-error.module.scss | 23 + .../with-errors/with-errors.module.scss | 6 + .../components/with-lazy/index.d.ts | 7 + .../components/with-lazy/index.d.ts.map | 1 + .../components/with-lazy/index.js | 49 + .../components/with-lazy/index.js.map | 1 + .../with-lazy/with-lazy.module.scss | 3 + .../components/with-loader/index.d.ts | 7 + .../components/with-loader/index.d.ts.map | 1 + .../components/with-loader/index.js | 23 + .../components/with-loader/index.js.map | 1 + .../with-loader/with-loader.module.scss | 11 + .../components/with-mouse-events/index.d.ts | 11 + .../with-mouse-events/index.d.ts.map | 1 + .../components/with-mouse-events/index.js | 46 + .../components/with-mouse-events/index.js.map | 1 + .../with-mouse-events.module.scss | 4 + .../components/with-observation/index.d.ts | 10 + .../with-observation/index.d.ts.map | 1 + .../components/with-observation/index.js | 46 + .../components/with-observation/index.js.map | 1 + .../with-observation.module.scss | 4 + .../components/with-processing/index.d.ts | 7 + .../components/with-processing/index.d.ts.map | 1 + .../components/with-processing/index.js | 12 + .../components/with-processing/index.js.map | 1 + .../video-processing/index.d.ts | 6 + .../video-processing/index.d.ts.map | 1 + .../with-processing/video-processing/index.js | 8 + .../video-processing/index.js.map | 1 + .../video-processing.module.scss | 86 + .../with-processing.module.scss | 17 + dist/react/video-player/index.d.ts | 2 + dist/react/video-player/index.d.ts.map | 1 + dist/react/video-player/index.js | 2 + dist/react/video-player/index.js.map | 1 + dist/react/video-player/shared/math.d.ts | 3 + dist/react/video-player/shared/math.d.ts.map | 1 + dist/react/video-player/shared/math.js | 18 + dist/react/video-player/shared/math.js.map | 1 + dist/react/video-player/shared/types.d.ts | 4 + dist/react/video-player/shared/types.d.ts.map | 1 + dist/react/video-player/shared/types.js | 2 + dist/react/video-player/shared/types.js.map | 1 + .../shared/ui/content-skeleton.d.ts | 4 + .../shared/ui/content-skeleton.d.ts.map | 1 + .../shared/ui/content-skeleton.js | 6 + .../shared/ui/content-skeleton.js.map | 1 + dist/react/video-player/tach-video-js.css | 695 ++ dist/react/video-player/video-player.d.ts | 26 + dist/react/video-player/video-player.d.ts.map | 1 + dist/react/video-player/video-player.js | 59 + dist/react/video-player/video-player.js.map | 1 + dist/react/video-player/video.module.scss | 37 + package-lock.json | 5994 +++++++++++++++++ package.json | 88 + scripts/build.mjs | 60 + src/angular/index.ts | 73 + src/core/engine-selector.ts | 48 + src/core/format-time.ts | 12 + src/core/index.ts | 24 + src/core/player-runtime.ts | 1007 +++ src/core/plugins/big-play-pause-button.ts | 31 + src/core/plugins/register.ts | 3 + .../tach-video-menu-button/index.ts | 116 + .../components/tach-video-menu-item/index.ts | 69 + .../components/tach-video-menu/index.ts | 77 + src/core/plugins/settings/index.ts | 201 + .../selectors/audio-track-selector/index.ts | 177 + .../selectors/playback-rate-selector/index.ts | 46 + .../selectors/quality-rate-selector/index.ts | 163 + .../selectors/text-track-selector/index.ts | 66 + src/core/plugins/settings/settings.css | 93 + src/core/plugins/settings/types.ts | 9 + src/core/plugins/skip-buttons.css | 126 + src/core/plugins/skip-buttons.ts | 196 + src/core/token-provider.ts | 23 + src/react/index.ts | 13 + .../components/player-extension/index.tsx | 31 + .../components/qr-scanner/index.tsx | 310 + .../__tests__/hls-or-videojs-player.test.tsx | 450 ++ .../components/video-js/default.css | 2226 ++++++ .../video-js/hls-or-videojs-player.tsx | 122 + .../components/video-js/index.tsx | 3 + .../plugins/big-play-pause-button/index.ts | 31 + .../tach-video-menu-button/index.ts | 116 + .../components/tach-video-menu-item/index.ts | 69 + .../components/tach-video-menu/index.ts | 77 + .../video-js/plugins/settings/index.ts | 203 + .../selectors/audio-track-selector/index.ts | 177 + .../selectors/playback-rate-selector/index.ts | 46 + .../selectors/quality-rate-selector/index.ts | 163 + .../selectors/text-track-selector/index.ts | 65 + .../video-js/plugins/settings/settings.css | 93 + .../video-js/plugins/skip-buttons/index.tsx | 205 + .../plugins/skip-buttons/skip-backward.svg | 15 + .../plugins/skip-buttons/skip-buttons.css | 115 + .../plugins/skip-buttons/skip-forward.svg | 15 + .../video-js/plugins/types/index.ts | 9 + .../video-player/components/video-js/types.ts | 58 + .../video-player/components/video-js/utils.ts | 10 + .../components/video-js/videojs.module.scss | 5 + .../components/with-blur/index.tsx | 101 + .../components/with-blur/with-blur.css | 9 + .../with-blur/with-blur.module.scss | 22 + .../components/with-cover/index.tsx | 130 + .../with-cover/with-cover.module.scss | 10 + .../components/with-duration-badge/index.tsx | 105 + .../with-duration-badge.module.scss | 22 + .../components/with-errors/index.tsx | 32 + .../with-errors/video-error/index.tsx | 44 + .../video-error/video-error-icon.svg | 6 + .../video-error/video-error.module.scss | 23 + .../with-errors/with-errors.module.scss | 6 + .../components/with-lazy/index.tsx | 78 + .../with-lazy/with-lazy.module.scss | 3 + .../components/with-loader/index.tsx | 45 + .../with-loader/with-loader.module.scss | 11 + .../components/with-mouse-events/index.tsx | 90 + .../with-mouse-events.module.scss | 4 + .../components/with-observation/index.tsx | 78 + .../with-observation.module.scss | 4 + .../components/with-processing/index.tsx | 28 + .../video-processing/index.tsx | 29 + .../video-processing.module.scss | 86 + .../with-processing.module.scss | 17 + src/react/video-player/index.tsx | 5 + src/react/video-player/shared/math.ts | 22 + src/react/video-player/shared/types.ts | 3 + .../shared/ui/content-skeleton.tsx | 7 + src/react/video-player/tach-video-js.css | 695 ++ src/react/video-player/video-player.tsx | 160 + src/react/video-player/video.module.scss | 37 + src/types/assets.d.ts | 21 + src/types/lodash.d.ts | 18 + .../angular-video-player-adapter.stories.tsx | 220 + stories/react-video-player.stories.tsx | 93 + tsconfig.build.json | 30 + tsconfig.json | 26 + 321 files changed, 23986 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.css create mode 100644 .storybook/preview.ts create mode 100644 dist/angular/index.d.ts create mode 100644 dist/angular/index.d.ts.map create mode 100644 dist/angular/index.js create mode 100644 dist/angular/index.js.map create mode 100644 dist/core/engine-selector.d.ts create mode 100644 dist/core/engine-selector.d.ts.map create mode 100644 dist/core/engine-selector.js create mode 100644 dist/core/engine-selector.js.map create mode 100644 dist/core/format-time.d.ts create mode 100644 dist/core/format-time.d.ts.map create mode 100644 dist/core/format-time.js create mode 100644 dist/core/format-time.js.map create mode 100644 dist/core/index.d.ts create mode 100644 dist/core/index.d.ts.map create mode 100644 dist/core/index.js create mode 100644 dist/core/index.js.map create mode 100644 dist/core/player-runtime.d.ts create mode 100644 dist/core/player-runtime.d.ts.map create mode 100644 dist/core/player-runtime.js create mode 100644 dist/core/player-runtime.js.map create mode 100644 dist/core/plugins/big-play-pause-button.d.ts create mode 100644 dist/core/plugins/big-play-pause-button.d.ts.map create mode 100644 dist/core/plugins/big-play-pause-button.js create mode 100644 dist/core/plugins/big-play-pause-button.js.map create mode 100644 dist/core/plugins/register.d.ts create mode 100644 dist/core/plugins/register.d.ts.map create mode 100644 dist/core/plugins/register.js create mode 100644 dist/core/plugins/register.js.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts create mode 100644 dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu-button/index.js create mode 100644 dist/core/plugins/settings/components/tach-video-menu-button/index.js.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts create mode 100644 dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu-item/index.js create mode 100644 dist/core/plugins/settings/components/tach-video-menu-item/index.js.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu/index.d.ts create mode 100644 dist/core/plugins/settings/components/tach-video-menu/index.d.ts.map create mode 100644 dist/core/plugins/settings/components/tach-video-menu/index.js create mode 100644 dist/core/plugins/settings/components/tach-video-menu/index.js.map create mode 100644 dist/core/plugins/settings/index.d.ts create mode 100644 dist/core/plugins/settings/index.d.ts.map create mode 100644 dist/core/plugins/settings/index.js create mode 100644 dist/core/plugins/settings/index.js.map create mode 100644 dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts create mode 100644 dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts.map create mode 100644 dist/core/plugins/settings/selectors/audio-track-selector/index.js create mode 100644 dist/core/plugins/settings/selectors/audio-track-selector/index.js.map create mode 100644 dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts create mode 100644 dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts.map create mode 100644 dist/core/plugins/settings/selectors/playback-rate-selector/index.js create mode 100644 dist/core/plugins/settings/selectors/playback-rate-selector/index.js.map create mode 100644 dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts create mode 100644 dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts.map create mode 100644 dist/core/plugins/settings/selectors/quality-rate-selector/index.js create mode 100644 dist/core/plugins/settings/selectors/quality-rate-selector/index.js.map create mode 100644 dist/core/plugins/settings/selectors/text-track-selector/index.d.ts create mode 100644 dist/core/plugins/settings/selectors/text-track-selector/index.d.ts.map create mode 100644 dist/core/plugins/settings/selectors/text-track-selector/index.js create mode 100644 dist/core/plugins/settings/selectors/text-track-selector/index.js.map create mode 100644 dist/core/plugins/settings/settings.css create mode 100644 dist/core/plugins/settings/types.d.ts create mode 100644 dist/core/plugins/settings/types.d.ts.map create mode 100644 dist/core/plugins/settings/types.js create mode 100644 dist/core/plugins/settings/types.js.map create mode 100644 dist/core/plugins/skip-buttons.css create mode 100644 dist/core/plugins/skip-buttons.d.ts create mode 100644 dist/core/plugins/skip-buttons.d.ts.map create mode 100644 dist/core/plugins/skip-buttons.js create mode 100644 dist/core/plugins/skip-buttons.js.map create mode 100644 dist/core/token-provider.d.ts create mode 100644 dist/core/token-provider.d.ts.map create mode 100644 dist/core/token-provider.js create mode 100644 dist/core/token-provider.js.map create mode 100644 dist/react/index.d.ts create mode 100644 dist/react/index.d.ts.map create mode 100644 dist/react/index.js create mode 100644 dist/react/index.js.map create mode 100644 dist/react/video-player/components/player-extension/index.d.ts create mode 100644 dist/react/video-player/components/player-extension/index.d.ts.map create mode 100644 dist/react/video-player/components/player-extension/index.js create mode 100644 dist/react/video-player/components/player-extension/index.js.map create mode 100644 dist/react/video-player/components/qr-scanner/index.d.ts create mode 100644 dist/react/video-player/components/qr-scanner/index.d.ts.map create mode 100644 dist/react/video-player/components/qr-scanner/index.js create mode 100644 dist/react/video-player/components/qr-scanner/index.js.map create mode 100644 dist/react/video-player/components/video-js/default.css create mode 100644 dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts create mode 100644 dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts.map create mode 100644 dist/react/video-player/components/video-js/hls-or-videojs-player.js create mode 100644 dist/react/video-player/components/video-js/hls-or-videojs-player.js.map create mode 100644 dist/react/video-player/components/video-js/index.d.ts create mode 100644 dist/react/video-player/components/video-js/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/index.js create mode 100644 dist/react/video-player/components/video-js/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/settings/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/settings/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/settings/settings.css create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/index.js.map create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/skip-backward.svg create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/skip-buttons.css create mode 100644 dist/react/video-player/components/video-js/plugins/skip-buttons/skip-forward.svg create mode 100644 dist/react/video-player/components/video-js/plugins/types/index.d.ts create mode 100644 dist/react/video-player/components/video-js/plugins/types/index.d.ts.map create mode 100644 dist/react/video-player/components/video-js/plugins/types/index.js create mode 100644 dist/react/video-player/components/video-js/plugins/types/index.js.map create mode 100644 dist/react/video-player/components/video-js/types.d.ts create mode 100644 dist/react/video-player/components/video-js/types.d.ts.map create mode 100644 dist/react/video-player/components/video-js/types.js create mode 100644 dist/react/video-player/components/video-js/types.js.map create mode 100644 dist/react/video-player/components/video-js/utils.d.ts create mode 100644 dist/react/video-player/components/video-js/utils.d.ts.map create mode 100644 dist/react/video-player/components/video-js/utils.js create mode 100644 dist/react/video-player/components/video-js/utils.js.map create mode 100644 dist/react/video-player/components/video-js/videojs.module.scss create mode 100644 dist/react/video-player/components/with-blur/index.d.ts create mode 100644 dist/react/video-player/components/with-blur/index.d.ts.map create mode 100644 dist/react/video-player/components/with-blur/index.js create mode 100644 dist/react/video-player/components/with-blur/index.js.map create mode 100644 dist/react/video-player/components/with-blur/with-blur.css create mode 100644 dist/react/video-player/components/with-blur/with-blur.module.scss create mode 100644 dist/react/video-player/components/with-cover/index.d.ts create mode 100644 dist/react/video-player/components/with-cover/index.d.ts.map create mode 100644 dist/react/video-player/components/with-cover/index.js create mode 100644 dist/react/video-player/components/with-cover/index.js.map create mode 100644 dist/react/video-player/components/with-cover/with-cover.module.scss create mode 100644 dist/react/video-player/components/with-duration-badge/index.d.ts create mode 100644 dist/react/video-player/components/with-duration-badge/index.d.ts.map create mode 100644 dist/react/video-player/components/with-duration-badge/index.js create mode 100644 dist/react/video-player/components/with-duration-badge/index.js.map create mode 100644 dist/react/video-player/components/with-duration-badge/with-duration-badge.module.scss create mode 100644 dist/react/video-player/components/with-errors/index.d.ts create mode 100644 dist/react/video-player/components/with-errors/index.d.ts.map create mode 100644 dist/react/video-player/components/with-errors/index.js create mode 100644 dist/react/video-player/components/with-errors/index.js.map create mode 100644 dist/react/video-player/components/with-errors/video-error/index.d.ts create mode 100644 dist/react/video-player/components/with-errors/video-error/index.d.ts.map create mode 100644 dist/react/video-player/components/with-errors/video-error/index.js create mode 100644 dist/react/video-player/components/with-errors/video-error/index.js.map create mode 100644 dist/react/video-player/components/with-errors/video-error/video-error-icon.svg create mode 100644 dist/react/video-player/components/with-errors/video-error/video-error.module.scss create mode 100644 dist/react/video-player/components/with-errors/with-errors.module.scss create mode 100644 dist/react/video-player/components/with-lazy/index.d.ts create mode 100644 dist/react/video-player/components/with-lazy/index.d.ts.map create mode 100644 dist/react/video-player/components/with-lazy/index.js create mode 100644 dist/react/video-player/components/with-lazy/index.js.map create mode 100644 dist/react/video-player/components/with-lazy/with-lazy.module.scss create mode 100644 dist/react/video-player/components/with-loader/index.d.ts create mode 100644 dist/react/video-player/components/with-loader/index.d.ts.map create mode 100644 dist/react/video-player/components/with-loader/index.js create mode 100644 dist/react/video-player/components/with-loader/index.js.map create mode 100644 dist/react/video-player/components/with-loader/with-loader.module.scss create mode 100644 dist/react/video-player/components/with-mouse-events/index.d.ts create mode 100644 dist/react/video-player/components/with-mouse-events/index.d.ts.map create mode 100644 dist/react/video-player/components/with-mouse-events/index.js create mode 100644 dist/react/video-player/components/with-mouse-events/index.js.map create mode 100644 dist/react/video-player/components/with-mouse-events/with-mouse-events.module.scss create mode 100644 dist/react/video-player/components/with-observation/index.d.ts create mode 100644 dist/react/video-player/components/with-observation/index.d.ts.map create mode 100644 dist/react/video-player/components/with-observation/index.js create mode 100644 dist/react/video-player/components/with-observation/index.js.map create mode 100644 dist/react/video-player/components/with-observation/with-observation.module.scss create mode 100644 dist/react/video-player/components/with-processing/index.d.ts create mode 100644 dist/react/video-player/components/with-processing/index.d.ts.map create mode 100644 dist/react/video-player/components/with-processing/index.js create mode 100644 dist/react/video-player/components/with-processing/index.js.map create mode 100644 dist/react/video-player/components/with-processing/video-processing/index.d.ts create mode 100644 dist/react/video-player/components/with-processing/video-processing/index.d.ts.map create mode 100644 dist/react/video-player/components/with-processing/video-processing/index.js create mode 100644 dist/react/video-player/components/with-processing/video-processing/index.js.map create mode 100644 dist/react/video-player/components/with-processing/video-processing/video-processing.module.scss create mode 100644 dist/react/video-player/components/with-processing/with-processing.module.scss create mode 100644 dist/react/video-player/index.d.ts create mode 100644 dist/react/video-player/index.d.ts.map create mode 100644 dist/react/video-player/index.js create mode 100644 dist/react/video-player/index.js.map create mode 100644 dist/react/video-player/shared/math.d.ts create mode 100644 dist/react/video-player/shared/math.d.ts.map create mode 100644 dist/react/video-player/shared/math.js create mode 100644 dist/react/video-player/shared/math.js.map create mode 100644 dist/react/video-player/shared/types.d.ts create mode 100644 dist/react/video-player/shared/types.d.ts.map create mode 100644 dist/react/video-player/shared/types.js create mode 100644 dist/react/video-player/shared/types.js.map create mode 100644 dist/react/video-player/shared/ui/content-skeleton.d.ts create mode 100644 dist/react/video-player/shared/ui/content-skeleton.d.ts.map create mode 100644 dist/react/video-player/shared/ui/content-skeleton.js create mode 100644 dist/react/video-player/shared/ui/content-skeleton.js.map create mode 100644 dist/react/video-player/tach-video-js.css create mode 100644 dist/react/video-player/video-player.d.ts create mode 100644 dist/react/video-player/video-player.d.ts.map create mode 100644 dist/react/video-player/video-player.js create mode 100644 dist/react/video-player/video-player.js.map create mode 100644 dist/react/video-player/video.module.scss create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/build.mjs create mode 100644 src/angular/index.ts create mode 100644 src/core/engine-selector.ts create mode 100644 src/core/format-time.ts create mode 100644 src/core/index.ts create mode 100644 src/core/player-runtime.ts create mode 100644 src/core/plugins/big-play-pause-button.ts create mode 100644 src/core/plugins/register.ts create mode 100644 src/core/plugins/settings/components/tach-video-menu-button/index.ts create mode 100644 src/core/plugins/settings/components/tach-video-menu-item/index.ts create mode 100644 src/core/plugins/settings/components/tach-video-menu/index.ts create mode 100644 src/core/plugins/settings/index.ts create mode 100644 src/core/plugins/settings/selectors/audio-track-selector/index.ts create mode 100644 src/core/plugins/settings/selectors/playback-rate-selector/index.ts create mode 100644 src/core/plugins/settings/selectors/quality-rate-selector/index.ts create mode 100644 src/core/plugins/settings/selectors/text-track-selector/index.ts create mode 100644 src/core/plugins/settings/settings.css create mode 100644 src/core/plugins/settings/types.ts create mode 100644 src/core/plugins/skip-buttons.css create mode 100644 src/core/plugins/skip-buttons.ts create mode 100644 src/core/token-provider.ts create mode 100644 src/react/index.ts create mode 100644 src/react/video-player/components/player-extension/index.tsx create mode 100644 src/react/video-player/components/qr-scanner/index.tsx create mode 100644 src/react/video-player/components/video-js/__tests__/hls-or-videojs-player.test.tsx create mode 100644 src/react/video-player/components/video-js/default.css create mode 100644 src/react/video-player/components/video-js/hls-or-videojs-player.tsx create mode 100644 src/react/video-player/components/video-js/index.tsx create mode 100644 src/react/video-player/components/video-js/plugins/big-play-pause-button/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/components/tach-video-menu/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.ts create mode 100644 src/react/video-player/components/video-js/plugins/settings/settings.css create mode 100644 src/react/video-player/components/video-js/plugins/skip-buttons/index.tsx create mode 100644 src/react/video-player/components/video-js/plugins/skip-buttons/skip-backward.svg create mode 100644 src/react/video-player/components/video-js/plugins/skip-buttons/skip-buttons.css create mode 100644 src/react/video-player/components/video-js/plugins/skip-buttons/skip-forward.svg create mode 100644 src/react/video-player/components/video-js/plugins/types/index.ts create mode 100644 src/react/video-player/components/video-js/types.ts create mode 100644 src/react/video-player/components/video-js/utils.ts create mode 100644 src/react/video-player/components/video-js/videojs.module.scss create mode 100644 src/react/video-player/components/with-blur/index.tsx create mode 100644 src/react/video-player/components/with-blur/with-blur.css create mode 100644 src/react/video-player/components/with-blur/with-blur.module.scss create mode 100644 src/react/video-player/components/with-cover/index.tsx create mode 100644 src/react/video-player/components/with-cover/with-cover.module.scss create mode 100644 src/react/video-player/components/with-duration-badge/index.tsx create mode 100644 src/react/video-player/components/with-duration-badge/with-duration-badge.module.scss create mode 100644 src/react/video-player/components/with-errors/index.tsx create mode 100644 src/react/video-player/components/with-errors/video-error/index.tsx create mode 100644 src/react/video-player/components/with-errors/video-error/video-error-icon.svg create mode 100644 src/react/video-player/components/with-errors/video-error/video-error.module.scss create mode 100644 src/react/video-player/components/with-errors/with-errors.module.scss create mode 100644 src/react/video-player/components/with-lazy/index.tsx create mode 100644 src/react/video-player/components/with-lazy/with-lazy.module.scss create mode 100644 src/react/video-player/components/with-loader/index.tsx create mode 100644 src/react/video-player/components/with-loader/with-loader.module.scss create mode 100644 src/react/video-player/components/with-mouse-events/index.tsx create mode 100644 src/react/video-player/components/with-mouse-events/with-mouse-events.module.scss create mode 100644 src/react/video-player/components/with-observation/index.tsx create mode 100644 src/react/video-player/components/with-observation/with-observation.module.scss create mode 100644 src/react/video-player/components/with-processing/index.tsx create mode 100644 src/react/video-player/components/with-processing/video-processing/index.tsx create mode 100644 src/react/video-player/components/with-processing/video-processing/video-processing.module.scss create mode 100644 src/react/video-player/components/with-processing/with-processing.module.scss create mode 100644 src/react/video-player/index.tsx create mode 100644 src/react/video-player/shared/math.ts create mode 100644 src/react/video-player/shared/types.ts create mode 100644 src/react/video-player/shared/ui/content-skeleton.tsx create mode 100644 src/react/video-player/tach-video-js.css create mode 100644 src/react/video-player/video-player.tsx create mode 100644 src/react/video-player/video.module.scss create mode 100644 src/types/assets.d.ts create mode 100644 src/types/lodash.d.ts create mode 100644 stories/angular-video-player-adapter.stories.tsx create mode 100644 stories/react-video-player.stories.tsx create mode 100644 tsconfig.build.json create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e552ac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +*.log +storybook-static diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..3892a0f --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,15 @@ +import type { StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + stories: ["../stories/**/*.stories.@(ts|tsx)"], + addons: ["@storybook/addon-essentials"], + framework: { + name: "@storybook/react-vite", + options: {}, + }, + docs: { + autodocs: "tag", + }, +}; + +export default config; diff --git a/.storybook/preview.css b/.storybook/preview.css new file mode 100644 index 0000000..3971c64 --- /dev/null +++ b/.storybook/preview.css @@ -0,0 +1,25 @@ +:root { + --Default-BgLight: #ffffff; + --Default-BgDarken: #f2f2f2; + --Default-StrokeDividers: #e0e0e0; + --Default-White: #ffffff; + --Text-Primary: #1d1d1d; + --Controls-Primary: #1d1d1d; + --Controls-Plashes: #f5f5f5; + --Shadow-Z100: 0 10px 24px rgba(20, 20, 20, 0.14); + --Accent-Primary: #5152ba; + --Opacity-BlackOpacity45: rgba(0, 0, 0, 0.45); + --corner-S: 8px; + --corner-M: 12px; + --Corner-XL: 32px; +} + +html, +body, +#storybook-root { + height: 100%; +} + +body { + background: #f6f8fb; +} diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000..e274dba --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,22 @@ +import type { Preview } from "@storybook/react"; + +import "antd/dist/reset.css"; +import "../src/react/video-player/tach-video-js.css"; +import "./preview.css"; + +const preview: Preview = { + parameters: { + layout: "padded", + controls: { + expanded: true, + sort: "requiredFirst", + }, + options: { + storySort: { + order: ["React", "Angular"], + }, + }, + }, +}; + +export default preview; diff --git a/README.md b/README.md index c0f6139..ec54b69 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,193 @@ -# web-video-player +# @tach/video-player +Single package with three entrypoints: + +- `@tach/video-player/core` +- `@tach/video-player/react` +- `@tach/video-player/angular` + +This folder is prepared to be moved into a dedicated repository as-is. + +## What Is Included + +- Build pipeline to `dist/`: + - `npm run build` + - `npm run typecheck` +- Storybook playground for framework entrypoints: + - `npm run storybook` + - `npm run build-storybook` +- `dist`-first flow for git-based installation: + - `dist/` is committed to the repository. + - consumers do not depend on `prepare` at install time. +- Version bump scripts: + - `npm run release:patch` + - `npm run release:minor` + - `npm run release:major` +- Optional framework peers: + - React peers are optional if only `core/angular` is used. + - Angular peers are optional if only `core/react` is used. + +## Repo Transfer Checklist + +1. Create a new repository (for example `tach/video-player`). +2. Copy everything from this folder to the new repo root. +3. In the new repo run: + +```bash +npm install +npm run build +``` + +4. Commit and push (including `dist/`): + +```bash +git add . +git commit -m "feat: initial @tach/video-player package" +git push origin main +``` + +5. Create a release tag: + +```bash +git tag v0.1.0 +git push origin v0.1.0 +``` + +## Build Output + +`npm run build` compiles TypeScript into `dist/` and copies required assets (`css/scss/svg/...`). +`dist/` must be committed before creating a new version tag. + +Entrypoints are exported from `dist`: + +- `@tach/video-player/core` +- `@tach/video-player/react` +- `@tach/video-player/angular` + +## Storybook + +Local Storybook exposes two pages for development and prop testing: + +- `React/VideoPlayer` - React component entrypoint with controls for player props. +- `Angular/VideoPlayerAdapter` - adapter entrypoint with controls for runtime options (`attach/update`). + +Run Storybook: + +```bash +npm run storybook +``` + +Build static Storybook: + +```bash +npm run build-storybook +``` + +## Installation From Git (Without npm Registry) + +### npm + +By tag: + +```bash +npm i git+ssh://git@github.com//video-player.git#v0.1.0 +``` + +By commit: + +```bash +npm i git+ssh://git@github.com//video-player.git# +``` + +By semver tag range: + +```bash +npm i github:/video-player#semver:^0.1.0 +``` + +### pnpm + +```bash +pnpm add git+ssh://git@github.com//video-player.git#v0.1.0 +``` + +### yarn + +```bash +yarn add git+ssh://git@github.com//video-player.git#v0.1.0 +``` + +## Versioning Workflow + +1. Build and bump version: + +```bash +npm run release:patch +# or release:minor / release:major +``` + +2. Commit generated `dist` changes and `package.json` version bump: + +```bash +git add . +git commit -m "chore(release): vX.Y.Z" +``` + +3. Push commit and tags: + +```bash +git push origin main --follow-tags +``` + +4. Consumers update git tag/version in their `package.json`. + +## Why Optional Peers + +Consumers install only the framework they need: + +- React app: install `react` and `react-dom`, use `@tach/video-player/react`. +- Angular app: install `@angular/*`, use `@tach/video-player/angular`. +- Shared utilities only: use `@tach/video-player/core`. + +## Entrypoints + +### Core + +```ts +import { + isHlsSource, + selectPlaybackEngine, + VideoPlayerRuntime, + setVideoPlayerTokenProvider, +} from "@tach/video-player/core"; + +setVideoPlayerTokenProvider(async () => { + // Provide host-app token retrieval here. + return null; +}); + +const runtime = new VideoPlayerRuntime(); +await runtime.init({ + container: document.getElementById("player")!, + source: { src: "https://example.com/video.m3u8" }, +}); +``` + +### React + +```tsx +import VideoPlayer from "@tach/video-player/react"; +``` + +### Angular + +```ts +import { AngularVideoPlayerAdapter } from "@tach/video-player/angular"; + +const adapter = new AngularVideoPlayerAdapter(); +await adapter.attach(containerElement, { + source: { src: "https://example.com/video.m3u8" }, +}); +``` + +`AngularVideoPlayerAdapter` is intentionally framework-light: it wraps `VideoPlayerRuntime` (`attach/update/destroy/on`) and does not depend on React code. diff --git a/dist/angular/index.d.ts b/dist/angular/index.d.ts new file mode 100644 index 0000000..927d83f --- /dev/null +++ b/dist/angular/index.d.ts @@ -0,0 +1,26 @@ +import { type VideoPlayerRuntimeEventMap, type VideoPlayerRuntimeInitOptions, type VideoPlayerRuntimeState, type VideoPlayerRuntimeUnsubscribe, type VideoPlayerRuntimeUpdateOptions } from "../core"; +export interface AngularVideoPlayerInput extends Omit { + source?: VideoPlayerRuntimeInitOptions["source"]; +} +export interface AngularVideoPlayerAttachInput extends Omit { +} +export interface AngularVideoPlayerState { + input: AngularVideoPlayerInput; + runtime: VideoPlayerRuntimeState; +} +export declare class AngularVideoPlayerAdapter { + private readonly runtime; + private input; + attach(container: HTMLElement, input: AngularVideoPlayerAttachInput): Promise<{ + input: AngularVideoPlayerInput; + runtime: VideoPlayerRuntimeState; + }>; + update(nextInput: AngularVideoPlayerInput): Promise<{ + input: AngularVideoPlayerInput; + runtime: VideoPlayerRuntimeState; + }>; + on(event: K, handler: (payload: VideoPlayerRuntimeEventMap[K]) => void): VideoPlayerRuntimeUnsubscribe; + destroy(): void; + getState(): AngularVideoPlayerState; +} +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/angular/index.d.ts.map b/dist/angular/index.d.ts.map new file mode 100644 index 0000000..eea92f6 --- /dev/null +++ b/dist/angular/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EAEpC,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAChB,SAAQ,IAAI,CAAC,+BAA+B,EAAE,QAAQ,CAAC;IACvD,MAAM,CAAC,EAAE,6BAA6B,CAAC,QAAQ,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,6BAChB,SAAQ,IAAI,CAAC,6BAA6B,EAAE,WAAW,CAAC;CAAG;AAE5D,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,uBAAuB,CAAC;IAC/B,OAAO,EAAE,uBAAuB,CAAC;CACjC;AAGD,qBAAa,yBAAyB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,KAAK,CAA+B;IAEtC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,6BAA6B;;;;IAcnE,MAAM,CAAC,SAAS,EAAE,uBAAuB;;;;IAc/C,EAAE,CAAC,CAAC,SAAS,MAAM,0BAA0B,EAC5C,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC,KAAK,IAAI,GACvD,6BAA6B;IAIhC,OAAO;IAIP,QAAQ,IAAI,uBAAuB;CAMnC"} \ No newline at end of file diff --git a/dist/angular/index.js b/dist/angular/index.js new file mode 100644 index 0000000..c19cdb6 --- /dev/null +++ b/dist/angular/index.js @@ -0,0 +1,43 @@ +import { VideoPlayerRuntime, } from "../core"; +// Angular-friendly wrapper around framework-agnostic runtime. +export class AngularVideoPlayerAdapter { + constructor() { + this.runtime = new VideoPlayerRuntime(); + this.input = {}; + } + async attach(container, input) { + this.input = { ...input }; + const runtime = await this.runtime.init({ + container, + ...input, + }); + return { + input: this.input, + runtime, + }; + } + async update(nextInput) { + this.input = { + ...this.input, + ...nextInput, + }; + const runtime = await this.runtime.update(nextInput); + return { + input: this.input, + runtime, + }; + } + on(event, handler) { + return this.runtime.on(event, handler); + } + destroy() { + this.runtime.dispose(); + } + getState() { + return { + input: this.input, + runtime: this.runtime.getState(), + }; + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/angular/index.js.map b/dist/angular/index.js.map new file mode 100644 index 0000000..13408ff --- /dev/null +++ b/dist/angular/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAMN,kBAAkB,GAClB,MAAM,SAAS,CAAC;AAejB,8DAA8D;AAC9D,MAAM,OAAO,yBAAyB;IAAtC;QACkB,YAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAC5C,UAAK,GAA4B,EAAE,CAAC;IA+C7C,CAAC;IA7CA,KAAK,CAAC,MAAM,CAAC,SAAsB,EAAE,KAAoC;QACxE,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;QAE1B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACvC,SAAS;YACT,GAAG,KAAK;SACR,CAAC,CAAC;QAEH,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO;SAC2B,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAkC;QAC9C,IAAI,CAAC,KAAK,GAAG;YACZ,GAAG,IAAI,CAAC,KAAK;YACb,GAAG,SAAS;SACZ,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAErD,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO;SAC2B,CAAC;IACrC,CAAC;IAED,EAAE,CACD,KAAQ,EACR,OAAyD;QAEzD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,OAAO;QACN,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,QAAQ;QACP,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;SAChC,CAAC;IACH,CAAC;CACD"} \ No newline at end of file diff --git a/dist/core/engine-selector.d.ts b/dist/core/engine-selector.d.ts new file mode 100644 index 0000000..c3844a9 --- /dev/null +++ b/dist/core/engine-selector.d.ts @@ -0,0 +1,12 @@ +export type PlaybackEngine = "hls" | "videojs"; +export type EngineStrategy = "auto" | "force-hls" | "force-videojs"; +export interface EngineSelectionInput { + src?: string | null; + type?: string | null; + strategy?: EngineStrategy; + hlsSupported?: boolean; + isIOS?: boolean; +} +export declare const isHlsSource: ({ src, type }: Pick) => boolean; +export declare const selectPlaybackEngine: ({ src, type, strategy, hlsSupported, isIOS, }: EngineSelectionInput) => PlaybackEngine; +//# sourceMappingURL=engine-selector.d.ts.map \ No newline at end of file diff --git a/dist/core/engine-selector.d.ts.map b/dist/core/engine-selector.d.ts.map new file mode 100644 index 0000000..c87ebac --- /dev/null +++ b/dist/core/engine-selector.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"engine-selector.d.ts","sourceRoot":"","sources":["../../src/core/engine-selector.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,WAAW,GAAG,eAAe,CAAC;AAEpE,MAAM,WAAW,oBAAoB;IACpC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAOD,eAAO,MAAM,WAAW,GAAI,eAAe,IAAI,CAAC,oBAAoB,EAAE,KAAK,GAAG,MAAM,CAAC,KAAG,OAIvF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,+CAMlC,oBAAoB,KAAG,cAkBzB,CAAC"} \ No newline at end of file diff --git a/dist/core/engine-selector.js b/dist/core/engine-selector.js new file mode 100644 index 0000000..538b586 --- /dev/null +++ b/dist/core/engine-selector.js @@ -0,0 +1,24 @@ +const HLS_MIME_TYPES = new Set([ + "application/x-mpegurl", + "application/vnd.apple.mpegurl", +]); +export const isHlsSource = ({ src, type }) => { + const sourceType = (type || "").toLowerCase(); + return HLS_MIME_TYPES.has(sourceType) || /\.m3u8($|\?)/i.test(src || ""); +}; +export const selectPlaybackEngine = ({ src, type, strategy = "auto", hlsSupported = false, isIOS = false, }) => { + if (strategy === "force-hls") { + return "hls"; + } + if (strategy === "force-videojs") { + return "videojs"; + } + if (!isHlsSource({ src, type })) { + return "videojs"; + } + if (isIOS) { + return "videojs"; + } + return hlsSupported ? "hls" : "videojs"; +}; +//# sourceMappingURL=engine-selector.js.map \ No newline at end of file diff --git a/dist/core/engine-selector.js.map b/dist/core/engine-selector.js.map new file mode 100644 index 0000000..7340b72 --- /dev/null +++ b/dist/core/engine-selector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"engine-selector.js","sourceRoot":"","sources":["../../src/core/engine-selector.ts"],"names":[],"mappings":"AAYA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC9B,uBAAuB;IACvB,+BAA+B;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAA8C,EAAW,EAAE;IACjG,MAAM,UAAU,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAE9C,OAAO,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EACpC,GAAG,EACH,IAAI,EACJ,QAAQ,GAAG,MAAM,EACjB,YAAY,GAAG,KAAK,EACpB,KAAK,GAAG,KAAK,GACS,EAAkB,EAAE;IAC1C,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACzC,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/core/format-time.d.ts b/dist/core/format-time.d.ts new file mode 100644 index 0000000..2973404 --- /dev/null +++ b/dist/core/format-time.d.ts @@ -0,0 +1,2 @@ +export declare const formatTime: (seconds: number) => string; +//# sourceMappingURL=format-time.d.ts.map \ No newline at end of file diff --git a/dist/core/format-time.d.ts.map b/dist/core/format-time.d.ts.map new file mode 100644 index 0000000..80858f6 --- /dev/null +++ b/dist/core/format-time.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"format-time.d.ts","sourceRoot":"","sources":["../../src/core/format-time.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,WAWzC,CAAC"} \ No newline at end of file diff --git a/dist/core/format-time.js b/dist/core/format-time.js new file mode 100644 index 0000000..bd28de4 --- /dev/null +++ b/dist/core/format-time.js @@ -0,0 +1,11 @@ +export const formatTime = (seconds) => { + const pad = (num) => String(num).padStart(2, "0"); + const hrs = Math.floor(seconds / 3600); + const mins = Math.floor((seconds % 3600) / 60); + const secs = Math.floor(seconds % 60); + if (seconds < 3600) { + return `${pad(mins)}:${pad(secs)}`; + } + return `${pad(hrs)}:${pad(mins)}:${pad(secs)}`; +}; +//# sourceMappingURL=format-time.js.map \ No newline at end of file diff --git a/dist/core/format-time.js.map b/dist/core/format-time.js.map new file mode 100644 index 0000000..19356c6 --- /dev/null +++ b/dist/core/format-time.js.map @@ -0,0 +1 @@ +{"version":3,"file":"format-time.js","sourceRoot":"","sources":["../../src/core/format-time.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE;IAC7C,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEtC,IAAI,OAAO,GAAG,IAAI,EAAE,CAAC;QACpB,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AAChD,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/core/index.d.ts b/dist/core/index.d.ts new file mode 100644 index 0000000..5934616 --- /dev/null +++ b/dist/core/index.d.ts @@ -0,0 +1,4 @@ +export { isHlsSource, selectPlaybackEngine, type EngineSelectionInput, type EngineStrategy, type PlaybackEngine, } from "./engine-selector"; +export { resolveVideoPlayerToken, setVideoPlayerTokenProvider, type VideoPlayerToken, type VideoPlayerTokenProvider, } from "./token-provider"; +export { VideoPlayerRuntime, type VideoPlayerRuntimeEventMap, type VideoPlayerRuntimeInitOptions, type VideoPlayerRuntimePlayer, type VideoPlayerRuntimePreload, type VideoPlayerRuntimeSource, type VideoPlayerRuntimeState, type VideoPlayerRuntimeUnsubscribe, type VideoPlayerRuntimeUpdateOptions, } from "./player-runtime"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/index.d.ts.map b/dist/core/index.d.ts.map new file mode 100644 index 0000000..64f83f6 --- /dev/null +++ b/dist/core/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,cAAc,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,GACpC,MAAM,kBAAkB,CAAC"} \ No newline at end of file diff --git a/dist/core/index.js b/dist/core/index.js new file mode 100644 index 0000000..fab4cb4 --- /dev/null +++ b/dist/core/index.js @@ -0,0 +1,4 @@ +export { isHlsSource, selectPlaybackEngine, } from "./engine-selector"; +export { resolveVideoPlayerToken, setVideoPlayerTokenProvider, } from "./token-provider"; +export { VideoPlayerRuntime, } from "./player-runtime"; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/index.js.map b/dist/core/index.js.map new file mode 100644 index 0000000..58b4b47 --- /dev/null +++ b/dist/core/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,oBAAoB,GAIpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,uBAAuB,EACvB,2BAA2B,GAG3B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,kBAAkB,GASlB,MAAM,kBAAkB,CAAC"} \ No newline at end of file diff --git a/dist/core/player-runtime.d.ts b/dist/core/player-runtime.d.ts new file mode 100644 index 0000000..928d1bb --- /dev/null +++ b/dist/core/player-runtime.d.ts @@ -0,0 +1,137 @@ +import Hls from "hls.js"; +import type Player from "video.js/dist/types/player"; +import "./plugins/register"; +import { type EngineStrategy, type PlaybackEngine } from "./engine-selector"; +export interface VideoPlayerRuntimeSource { + src: string; + type?: string; +} +export type VideoPlayerRuntimePreload = "auto" | "metadata" | "none" | "visibility"; +export type VideoPlayerRuntimeEventMap = { + ready: { + engine: PlaybackEngine; + source: VideoPlayerRuntimeSource; + player: VideoPlayerRuntimePlayer; + }; + enginechange: { + previous: PlaybackEngine | null; + next: PlaybackEngine; + source: VideoPlayerRuntimeSource; + }; + sourcechange: { + previous: VideoPlayerRuntimeSource; + next: VideoPlayerRuntimeSource; + engine: PlaybackEngine; + }; + manifestloaded: { + engine: PlaybackEngine; + duration?: number; + live?: boolean; + }; + duration: { + duration: number; + }; + playstart: { + engine: PlaybackEngine; + }; + error: { + scope: "runtime" | "player" | "hls"; + error: unknown; + fatal?: boolean; + }; + dispose: Record; +}; +export type VideoPlayerRuntimePlayer = Player & { + hlsInstance?: Hls | null; + liveTracker?: { + isLive_: boolean; + atLiveEdge?: () => boolean; + startTracking: () => void; + trigger: (event: string) => void; + }; + settingsMenu?: () => void; + bigPlayPauseButton?: () => void; + skipButtons?: (options: { + skip: number; + }) => void; + subscribeToSegmentChange: (callback: (segment: unknown) => void) => void; + subscribeToDuration: (callback: (duration: number) => void) => void; + subscribeToPlayStart: (callback: () => void) => void; + subscribeToPlayStarted: (callback: () => void) => void; + subscribeToManifestLoaded: (callback: () => void) => void; + mediaduration: () => number | undefined; +}; +interface VideoPlayerRuntimeOptions { + source: VideoPlayerRuntimeSource; + strategy: EngineStrategy; + preload: VideoPlayerRuntimePreload; + autoplay: boolean; + controls: boolean; + responsive: boolean; + aspectRatio?: string; + fluid: boolean; + muted: boolean; + poster?: string; + preferHQ: boolean; + debug: boolean; + initialTime: number; + isIOS?: boolean; + isMobile?: boolean; + full: boolean; + withRewind: boolean; + skipSeconds: number; + classNames: string[]; + onPlayerReady?: (player: VideoPlayerRuntimePlayer, state: VideoPlayerRuntimeState) => void; +} +export interface VideoPlayerRuntimeInitOptions extends Partial> { + container: HTMLElement; + source: VideoPlayerRuntimeSource; +} +export interface VideoPlayerRuntimeUpdateOptions extends Partial> { + source?: VideoPlayerRuntimeSource; +} +export interface VideoPlayerRuntimeState { + initialized: boolean; + engine: PlaybackEngine | null; + source: VideoPlayerRuntimeSource | null; +} +export type VideoPlayerRuntimeUnsubscribe = () => void; +export declare class VideoPlayerRuntime { + private containerRef; + private videoRef; + private playerRef; + private hlsRef; + private options; + private currentEngine; + private currentSource; + private vhsAuthTokenRef; + private vhsRequestCleanupRef; + private visibilityObserverRef; + private originalPlayRef; + private hlsLoaded; + private eventListeners; + init(options: VideoPlayerRuntimeInitOptions): Promise; + update(options: VideoPlayerRuntimeUpdateOptions): Promise; + on(event: K, handler: (payload: VideoPlayerRuntimeEventMap[K]) => void): VideoPlayerRuntimeUnsubscribe; + dispose(): void; + getState(): VideoPlayerRuntimeState; + getPlayer(): VideoPlayerRuntimePlayer | null; + private emit; + private tryPlay; + private resolveEngine; + private createVideoElement; + private createPlayer; + private syncPoster; + private syncPlayerDisplayOptions; + private attachCompatibilityApi; + private attachDurationAndPlayStartHooks; + private loadCurrentSource; + private buildHlsConfig; + private loadHlsSource; + private loadVideoJsSource; + private resetDeferredHlsLoading; + private ensureVhsAuthInterceptor; + private teardownHls; +} +export {}; +//# sourceMappingURL=player-runtime.d.ts.map \ No newline at end of file diff --git a/dist/core/player-runtime.d.ts.map b/dist/core/player-runtime.d.ts.map new file mode 100644 index 0000000..93c6002 --- /dev/null +++ b/dist/core/player-runtime.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"player-runtime.d.ts","sourceRoot":"","sources":["../../src/core/player-runtime.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/player-runtime.js b/dist/core/player-runtime.js new file mode 100644 index 0000000..ff79ca7 --- /dev/null +++ b/dist/core/player-runtime.js @@ -0,0 +1,707 @@ +import Hls from "hls.js"; +import videojs from "video.js"; +import "./plugins/register"; +import { selectPlaybackEngine, } from "./engine-selector"; +import { formatTime } from "./format-time"; +import { resolveVideoPlayerToken } from "./token-provider"; +const DEFAULT_SOURCE_TYPE = "application/x-mpegurl"; +const detectIOS = () => { + if (typeof navigator === "undefined") { + return false; + } + const userAgent = navigator.userAgent || ""; + return /iPad|iPhone|iPod/.test(userAgent); +}; +const createAuthPlaylistLoader = ({ debug, }) => { + const BaseLoader = Hls.DefaultConfig.loader; + return class AuthPlaylistLoader extends BaseLoader { + constructor(config) { + super({ ...config, debug: debug ?? false }); + } + load(context, config, callbacks) { + const start = async () => { + try { + const token = await resolveVideoPlayerToken(); + if (token) { + context.headers = { + ...(context.headers ?? {}), + Authorization: `Bearer ${token}`, + }; + } + } + catch (error) { + if (debug) { + console.warn("[VideoRuntime:HLS] Failed to append auth header to playlist request", error); + } + } + finally { + super.load(context, config, callbacks); + } + }; + void start().catch(error => { + if (debug) { + console.error("[VideoRuntime:HLS] Playlist loader start failed", error); + } + }); + } + }; +}; +const normalizeSource = (source) => ({ + src: source?.src ?? "", + type: source?.type ?? DEFAULT_SOURCE_TYPE, +}); +const normalizeOptions = (options, previous) => ({ + source: normalizeSource(options.source ?? previous?.source), + strategy: options.strategy ?? previous?.strategy ?? "auto", + preload: options.preload ?? previous?.preload ?? "auto", + autoplay: options.autoplay ?? previous?.autoplay ?? false, + controls: options.controls ?? previous?.controls ?? true, + responsive: options.responsive ?? previous?.responsive ?? true, + aspectRatio: options.aspectRatio ?? previous?.aspectRatio, + fluid: options.fluid ?? previous?.fluid ?? true, + muted: options.muted ?? previous?.muted ?? false, + poster: options.poster ?? previous?.poster, + preferHQ: options.preferHQ ?? previous?.preferHQ ?? false, + debug: options.debug ?? previous?.debug ?? false, + initialTime: options.initialTime ?? previous?.initialTime ?? 0, + isIOS: options.isIOS ?? previous?.isIOS, + isMobile: options.isMobile ?? previous?.isMobile, + full: options.full ?? previous?.full ?? false, + withRewind: options.withRewind ?? previous?.withRewind ?? true, + skipSeconds: options.skipSeconds ?? previous?.skipSeconds ?? 10, + classNames: options.classNames ?? previous?.classNames ?? [], + onPlayerReady: options.onPlayerReady ?? previous?.onPlayerReady, +}); +export class VideoPlayerRuntime { + constructor() { + this.containerRef = null; + this.videoRef = null; + this.playerRef = null; + this.hlsRef = null; + this.options = null; + this.currentEngine = null; + this.currentSource = null; + this.vhsAuthTokenRef = null; + this.vhsRequestCleanupRef = null; + this.visibilityObserverRef = null; + this.originalPlayRef = null; + this.hlsLoaded = false; + this.eventListeners = new Map(); + } + async init(options) { + this.dispose(); + this.containerRef = options.container; + this.options = normalizeOptions(options); + this.createVideoElement(); + this.createPlayer(); + const state = await this.loadCurrentSource(null); + this.emit("ready", { + engine: state.engine, + source: state.source, + player: this.playerRef, + }); + this.options.onPlayerReady?.(this.playerRef, state); + return state; + } + async update(options) { + if (!this.options || !this.playerRef) { + return this.getState(); + } + const previous = this.options; + const nextOptions = normalizeOptions(options, previous); + this.options = nextOptions; + this.syncPlayerDisplayOptions(previous, nextOptions); + const sourceChanged = nextOptions.source.src !== previous.source.src || + nextOptions.source.type !== previous.source.type; + const engineDependsOnChanged = nextOptions.strategy !== previous.strategy || + nextOptions.isIOS !== previous.isIOS; + if (sourceChanged || engineDependsOnChanged) { + if (sourceChanged) { + this.emit("sourcechange", { + previous: previous.source, + next: nextOptions.source, + engine: this.currentEngine, + }); + } + return this.loadCurrentSource(this.currentEngine); + } + if (nextOptions.poster !== previous.poster) { + this.syncPoster(nextOptions.poster); + } + return this.getState(); + } + on(event, handler) { + if (!this.eventListeners.has(event)) { + this.eventListeners.set(event, new Set()); + } + const listeners = this.eventListeners.get(event); + listeners.add(handler); + return () => { + listeners.delete(handler); + }; + } + dispose() { + this.emit("dispose", {}); + this.resetDeferredHlsLoading(); + this.teardownHls(); + this.vhsRequestCleanupRef?.(); + this.vhsRequestCleanupRef = null; + this.vhsAuthTokenRef = null; + if (this.playerRef) { + this.playerRef.dispose(); + } + if (this.containerRef) { + this.containerRef.innerHTML = ""; + } + this.containerRef = null; + this.videoRef = null; + this.playerRef = null; + this.options = null; + this.currentEngine = null; + this.currentSource = null; + this.hlsLoaded = false; + } + getState() { + return { + initialized: Boolean(this.playerRef), + engine: this.currentEngine, + source: this.currentSource, + }; + } + getPlayer() { + return this.playerRef; + } + emit(event, payload) { + const listeners = this.eventListeners.get(event); + if (!listeners?.size) { + return; + } + listeners.forEach(listener => { + try { + listener(payload); + } + catch (error) { + console.error("[VideoRuntime] Listener failed", { + event, + error, + }); + } + }); + } + tryPlay(player) { + const playResult = player.play(); + if (playResult && typeof playResult.catch === "function") { + void playResult.catch(() => undefined); + } + } + resolveEngine(options) { + return selectPlaybackEngine({ + src: options.source.src, + type: options.source.type, + strategy: options.strategy, + hlsSupported: Hls.isSupported(), + isIOS: options.isIOS ?? detectIOS(), + }); + } + createVideoElement() { + if (!this.containerRef || !this.options) { + return; + } + const videoElement = document.createElement("video"); + videoElement.classList.add("video-js", "vjs-tach-skin"); + if (this.options.isMobile) { + videoElement.classList.add("vjs-mobile-ui"); + } + if (!this.options.withRewind) { + videoElement.classList.add("vjs-disable-rewind"); + } + videoElement.setAttribute("playsinline", "true"); + if (this.options.poster) { + videoElement.setAttribute("poster", this.options.poster); + } + this.options.classNames.forEach(className => { + videoElement.classList.add(className); + }); + this.containerRef.innerHTML = ""; + this.containerRef.appendChild(videoElement); + this.videoRef = videoElement; + } + createPlayer() { + if (!this.videoRef || !this.options) { + throw new Error("[VideoRuntime] Unable to create player without video element"); + } + const videoJsAny = videojs; + videoJsAny.formatTime = formatTime; + videoJsAny.setFormatTime?.(formatTime); + const player = (this.playerRef = videojs(this.videoRef, { + autoplay: this.options.autoplay, + controls: this.options.controls, + preload: this.options.preload === "visibility" ? "none" : this.options.preload, + fluid: this.options.fluid, + responsive: this.options.responsive, + aspectRatio: this.options.aspectRatio, + muted: this.options.muted, + })); + this.attachCompatibilityApi(player); + player.on("error", () => { + this.emit("error", { + scope: "player", + error: player.error?.() ?? new Error("Unknown player error"), + }); + }); + player.bigPlayPauseButton?.(); + if (this.options.full) { + player.settingsMenu?.(); + player.skipButtons?.({ skip: this.options.skipSeconds }); + } + } + syncPoster(poster) { + const videoElement = this.videoRef; + if (!videoElement) { + return; + } + if (poster) { + videoElement.setAttribute("poster", poster); + } + else { + videoElement.removeAttribute("poster"); + } + } + syncPlayerDisplayOptions(previous, next) { + const player = this.playerRef; + if (!player) { + return; + } + if (previous.muted !== next.muted) { + player.muted(next.muted); + } + if (previous.controls !== next.controls) { + player.controls(next.controls); + } + if (!previous.full && next.full) { + player.settingsMenu?.(); + player.skipButtons?.({ skip: next.skipSeconds }); + } + if (previous.initialTime !== next.initialTime && next.initialTime > 0) { + if (this.hlsRef) { + this.hlsRef.startLoad(next.initialTime); + } + player.currentTime(next.initialTime); + } + if (!previous.autoplay && next.autoplay && player.paused()) { + this.tryPlay(player); + } + } + attachCompatibilityApi(player) { + player.subscribeToSegmentChange = callback => { + let lastIndex = -1; + if (this.hlsRef) { + this.hlsRef.on(Hls.Events.FRAG_CHANGED, (_event, data) => { + callback(data.frag); + }); + return; + } + player.on("timeupdate", () => { + const seconds = Math.floor(player.currentTime() || 0); + const segmentIndex = Math.floor(seconds / 10); + if (segmentIndex > lastIndex) { + lastIndex = segmentIndex; + callback({ start: segmentIndex * 10 }); + } + }); + }; + player.mediaduration = () => { + if (this.hlsRef) { + const level = this.hlsRef.levels[this.hlsRef.currentLevel]; + const details = level?.details; + if (details?.totalduration) { + return details.totalduration; + } + } + return player.duration(); + }; + player.subscribeToDuration = callback => { + const fire = (duration) => { + if (duration && !Number.isNaN(duration) && duration > 0) { + callback(duration); + } + }; + fire(player.duration()); + if (this.hlsRef) { + this.hlsRef.on(Hls.Events.MANIFEST_PARSED, () => { + const totalDuration = this.hlsRef?.levels[0]?.details?.totalduration; + if (totalDuration) { + fire(totalDuration); + } + }); + } + player.on("loadedmetadata", () => fire(player.mediaduration())); + }; + player.subscribeToPlayStart = callback => { + let started = false; + const onPlayStart = () => { + if (!started) { + started = true; + callback(); + } + }; + if (this.hlsRef) { + this.hlsRef.once(Hls.Events.FRAG_BUFFERED, onPlayStart); + } + player.one("playing", onPlayStart); + }; + player.subscribeToPlayStarted = callback => { + let started = false; + const onPlayStarted = () => { + if (!started) { + started = true; + callback(); + } + }; + player.one("playing", onPlayStarted); + }; + player.subscribeToManifestLoaded = callback => { + if (this.hlsRef) { + this.hlsRef.once(Hls.Events.MANIFEST_PARSED, () => callback()); + return; + } + player.one("loadedmetadata", () => callback()); + }; + } + attachDurationAndPlayStartHooks() { + const player = this.playerRef; + if (!player) { + return; + } + player.one("playing", () => { + this.emit("playstart", { + engine: this.currentEngine, + }); + }); + player.one("loadedmetadata", () => { + const duration = player.duration(); + if (typeof duration === "number" && !Number.isNaN(duration)) { + this.emit("duration", { duration }); + } + }); + } + async loadCurrentSource(previousEngine) { + if (!this.options || !this.playerRef || !this.videoRef) { + return this.getState(); + } + const nextEngine = this.resolveEngine(this.options); + const source = this.options.source; + if (previousEngine !== nextEngine || this.currentEngine !== nextEngine) { + this.emit("enginechange", { + previous: this.currentEngine, + next: nextEngine, + source, + }); + } + this.currentEngine = nextEngine; + this.currentSource = source; + if (nextEngine === "hls") { + await this.loadHlsSource(); + } + else { + await this.loadVideoJsSource(); + } + this.attachDurationAndPlayStartHooks(); + return this.getState(); + } + buildHlsConfig(overrides = {}) { + const options = this.options; + if (!options) { + return overrides; + } + const preferHqSettings = options.preferHQ + ? { abrEwmaDefaultEstimate: 10690560 * 1.2 } + : {}; + const playlistLoader = createAuthPlaylistLoader({ debug: options.debug }); + return { + debug: options.debug, + enableWorker: true, + fragLoadingMaxRetry: 2, + manifestLoadingMaxRetry: 2, + fragLoadingRetryDelay: 2000, + manifestLoadingRetryDelay: 2000, + forceKeyFrameOnDiscontinuity: true, + backBufferLength: 90, + appendErrorMaxRetry: 3, + startPosition: options.initialTime > 0 ? options.initialTime : -1, + testBandwidth: false, + lowLatencyMode: false, + liveSyncDurationCount: 2, + maxBufferHole: 10, + nudgeOffset: 0.1, + nudgeMaxRetry: 5, + highBufferWatchdogPeriod: 2, + ...preferHqSettings, + ...overrides, + pLoader: playlistLoader, + }; + } + async loadHlsSource() { + const options = this.options; + const player = this.playerRef; + const video = this.videoRef; + if (!options || !player || !video) { + return; + } + this.resetDeferredHlsLoading(); + this.teardownHls(); + player.pause(); + this.hlsLoaded = false; + if (!Hls.isSupported()) { + await this.loadVideoJsSource(); + return; + } + const setupHls = () => { + if (this.hlsLoaded) { + return; + } + this.hlsLoaded = true; + const hls = new Hls(this.buildHlsConfig()); + this.hlsRef = hls; + player.hlsInstance = hls; + let recoveryAttempts = 0; + const MAX_RECOVERY_ATTEMPTS = 10; + let lastErrorTime = 0; + const ERROR_RESET_TIME = 10000; + let lastSegmentIndex = -1; + const isAtLiveEdge = () => { + if (!hls.liveSyncPosition || !video.duration) { + return false; + } + return hls.liveSyncPosition - video.currentTime < 10; + }; + hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => { + const details = data.levels?.[0]?.details; + this.emit("manifestloaded", { + engine: "hls", + duration: details?.totalduration, + live: details?.live, + }); + if (details?.live) { + video.parentElement?.classList.add("vjs-hls-live", "vjs-live"); + player.duration(Infinity); + if (player.liveTracker) { + player.liveTracker.isLive_ = true; + player.liveTracker.startTracking(); + player.liveTracker.trigger("durationchange"); + } + } + if (options.initialTime > 0) { + hls.startLoad(options.initialTime); + } + }); + hls.on(Hls.Events.FRAG_CHANGED, () => { + if (player.liveTracker) { + player.liveTracker.atLiveEdge = isAtLiveEdge; + player.liveTracker.trigger("liveedgechange"); + } + }); + hls.on(Hls.Events.ERROR, (_event, data) => { + this.emit("error", { + scope: "hls", + error: data, + fatal: data.fatal, + }); + if (!data.fatal) { + return; + } + const now = Date.now(); + if (now - lastErrorTime > ERROR_RESET_TIME) { + recoveryAttempts = 0; + lastSegmentIndex = -1; + } + lastErrorTime = now; + if (recoveryAttempts >= MAX_RECOVERY_ATTEMPTS) { + return; + } + recoveryAttempts += 1; + switch (data.type) { + case Hls.ErrorTypes.NETWORK_ERROR: + setTimeout(() => hls.startLoad(), 1000); + break; + case Hls.ErrorTypes.MEDIA_ERROR: { + const currentLevel = hls.currentLevel; + const details = hls.levels[currentLevel]?.details; + if (details?.fragments?.length) { + if (lastSegmentIndex === -1) { + lastSegmentIndex = details.startSN; + } + lastSegmentIndex += 1; + if (lastSegmentIndex < details.endSN) { + const fragment = details.fragments[lastSegmentIndex - details.startSN]; + if (fragment) { + const savedTime = fragment.start; + video.currentTime = savedTime; + setTimeout(() => { + if (Math.abs(video.currentTime - savedTime) > 0.1) { + video.currentTime = savedTime; + } + hls.recoverMediaError(); + if (!video.paused && options.autoplay) { + void video.play().catch(() => undefined); + } + }, 100); + break; + } + } + else { + recoveryAttempts = MAX_RECOVERY_ATTEMPTS; + break; + } + } + setTimeout(() => hls.recoverMediaError(), 1000); + break; + } + default: + setTimeout(() => { + this.teardownHls(); + this.hlsLoaded = false; + setupHls(); + }, 2000); + } + }); + hls.loadSource(options.source.src); + hls.attachMedia(video); + if (options.autoplay && options.preload !== "none") { + this.tryPlay(player); + } + }; + switch (options.preload) { + case "none": + this.originalPlayRef = player.play.bind(player); + player.play = (...args) => { + setupHls(); + return this.originalPlayRef(...args); + }; + break; + case "metadata": { + const hls = new Hls(this.buildHlsConfig({ + autoStartLoad: false, + })); + this.hlsLoaded = true; + this.hlsRef = hls; + player.hlsInstance = hls; + hls.attachMedia(video); + hls.loadSource(options.source.src); + break; + } + case "visibility": + if (typeof IntersectionObserver !== "undefined" && this.containerRef) { + this.visibilityObserverRef = new IntersectionObserver(entries => { + if (entries[0]?.isIntersecting) { + setupHls(); + this.visibilityObserverRef?.disconnect(); + this.visibilityObserverRef = null; + } + }, { threshold: 0.25 }); + this.visibilityObserverRef.observe(this.containerRef); + } + else { + setupHls(); + } + break; + default: + setupHls(); + } + } + async loadVideoJsSource() { + const options = this.options; + const player = this.playerRef; + if (!options || !player) { + return; + } + player.pause(); + this.resetDeferredHlsLoading(); + this.teardownHls(); + try { + const token = await resolveVideoPlayerToken(); + this.vhsAuthTokenRef = token; + this.ensureVhsAuthInterceptor(player); + } + catch (error) { + this.emit("error", { + scope: "runtime", + error, + }); + } + player.src([ + { + src: options.source.src, + type: options.source.type ?? DEFAULT_SOURCE_TYPE, + }, + ]); + if (options.initialTime > 0) { + player.one("loadedmetadata", () => { + player.currentTime(options.initialTime); + }); + } + if (options.autoplay) { + this.tryPlay(player); + } + } + resetDeferredHlsLoading() { + if (this.visibilityObserverRef) { + this.visibilityObserverRef.disconnect(); + this.visibilityObserverRef = null; + } + if (this.originalPlayRef && this.playerRef) { + this.playerRef.play = this.originalPlayRef; + this.originalPlayRef = null; + } + } + ensureVhsAuthInterceptor(player) { + if (this.vhsRequestCleanupRef) { + return; + } + const videojsAny = videojs; + const xhr = videojsAny?.Vhs?.xhr ?? videojsAny?.Hls?.xhr; + if (!xhr) { + return; + } + const originalBeforeRequest = xhr.beforeRequest; + xhr.beforeRequest = (requestOptions) => { + const processedOptions = originalBeforeRequest?.call(xhr, requestOptions) ?? requestOptions; + if (this.vhsAuthTokenRef) { + processedOptions.headers = { + ...(processedOptions.headers ?? {}), + Authorization: `Bearer ${this.vhsAuthTokenRef}`, + }; + } + return processedOptions; + }; + this.vhsRequestCleanupRef = () => { + xhr.beforeRequest = originalBeforeRequest; + }; + player.one("dispose", () => { + this.vhsRequestCleanupRef?.(); + this.vhsRequestCleanupRef = null; + }); + } + teardownHls() { + if (!this.hlsRef) { + return; + } + this.hlsRef.stopLoad(); + this.hlsRef.detachMedia(); + this.hlsRef.destroy(); + this.hlsRef = null; + this.hlsLoaded = false; + if (this.playerRef) { + this.playerRef.hlsInstance = null; + const videoElement = this.playerRef + .el() + ?.querySelector("video"); + videoElement?.parentElement?.classList.remove("vjs-hls-live", "vjs-live"); + if (this.playerRef.liveTracker) { + this.playerRef.liveTracker.isLive_ = false; + this.playerRef.liveTracker.trigger("durationchange"); + } + } + } +} +//# sourceMappingURL=player-runtime.js.map \ No newline at end of file diff --git a/dist/core/player-runtime.js.map b/dist/core/player-runtime.js.map new file mode 100644 index 0000000..456c9f9 --- /dev/null +++ b/dist/core/player-runtime.js.map @@ -0,0 +1 @@ +{"version":3,"file":"player-runtime.js","sourceRoot":"","sources":["../../src/core/player-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,GAON,MAAM,QAAQ,CAAC;AAChB,OAAO,OAAO,MAAM,UAAU,CAAC;AAG/B,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAGN,oBAAoB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAgH3D,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAEpD,MAAM,SAAS,GAAG,GAAG,EAAE;IACtB,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC;IAE5C,OAAO,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,EACjC,KAAK,GAGL,EAA6B,EAAE;IAC/B,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,CAAC,MAEH,CAAC;IAEnC,OAAO,MAAM,kBAAmB,SAAQ,UAAU;QACjD,YAAY,MAAiB;YAC5B,KAAK,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CACH,OAA8B,EAC9B,MAA2B,EAC3B,SAAiD;YAEjD,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;gBACxB,IAAI,CAAC;oBACJ,MAAM,KAAK,GAAG,MAAM,uBAAuB,EAAE,CAAC;oBAC9C,IAAI,KAAK,EAAE,CAAC;wBACX,OAAO,CAAC,OAAO,GAAG;4BACjB,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;4BAC1B,aAAa,EAAE,UAAU,KAAK,EAAE;yBAChC,CAAC;oBACH,CAAC;gBACF,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,KAAK,EAAE,CAAC;wBACX,OAAO,CAAC,IAAI,CACX,qEAAqE,EACrE,KAAK,CACL,CAAC;oBACH,CAAC;gBACF,CAAC;wBAAS,CAAC;oBACV,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;gBACxC,CAAC;YACF,CAAC,CAAC;YAEF,KAAK,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBAC1B,IAAI,KAAK,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;gBACzE,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;KACD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CACvB,MAAwC,EACb,EAAE,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE;IACtB,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,mBAAmB;CACzC,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CACxB,OAAwE,EACxE,QAAoC,EACR,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM,CAAC;IAC3D,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,MAAM;IAC1D,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,IAAI,MAAM;IACvD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,KAAK;IACzD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,IAAI;IACxD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ,EAAE,UAAU,IAAI,IAAI;IAC9D,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ,EAAE,WAAW;IACzD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,IAAI;IAC/C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,KAAK;IAChD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM;IAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,KAAK;IACzD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,KAAK;IAChD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ,EAAE,WAAW,IAAI,CAAC;IAC9D,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK;IACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ;IAChD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,KAAK;IAC7C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ,EAAE,UAAU,IAAI,IAAI;IAC9D,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,QAAQ,EAAE,WAAW,IAAI,EAAE;IAC/D,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ,EAAE,UAAU,IAAI,EAAE;IAC5D,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,QAAQ,EAAE,aAAa;CAC/D,CAAC,CAAC;AAEH,MAAM,OAAO,kBAAkB;IAA/B;QACS,iBAAY,GAAuB,IAAI,CAAC;QACxC,aAAQ,GAA4B,IAAI,CAAC;QACzC,cAAS,GAAoC,IAAI,CAAC;QAClD,WAAM,GAAe,IAAI,CAAC;QAC1B,YAAO,GAAqC,IAAI,CAAC;QACjD,kBAAa,GAA0B,IAAI,CAAC;QAC5C,kBAAa,GAAoC,IAAI,CAAC;QACtD,oBAAe,GAA8B,IAAI,CAAC;QAClD,yBAAoB,GAAwB,IAAI,CAAC;QACjD,0BAAqB,GAAgC,IAAI,CAAC;QAC1D,oBAAe,GAA4C,IAAI,CAAC;QAChE,cAAS,GAAG,KAAK,CAAC;QAClB,mBAAc,GAAG,IAAI,GAAG,EAG7B,CAAC;IA6vBL,CAAC;IA3vBA,KAAK,CAAC,IAAI,CAAC,OAAsC;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAClB,MAAM,EAAE,KAAK,CAAC,MAAwB;YACtC,MAAM,EAAE,KAAK,CAAC,MAAkC;YAChD,MAAM,EAAE,IAAI,CAAC,SAAqC;SAClD,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAC3B,IAAI,CAAC,SAAqC,EAC1C,KAAK,CACL,CAAC;QAEF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAwC;QACpD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9B,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;QAE3B,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAErD,MAAM,aAAa,GAClB,WAAW,CAAC,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,MAAM,CAAC,GAAG;YAC9C,WAAW,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;QAClD,MAAM,sBAAsB,GAC3B,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;YAC1C,WAAW,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC;QAEtC,IAAI,aAAa,IAAI,sBAAsB,EAAE,CAAC;YAC7C,IAAI,aAAa,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;oBACzB,QAAQ,EAAE,QAAQ,CAAC,MAAM;oBACzB,IAAI,EAAE,WAAW,CAAC,MAAM;oBACxB,MAAM,EAAE,IAAI,CAAC,aAA+B;iBAC5C,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,EAAE,CACD,KAAQ,EACR,OAAyD;QAEzD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAE9C,CAAC;QACF,SAAS,CAAC,GAAG,CAAC,OAAqC,CAAC,CAAC;QAErD,OAAO,GAAG,EAAE;YACX,SAAS,CAAC,MAAM,CAAC,OAAqC,CAAC,CAAC;QACzD,CAAC,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEzB,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,QAAQ;QACP,OAAO;YACN,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YACpC,MAAM,EAAE,IAAI,CAAC,aAAa;YAC1B,MAAM,EAAE,IAAI,CAAC,aAAa;SAC1B,CAAC;IACH,CAAC;IAED,SAAS;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAEO,IAAI,CACX,KAAQ,EACR,OAAsC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAC5B,IAAI,CAAC;gBACH,QAA6D,CAAC,OAAO,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE;oBAC/C,KAAK;oBACL,KAAK;iBACL,CAAC,CAAC;YACJ,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,OAAO,CAAC,MAAgC;QAC/C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,UAAU,IAAI,OAAQ,UAA4B,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC7E,KAAM,UAA4B,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAEO,aAAa,CAAC,OAAkC;QACvD,OAAO,oBAAoB,CAAC;YAC3B,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;YACvB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE;YAC/B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS,EAAE;SACnC,CAAC,CAAC;IACJ,CAAC;IAEO,kBAAkB;QACzB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACzC,OAAO;QACR,CAAC;QAED,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACrD,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACxD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC3B,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9B,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClD,CAAC;QACD,YAAY,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACzB,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC3C,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,EAAE,CAAC;QACjC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC;IAC9B,CAAC;IAEO,YAAY;QACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,UAAU,GAAG,OAGlB,CAAC;QACF,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,UAAU,CAAC,aAAa,EAAE,CAAC,UAAU,CAAC,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE;YACvD,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,OAAO,EACN,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;YACtE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YACnC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACrC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;SACzB,CAA6B,CAAC,CAAC;QAEhC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAEpC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;gBAClB,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,IAAI,KAAK,CAAC,sBAAsB,CAAC;aAC5D,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;YACxB,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;IACF,CAAC;IAEO,UAAU,CAAC,MAAe;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,YAAY,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACZ,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAEO,wBAAwB,CAC/B,QAAmC,EACnC,IAA+B;QAE/B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACzC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC;YACxB,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACvE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACF,CAAC;IAEO,sBAAsB,CAAC,MAAgC;QAC9D,MAAM,CAAC,wBAAwB,GAAG,QAAQ,CAAC,EAAE;YAC5C,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;YACnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;oBACxD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;gBACH,OAAO;YACR,CAAC;YAED,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;gBACtD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;gBAC9C,IAAI,YAAY,GAAG,SAAS,EAAE,CAAC;oBAC9B,SAAS,GAAG,YAAY,CAAC;oBACzB,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC;gBACxC,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE;YAC3B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,CAAC;gBAC/B,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;oBAC5B,OAAO,OAAO,CAAC,aAAa,CAAC;gBAC9B,CAAC;YACF,CAAC;YAED,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEF,MAAM,CAAC,mBAAmB,GAAG,QAAQ,CAAC,EAAE;YACvC,MAAM,IAAI,GAAG,CAAC,QAAiB,EAAE,EAAE;gBAClC,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;oBACzD,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YAExB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE;oBAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC;oBACrE,IAAI,aAAa,EAAE,CAAC;wBACnB,IAAI,CAAC,aAAa,CAAC,CAAC;oBACrB,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;YAED,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC,EAAE;YACxC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,WAAW,GAAG,GAAG,EAAE;gBACxB,IAAI,CAAC,OAAO,EAAE,CAAC;oBACd,OAAO,GAAG,IAAI,CAAC;oBACf,QAAQ,EAAE,CAAC;gBACZ,CAAC;YACF,CAAC,CAAC;YAEF,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF,MAAM,CAAC,sBAAsB,GAAG,QAAQ,CAAC,EAAE;YAC1C,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,aAAa,GAAG,GAAG,EAAE;gBAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;oBACd,OAAO,GAAG,IAAI,CAAC;oBACf,QAAQ,EAAE,CAAC;gBACZ,CAAC;YACF,CAAC,CAAC;YAEF,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,MAAM,CAAC,yBAAyB,GAAG,QAAQ,CAAC,EAAE;YAC7C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/D,OAAO;YACR,CAAC;YAED,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC;IACH,CAAC;IAEO,+BAA+B;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO;QACR,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBACtB,MAAM,EAAE,IAAI,CAAC,aAA+B;aAC5C,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7D,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrC,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,cAAqC;QACpE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAEnC,IAAI,cAAc,KAAK,UAAU,IAAI,IAAI,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YACxE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACzB,QAAQ,EAAE,IAAI,CAAC,aAAa;gBAC5B,IAAI,EAAE,UAAU;gBAChB,MAAM;aACN,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;QAChC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAE5B,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5B,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,+BAA+B,EAAE,CAAC;QAEvC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAEO,cAAc,CAAC,YAAgC,EAAE;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ;YACxC,CAAC,CAAC,EAAE,sBAAsB,EAAE,QAAQ,GAAG,GAAG,EAAE;YAC5C,CAAC,CAAC,EAAE,CAAC;QAEN,MAAM,cAAc,GAAG,wBAAwB,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAE1E,OAAO;YACN,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,YAAY,EAAE,IAAI;YAClB,mBAAmB,EAAE,CAAC;YACtB,uBAAuB,EAAE,CAAC;YAC1B,qBAAqB,EAAE,IAAI;YAC3B,yBAAyB,EAAE,IAAI;YAC/B,4BAA4B,EAAE,IAAI;YAClC,gBAAgB,EAAE,EAAE;YACpB,mBAAmB,EAAE,CAAC;YACtB,aAAa,EAAE,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,KAAK;YACrB,qBAAqB,EAAE,CAAC;YACxB,aAAa,EAAE,EAAE;YACjB,WAAW,EAAE,GAAG;YAChB,aAAa,EAAE,CAAC;YAChB,wBAAwB,EAAE,CAAC;YAC3B,GAAG,gBAAgB;YACnB,GAAG,SAAS;YACZ,OAAO,EAAE,cAAc;SACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC/B,OAAO;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,EAAE;YACrB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,OAAO;YACR,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAEtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,MAAmC,CAAC,WAAW,GAAG,GAAG,CAAC;YACvD,IAAI,gBAAgB,GAAG,CAAC,CAAC;YACzB,MAAM,qBAAqB,GAAG,EAAE,CAAC;YACjC,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,MAAM,gBAAgB,GAAG,KAAM,CAAC;YAChC,IAAI,gBAAgB,GAAG,CAAC,CAAC,CAAC;YAE1B,MAAM,YAAY,GAAG,GAAG,EAAE;gBACzB,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAC9C,OAAO,KAAK,CAAC;gBACd,CAAC;gBACD,OAAO,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;YACtD,CAAC,CAAC;YAEF,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;gBACnD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;gBAC1C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;oBAC3B,MAAM,EAAE,KAAK;oBACb,QAAQ,EAAE,OAAO,EAAE,aAAa;oBAChC,IAAI,EAAE,OAAO,EAAE,IAAI;iBACnB,CAAC,CAAC;gBAEH,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;oBACnB,KAAK,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;oBAC/D,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAC1B,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;wBACxB,MAAM,CAAC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;wBAClC,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;wBACnC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;oBAC9C,CAAC;gBACF,CAAC;gBAED,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;oBAC7B,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBACpC,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE;gBACpC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACxB,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,YAAY,CAAC;oBAC7C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBAC9C,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;gBACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;oBAClB,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,IAAI,CAAC,KAAK;iBACjB,CAAC,CAAC;gBAEH,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACjB,OAAO;gBACR,CAAC;gBAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,IAAI,GAAG,GAAG,aAAa,GAAG,gBAAgB,EAAE,CAAC;oBAC5C,gBAAgB,GAAG,CAAC,CAAC;oBACrB,gBAAgB,GAAG,CAAC,CAAC,CAAC;gBACvB,CAAC;gBACD,aAAa,GAAG,GAAG,CAAC;gBAEpB,IAAI,gBAAgB,IAAI,qBAAqB,EAAE,CAAC;oBAC/C,OAAO;gBACR,CAAC;gBACD,gBAAgB,IAAI,CAAC,CAAC;gBAEtB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;oBACnB,KAAK,GAAG,CAAC,UAAU,CAAC,aAAa;wBAChC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,CAAC;wBACxC,MAAM;oBACP,KAAK,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;wBACjC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;wBACtC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;wBAClD,IAAI,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;4BAChC,IAAI,gBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC;gCAC7B,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;4BACpC,CAAC;4BACD,gBAAgB,IAAI,CAAC,CAAC;4BAEtB,IAAI,gBAAgB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;gCACtC,MAAM,QAAQ,GACb,OAAO,CAAC,SAAS,CAAC,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;gCACvD,IAAI,QAAQ,EAAE,CAAC;oCACd,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC;oCACjC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;oCAC9B,UAAU,CAAC,GAAG,EAAE;wCACf,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,GAAG,EAAE,CAAC;4CACnD,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;wCAC/B,CAAC;wCACD,GAAG,CAAC,iBAAiB,EAAE,CAAC;wCACxB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;4CACvC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;wCAC1C,CAAC;oCACF,CAAC,EAAE,GAAG,CAAC,CAAC;oCACR,MAAM;gCACP,CAAC;4BACF,CAAC;iCAAM,CAAC;gCACP,gBAAgB,GAAG,qBAAqB,CAAC;gCACzC,MAAM;4BACP,CAAC;wBACF,CAAC;wBAED,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,CAAC;wBAChD,MAAM;oBACP,CAAC;oBACD;wBACC,UAAU,CAAC,GAAG,EAAE;4BACf,IAAI,CAAC,WAAW,EAAE,CAAC;4BACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;4BACvB,QAAQ,EAAE,CAAC;wBACZ,CAAC,EAAE,IAAI,CAAC,CAAC;gBACX,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAEvB,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBACpD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;QACF,CAAC,CAAC;QAEF,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,KAAK,MAAM;gBACV,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,IAAQ,EAAE,EAAE;oBAC7B,QAAQ,EAAE,CAAC;oBACX,OAAQ,IAAI,CAAC,eAAmE,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC3F,CAAC,CAAC;gBACF,MAAM;YACP,KAAK,UAAU,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,GAAG,IAAI,GAAG,CAClB,IAAI,CAAC,cAAc,CAAC;oBACnB,aAAa,EAAE,KAAK;iBACpB,CAAC,CACF,CAAC;gBACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;gBACjB,MAAmC,CAAC,WAAW,GAAG,GAAG,CAAC;gBACvD,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gBACvB,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACnC,MAAM;YACP,CAAC;YACD,KAAK,YAAY;gBAChB,IAAI,OAAO,oBAAoB,KAAK,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtE,IAAI,CAAC,qBAAqB,GAAG,IAAI,oBAAoB,CACpD,OAAO,CAAC,EAAE;wBACT,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;4BAChC,QAAQ,EAAE,CAAC;4BACX,IAAI,CAAC,qBAAqB,EAAE,UAAU,EAAE,CAAC;4BACzC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;wBACnC,CAAC;oBACF,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACnB,CAAC;oBACF,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACvD,CAAC;qBAAM,CAAC;oBACP,QAAQ,EAAE,CAAC;gBACZ,CAAC;gBACD,MAAM;YACP;gBACC,QAAQ,EAAE,CAAC;QACb,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO;QACR,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,uBAAuB,EAAE,CAAC;YAC9C,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;gBAClB,KAAK,EAAE,SAAS;gBAChB,KAAK;aACL,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,GAAG,CAAC;YACV;gBACC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;gBACvB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,mBAAmB;aAChD;SACD,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,EAAE;gBACjC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACF,CAAC;IAEO,uBAAuB;QAC9B,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACnC,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC;YAC3C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC7B,CAAC;IACF,CAAC;IAEO,wBAAwB,CAAC,MAAgC;QAChE,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,OAAO;QACR,CAAC;QAED,MAAM,UAAU,GAAG,OAelB,CAAC;QAEF,MAAM,GAAG,GAAG,UAAU,EAAE,GAAG,EAAE,GAAG,IAAI,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;QACzD,IAAI,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACR,CAAC;QAED,MAAM,qBAAqB,GAAG,GAAG,CAAC,aAAa,CAAC;QAEhD,GAAG,CAAC,aAAa,GAAG,CAAC,cAAmC,EAAE,EAAE;YAC3D,MAAM,gBAAgB,GACrB,qBAAqB,EAAE,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,cAAc,CAAC;YAEpE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1B,gBAAgB,CAAC,OAAO,GAAG;oBAC1B,GAAG,CAAC,gBAAgB,CAAC,OAAO,IAAI,EAAE,CAAC;oBACnC,aAAa,EAAE,UAAU,IAAI,CAAC,eAAe,EAAE;iBAC/C,CAAC;YACH,CAAC;YAED,OAAO,gBAAgB,CAAC;QACzB,CAAC,CAAC;QAEF,IAAI,CAAC,oBAAoB,GAAG,GAAG,EAAE;YAChC,GAAG,CAAC,aAAa,GAAG,qBAAqB,CAAC;QAC3C,CAAC,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QAClC,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,WAAW;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO;QACR,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,SAAsC,CAAC,WAAW,GAAG,IAAI,CAAC;YAChE,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS;iBACjC,EAAE,EAAE;gBACL,EAAE,aAAa,CAAC,OAAO,CAA4B,CAAC;YACrD,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YAC1E,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;gBAChC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC3C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACtD,CAAC;QACF,CAAC;IACF,CAAC;CACD"} \ No newline at end of file diff --git a/dist/core/plugins/big-play-pause-button.d.ts b/dist/core/plugins/big-play-pause-button.d.ts new file mode 100644 index 0000000..f11c6c4 --- /dev/null +++ b/dist/core/plugins/big-play-pause-button.d.ts @@ -0,0 +1,4 @@ +import Player from "video.js/dist/types/player"; +declare function bigPlayPauseButtonPlugin(this: Player): void; +export default bigPlayPauseButtonPlugin; +//# sourceMappingURL=big-play-pause-button.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/big-play-pause-button.d.ts.map b/dist/core/plugins/big-play-pause-button.d.ts.map new file mode 100644 index 0000000..15d8633 --- /dev/null +++ b/dist/core/plugins/big-play-pause-button.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"big-play-pause-button.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/big-play-pause-button.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAkBhD,iBAAS,wBAAwB,CAAC,IAAI,EAAE,MAAM,QAO7C;AAID,eAAe,wBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/big-play-pause-button.js b/dist/core/plugins/big-play-pause-button.js new file mode 100644 index 0000000..a9d5513 --- /dev/null +++ b/dist/core/plugins/big-play-pause-button.js @@ -0,0 +1,26 @@ +import videojs from "video.js"; +const BigPlayButton = videojs.getComponent("BigPlayButton"); +class BigPlayPauseButton extends BigPlayButton { + handleClick() { + const player = this.player(); + if (player.paused()) { + player.play(); + } + else { + player.pause(); + } + } +} +videojs.registerComponent("BigPlayPauseButton", BigPlayPauseButton); +// Функция плагина с аннотацией типа this +function bigPlayPauseButtonPlugin() { + const player = this; + const defaultButton = player.getChild("bigPlayButton"); + if (defaultButton) { + defaultButton.dispose(); + } + player.addChild("BigPlayPauseButton", {}); +} +videojs.registerPlugin("bigPlayPauseButton", bigPlayPauseButtonPlugin); +export default bigPlayPauseButtonPlugin; +//# sourceMappingURL=big-play-pause-button.js.map \ No newline at end of file diff --git a/dist/core/plugins/big-play-pause-button.js.map b/dist/core/plugins/big-play-pause-button.js.map new file mode 100644 index 0000000..6cb3865 --- /dev/null +++ b/dist/core/plugins/big-play-pause-button.js.map @@ -0,0 +1 @@ +{"version":3,"file":"big-play-pause-button.js","sourceRoot":"","sources":["../../../src/core/plugins/big-play-pause-button.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAG/B,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;AAE5D,MAAM,kBAAmB,SAAQ,aAAa;IAC7C,WAAW;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAY,CAAC;QAEvC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACF,CAAC;CACD;AAED,OAAO,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;AACpE,yCAAyC;AACzC,SAAS,wBAAwB;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACvD,IAAI,aAAa,EAAE,CAAC;QACnB,aAAa,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC;AAEvE,eAAe,wBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/register.d.ts b/dist/core/plugins/register.d.ts new file mode 100644 index 0000000..d2110f6 --- /dev/null +++ b/dist/core/plugins/register.d.ts @@ -0,0 +1,4 @@ +import "./settings"; +import "./big-play-pause-button"; +import "./skip-buttons"; +//# sourceMappingURL=register.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/register.d.ts.map b/dist/core/plugins/register.d.ts.map new file mode 100644 index 0000000..60a546a --- /dev/null +++ b/dist/core/plugins/register.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/register.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,gBAAgB,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/register.js b/dist/core/plugins/register.js new file mode 100644 index 0000000..e32fd0e --- /dev/null +++ b/dist/core/plugins/register.js @@ -0,0 +1,4 @@ +import "./settings"; +import "./big-play-pause-button"; +import "./skip-buttons"; +//# sourceMappingURL=register.js.map \ No newline at end of file diff --git a/dist/core/plugins/register.js.map b/dist/core/plugins/register.js.map new file mode 100644 index 0000000..c53d844 --- /dev/null +++ b/dist/core/plugins/register.js.map @@ -0,0 +1 @@ +{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/core/plugins/register.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,gBAAgB,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts b/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts new file mode 100644 index 0000000..3eca6f0 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts @@ -0,0 +1,38 @@ +import Component from "video.js/dist/types/component"; +import Player from "video.js/dist/types/player"; +import TachVideoMenu from "../tach-video-menu"; +import TachVideoMenuItem from "../tach-video-menu-item"; +declare const MenuButton: typeof Component; +export default class TachVideoMenuButton extends MenuButton { + private hideThreshold_; + private buttonPressed_; + private menu; + private menuButton_; + items: TachVideoMenuItem[]; + /** + * Button constructor. + * + * @param {Player} player - videojs player instance + */ + constructor(player: Player, title: string, name: string); + /** + * Creates button items. + * + * @return {TachVideoMenuItem[]} - Button items + */ + createItems(): TachVideoMenuItem[]; + /** + * Создаёт меню и добавляет в него все пункты. + * + * @return {Menu} - Сконструированное меню + */ + createMenu(): TachVideoMenu; + /** + * Обновление меню без его пересоздания. + * + * @return {Menu} - Обновлённое меню + */ + update(): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts.map b/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts.map new file mode 100644 index 0000000..17241ab --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-button/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu-button/index.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,+BAA+B,CAAC;AACtD,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AAExD,QAAA,MAAM,UAAU,kBAAqC,CAAC;AAStD,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,UAAU;IAC1D,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,WAAW,CAAa;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAM;IAEvC;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAiBvD;;;;OAIG;IACH,WAAW,IAAI,iBAAiB,EAAE;IAIlC;;;;OAIG;IACH,UAAU;IAsBV;;;;OAIG;IACH,MAAM;CA6BN"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-button/index.js b/dist/core/plugins/settings/components/tach-video-menu-button/index.js new file mode 100644 index 0000000..abc713d --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-button/index.js @@ -0,0 +1,90 @@ +import videojs from "video.js"; +import TachVideoMenu from "../tach-video-menu"; +const MenuButton = videojs.getComponent("MenuButton"); +const Menu = videojs.getComponent("Menu"); +export default class TachVideoMenuButton extends MenuButton { + /** + * Button constructor. + * + * @param {Player} player - videojs player instance + */ + constructor(player, title, name) { + super(player, { + title: title, + name: name, + }); + this.hideThreshold_ = 0; + this.buttonPressed_ = false; + this.items = []; + // Перехватываем событие 'mouseenter' на уровне захвата и предотвращаем его дальнейшее распространение + const el = this.menuButton_.el(); + el.addEventListener("mouseenter", e => { + e.stopImmediatePropagation(); + }, true); + } + /** + * Creates button items. + * + * @return {TachVideoMenuItem[]} - Button items + */ + createItems() { + return []; + } + /** + * Создаёт меню и добавляет в него все пункты. + * + * @return {Menu} - Сконструированное меню + */ + createMenu() { + const menu = new TachVideoMenu(this.player_, { + menuButton: this, + }); + this.hideThreshold_ = 0; + this.items = this.createItems(); + if (this.items) { + // Если метод updateItems присутствует, используем его для обновления списка + if (typeof menu.updateItems === "function") { + menu.updateItems(this.items); + } + else { + // Если по какой-то причине обновление недоступно, добавляем элементы по одному + this.items.forEach(item => menu.addItem(item)); + } + } + return menu; + } + /** + * Обновление меню без его пересоздания. + * + * @return {Menu} - Обновлённое меню + */ + update() { + // Если меню уже создано и поддерживает updateItems, обновляем его содержимое + if (this.menu && typeof this.menu.updateItems === "function") { + this.items = this.createItems(); + this.menu.updateItems(this.items); + } + else { + // Если меню ещё не создано, создаём его + this.menu = this.createMenu(); + } + this.addChild(this.menu); + /** + * Track the state of the menu button + * + * @type {Boolean} + * @private + */ + this.buttonPressed_ = false; + this.menuButton_.el_.setAttribute("aria-expanded", "false"); + if (this.items && this.items?.length <= this.hideThreshold_) { + this.hide(); + this.menu.contentEl().removeAttribute("role"); + } + else { + this.show(); + this.menu.contentEl().setAttribute("role", "menu"); + } + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-button/index.js.map b/dist/core/plugins/settings/components/tach-video-menu-button/index.js.map new file mode 100644 index 0000000..eebfbc6 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-button/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu-button/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts b/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts new file mode 100644 index 0000000..73fee41 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts @@ -0,0 +1,33 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions, TachPlayerPlugin } from "../../types"; +import TachVideoMenuButton from "../tach-video-menu-button"; +declare const VideoJsMenuItemClass: typeof import("video.js/dist/types/component").default; +export interface ITachPlayerMenuItem extends TachPlayerMenuItemOptions { + onClick: () => void; + enabled?: boolean; + value?: unknown; +} +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenuItem extends VideoJsMenuItemClass { + private item; + private button; + private plugin; + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {ITachVideoMenuItem} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player: Player, item: ITachPlayerMenuItem, button: TachVideoMenuButton, plugin: TachPlayerPlugin); + /** + * Click event for menu item. + */ + handleClick(): void; + selected(val: boolean): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts.map b/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts.map new file mode 100644 index 0000000..0e5930f --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-item/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu-item/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAG5D,QAAA,MAAM,oBAAoB,wDAAmC,CAAC;AAG9D,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACrE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,oBAAoB;IAClE,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAmB;IAEjC;;;;;;;OAOG;gBAEF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,gBAAgB;IAczB;;OAEG;IACH,WAAW;IAWX,QAAQ,CAAC,GAAG,EAAE,OAAO;CAIrB"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-item/index.js b/dist/core/plugins/settings/components/tach-video-menu-item/index.js new file mode 100644 index 0000000..e8f3e8d --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-item/index.js @@ -0,0 +1,45 @@ +import videojs from "video.js"; +// Concrete classes +const VideoJsMenuItemClass = videojs.getComponent("MenuItem"); +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenuItem extends VideoJsMenuItemClass { + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {ITachVideoMenuItem} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player, item, button, plugin) { + super(player, { + label: item.label, + selectable: item.selectable || true, + selected: item.selected || false, + }); + this.item = item; + this.button = button; + this.plugin = plugin; + item.className && this.addClass(item.className); + } + /** + * Click event for menu item. + */ + handleClick() { + if (this.item.onClick) { + // Reset other menu items selected status. + for (let i = 0; i < this.button.items?.length; ++i) { + this.button.items[i].selected(false); + } + this.selected(true); + return this.item.onClick(); + } + } + selected(val) { + //@ts-expect-error // getComponent reduant + super.selected(val); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu-item/index.js.map b/dist/core/plugins/settings/components/tach-video-menu-item/index.js.map new file mode 100644 index 0000000..a611b0d --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu-item/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu-item/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAM/B,mBAAmB;AACnB,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;AAS9D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,oBAAoB;IAKlE;;;;;;;OAOG;IACH,YACC,MAAc,EACd,IAAyB,EACzB,MAA2B,EAC3B,MAAwB;QAExB,KAAK,CAAC,MAAM,EAAE;YACb,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;SACzB,CAAC,CAAC;QACV,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,WAAW;QACV,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvB,0CAA0C;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;gBACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;IACF,CAAC;IAED,QAAQ,CAAC,GAAY;QACpB,0CAA0C;QAC1C,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;CACD"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu/index.d.ts b/dist/core/plugins/settings/components/tach-video-menu/index.d.ts new file mode 100644 index 0000000..409c59e --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu/index.d.ts @@ -0,0 +1,33 @@ +import Player from "video.js/dist/types/player"; +import TachVideoMenuButton from "../tach-video-menu-button"; +import TachVideoMenuItem from "../tach-video-menu-item"; +declare const VideoJsMenuClass: typeof import("video.js/dist/types/component").default; +type BaseMenuOptions = ConstructorParameters[1]; +interface TachMenuOptions extends NonNullable { + menuButton: TachVideoMenuButton; +} +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenu extends VideoJsMenuClass { + private menuOpened_; + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {TachPlayerMenuItemOptions} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player: Player, options: TachMenuOptions); + hide(): void; + show(): void; + addItem(item: TachVideoMenuItem): void; + /** + * Обновляет пункты меню. + * @param {Array} newItems - Массив новых компонентов или их имён, которые будут добавлены в меню. + */ + updateItems(newItems: TachVideoMenuItem[]): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu/index.d.ts.map b/dist/core/plugins/settings/components/tach-video-menu/index.d.ts.map new file mode 100644 index 0000000..be100e7 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAC5D,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AAGxD,QAAA,MAAM,gBAAgB,wDAA+B,CAAC;AAMtD,KAAK,eAAe,GAAG,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,UAAU,eAAgB,SAAQ,WAAW,CAAC,eAAe,CAAC;IAC7D,UAAU,EAAE,mBAAmB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,gBAAgB;IAC1D,OAAO,CAAC,WAAW,CAAkB;IACrC;;;;;;;OAOG;gBACS,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe;IAUpD,IAAI;IAMJ,IAAI;IAMJ,OAAO,CAAC,IAAI,EAAE,iBAAiB;IAK/B;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,iBAAiB,EAAE;CAczC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu/index.js b/dist/core/plugins/settings/components/tach-video-menu/index.js new file mode 100644 index 0000000..8e1caa8 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu/index.js @@ -0,0 +1,56 @@ +import videojs from "video.js"; +// Concrete classes +const VideoJsMenuClass = videojs.getComponent("Menu"); +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenu extends VideoJsMenuClass { + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {TachPlayerMenuItemOptions} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player, options) { + super(player, options); + this.menuOpened_ = false; + player.on("userinactive", () => { + if (this.menuOpened_) { + player.userActive(true); + } + }); + } + hide() { + this.menuOpened_ = false; + // Вызов родительского метода скрытия + super.hide(); + } + show() { + this.menuOpened_ = true; + // Вызов родительского метода скрытия + super.show(); + } + addItem(item) { + //@ts-expect-error getComponent reduant method + super.addItem(item); + } + /** + * Обновляет пункты меню. + * @param {Array} newItems - Массив новых компонентов или их имён, которые будут добавлены в меню. + */ + updateItems(newItems) { + // Получаем текущих потомков + const currentChildren = this.children().slice(); + // Удаляем все остальные дочерние компоненты. + currentChildren.forEach(child => { + this.removeChild(child); + }); + // Добавляем новые пункты меню. + newItems.forEach(item => { + this.addItem(item); + }); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/components/tach-video-menu/index.js.map b/dist/core/plugins/settings/components/tach-video-menu/index.js.map new file mode 100644 index 0000000..b98de13 --- /dev/null +++ b/dist/core/plugins/settings/components/tach-video-menu/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/components/tach-video-menu/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAM/B,mBAAmB;AACnB,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAWtD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,gBAAgB;IAE1D;;;;;;;OAOG;IACH,YAAY,MAAc,EAAE,OAAwB;QACnD,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAVhB,gBAAW,GAAY,KAAK,CAAC;QAYpC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,IAAI;QACH,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,qCAAqC;QACrC,KAAK,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,IAAI;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,qCAAqC;QACrC,KAAK,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAuB;QAC9B,8CAA8C;QAC9C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,QAA6B;QACxC,4BAA4B;QAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC;QAEhD,6CAA6C;QAC7C,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC/B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"} \ No newline at end of file diff --git a/dist/core/plugins/settings/index.d.ts b/dist/core/plugins/settings/index.d.ts new file mode 100644 index 0000000..e6a1ee7 --- /dev/null +++ b/dist/core/plugins/settings/index.d.ts @@ -0,0 +1,53 @@ +import Component from "video.js/dist/types/component"; +import Player from "video.js/dist/types/player"; +import Plugin from "video.js/dist/types/plugin"; +import "./settings.css"; +interface SettingsButtonOptions { +} +interface PlayerWithControlBar extends Player { + hlsInstance?: unknown; + controlBar: Component; +} +declare const BasePlugin: typeof Plugin; +declare class SettingsButton extends BasePlugin { + private options; + private mainMenu; + private settingsButton; + private buttonInstance; + private backButton; + private playbackRateButton; + private qualityRateButton; + private audioTracksButton; + private textTracksButton; + constructor(player: PlayerWithControlBar, options: SettingsButtonOptions); + /** + * Инициализация плагина: создание кнопки настроек и привязка событий + */ + private initialize; + /** + * Привязка событий плеера (например, для обновления меню) + */ + private bindPlayerEvents; + /** + * Создание кнопки настроек и определение пунктов меню. + * Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню. + */ + private createSettingsButton; + /** + * Обёртка для создания экземпляра пункта меню. + * + * @param item - объект настроек пункта меню + * @returns экземпляр TachVideoMenuItem + */ + private getMenuItem; + /** + * Устанавливает (обновляет) пункты меню плагина. + * + * @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию) + * @param skipBackButton - если true, не добавлять кнопку "Назад" + * @param forceShow - если true, принудительно показать меню после обновления + */ + private setMenu; +} +export default SettingsButton; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/index.d.ts.map b/dist/core/plugins/settings/index.d.ts.map new file mode 100644 index 0000000..770fcf9 --- /dev/null +++ b/dist/core/plugins/settings/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/settings/index.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,+BAA+B,CAAC;AACtD,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAChD,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAWhD,OAAO,gBAAgB,CAAC;AAGxB,UAAU,qBAAqB;CAE9B;AAGD,UAAU,oBAAqB,SAAQ,MAAM;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,EAAmC,OAAO,MAAM,CAAC;AAKjE,cAAM,cAAe,SAAQ,UAAU;IACtC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAa;IAGnC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,qBAAqB;IAMxE;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA8D5B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;OAMG;YACW,OAAO;CA8CrB;AAID,eAAe,cAAc,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/index.js b/dist/core/plugins/settings/index.js new file mode 100644 index 0000000..4aadb91 --- /dev/null +++ b/dist/core/plugins/settings/index.js @@ -0,0 +1,141 @@ +import videojs from "video.js"; +import TachVideoMenuButton from "./components/tach-video-menu-button"; +import TachVideoMenuItem from "./components/tach-video-menu-item"; +import audioTrackSelector from "./selectors/audio-track-selector"; +import playbackRateSelector from "./selectors/playback-rate-selector"; +import qualityRateSelector from "./selectors/quality-rate-selector"; +import textTracksSelector from "./selectors/text-track-selector"; +import "./settings.css"; +const BasePlugin = videojs.getPlugin("plugin"); +// Значения опций по умолчанию +const defaults = {}; +class SettingsButton extends BasePlugin { + constructor(player, options) { + super(player); + this.mainMenu = []; + this.options = videojs.obj.merge(defaults, options); + this.player.ready(() => this.initialize()); + } + /** + * Инициализация плагина: создание кнопки настроек и привязка событий + */ + initialize() { + this.createSettingsButton(); + this.bindPlayerEvents(); + } + /** + * Привязка событий плеера (например, для обновления меню) + */ + bindPlayerEvents() { + // При необходимости можно привязать событие, например: + // this.settingsButton.on("click", this.setMenu.bind(this, undefined, false, true)); + } + /** + * Создание кнопки настроек и определение пунктов меню. + * Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню. + */ + createSettingsButton() { + const player = this.player; + // Создаем кнопку настроек с помощью компонента TachVideoMenuButton + this.settingsButton = new TachVideoMenuButton(player, "Settings", "Settings"); + this.buttonInstance = player.controlBar.addChild(this.settingsButton, { + componentClass: "settingsButton", + }); + this.buttonInstance.addClass("vjs-settings-button"); + // Определяем кнопку "Назад" для возврата в главное меню + this.backButton = { + label: "Назад", + value: this.mainMenu, + selectable: false, + selected: false, + onClick: () => this.setMenu(undefined, true, true), + className: "settings-back", + }; + // Создаем фабрики для дополнительных настроек + const { menuItem: audioMenuItem, menuItems: audioMenuItems } = audioTrackSelector(player); + this.audioTracksButton = () => ({ + ...audioMenuItem(), + onClick: () => this.setMenu(audioMenuItems(), false, true), + }); + const { menuItem: textMenuItem, menuItems: textMenuItems } = textTracksSelector(player); + this.textTracksButton = () => ({ + ...textMenuItem(), + onClick: () => this.setMenu(textMenuItems(), false, true), + }); + const { menuItem: playbackMenuItem, menuItems: playbackMenuItems } = playbackRateSelector(player); + this.playbackRateButton = () => ({ + ...playbackMenuItem(), + onClick: () => this.setMenu(playbackMenuItems(), false, true), + }); + // В createSettingsButton замени этот участок: + const qualitySelector = qualityRateSelector(player); + this.qualityRateButton = () => ({ + ...qualitySelector.menuItem(), // пересоздание при каждом открытии меню + onClick: () => this.setMenu(qualitySelector.menuItems(), false, true), + }); + // Подписка на автообновление, когда hls переключает уровень + qualitySelector.setMenuUpdateCallback(() => { + this.setMenu(undefined, true); // Обновить главное меню без перезахода + }); + // Инициализируем меню с кнопками по умолчанию без показа + this.setMenu(undefined, true, false); + } + /** + * Обёртка для создания экземпляра пункта меню. + * + * @param item - объект настроек пункта меню + * @returns экземпляр TachVideoMenuItem + */ + getMenuItem(item) { + return new TachVideoMenuItem(this.player, item, this.settingsButton, this); + } + /** + * Устанавливает (обновляет) пункты меню плагина. + * + * @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию) + * @param skipBackButton - если true, не добавлять кнопку "Назад" + * @param forceShow - если true, принудительно показать меню после обновления + */ + async setMenu(items = [], skipBackButton = false, forceShow = false) { + const menuButtons = []; + if (!skipBackButton) { + menuButtons.push(this.backButton); + } + if (items?.length === 0) { + // Если не переданы конкретные пункты меню – используем кнопки по умолчанию + const defaultButtons = [ + this.playbackRateButton, + this.qualityRateButton, + this.textTracksButton, + this.audioTracksButton, + ]; + defaultButtons.forEach(createButton => { + const btn = createButton(); + if (btn.enabled) { + menuButtons.push(btn); + } + }); + } + else { + menuButtons.push(...items); + } + // Формируем список пунктов меню: вместо пересоздания меню, назначаем функцию, + // возвращающую актуальный список пунктов, и вызываем метод обновления. + this.settingsButton.createItems = () => menuButtons.map(item => this.getMenuItem(item)); + await this.settingsButton.update(); + // Если требуется принудительно показать меню, эмулируем клик по кнопке меню + if (forceShow) { + const menuElement = this.buttonInstance.el().querySelector(".vjs-menu"); + const menuButton = this.buttonInstance + .el() + .querySelector(".vjs-menu-button"); + if (menuElement && menuButton) { + menuButton.click(); + } + } + } +} +// Регистрируем плагин в Video.js +videojs.registerPlugin("settingsMenu", SettingsButton); +export default SettingsButton; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/index.js.map b/dist/core/plugins/settings/index.js.map new file mode 100644 index 0000000..e30810e --- /dev/null +++ b/dist/core/plugins/settings/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/plugins/settings/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts b/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts new file mode 100644 index 0000000..77d434e --- /dev/null +++ b/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts @@ -0,0 +1,27 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../types"; +interface TrackMenuOptions extends TachPlayerMenuItemOptions { +} +declare const audioTrack: (player: Player, options?: TrackMenuOptions) => { + menuItems: () => { + label: string; + value: number; + selected: boolean; + onClick: () => void; + }[] | { + label: string; + value: string | undefined; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + value: string | null; + enabled: boolean; + label: string; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default audioTrack; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts.map b/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts.map new file mode 100644 index 0000000..5722033 --- /dev/null +++ b/dist/core/plugins/settings/selectors/audio-track-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/audio-track-selector/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AASxD,UAAU,gBAAiB,SAAQ,yBAAyB;CAAG;AAe/D,QAAA,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,UAAS,gBAA2B;;;;;;;;;;;;;;;;;;;;CAmJvE,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/audio-track-selector/index.js b/dist/core/plugins/settings/selectors/audio-track-selector/index.js new file mode 100644 index 0000000..2d5db34 --- /dev/null +++ b/dist/core/plugins/settings/selectors/audio-track-selector/index.js @@ -0,0 +1,125 @@ +const defaults = { + label: "Язык", + selected: false, + selectable: false, + className: "audio-selector", +}; +const audioTrack = (player, options = defaults) => { + const playerWithTracks = player; + const getNativeTrackList = () => { + if (typeof playerWithTracks.audioTracks !== "function") { + return undefined; + } + return playerWithTracks.audioTracks(); + }; + const getNativeTracks = () => { + return getNativeTrackList()?.tracks_ ?? []; + }; + const setNativeTrack = (track) => { + const audioTracks = getNativeTracks(); + for (let i = 0; i < audioTracks.length; ++i) { + audioTracks[i].enabled = audioTracks[i] === track; + } + }; + const getSelectedNativeTrack = () => { + const audioTracks = getNativeTracks(); + for (let i = 0; i < audioTracks.length; ++i) { + if (audioTracks[i].enabled === true) { + return audioTracks[i]; + } + } + return null; + }; + const getHlsInstance = () => playerWithTracks.hlsInstance ?? null; + const getHlsTracks = () => { + const hls = getHlsInstance(); + return hls?.audioTracks ?? []; + }; + const setHlsTrack = (trackId) => { + const hls = getHlsInstance(); + if (!hls) + return; + hls.audioTrack = trackId; + }; + const getSelectedHlsTrack = () => { + const hls = getHlsInstance(); + if (!hls) + return null; + const tracks = getHlsTracks(); + const currentId = hls.audioTrack; + return tracks.find(track => track.id === currentId) ?? null; + }; + const formatHlsTrackLabel = (track, index) => { + if (track.name?.trim()) { + return track.name.trim(); + } + if (track.lang?.trim()) { + return track.lang.trim().toUpperCase(); + } + const fallbackIndex = typeof index === "number" + ? index + 1 + : typeof track.id === "number" + ? track.id + 1 + : 1; + return `Дорожка ${fallbackIndex}`; + }; + const buildHlsMenuItems = () => { + const hls = getHlsInstance(); + const hlsTracks = getHlsTracks(); + if (!hls || hlsTracks.length === 0) { + return []; + } + return hlsTracks.map((track, index) => ({ + label: formatHlsTrackLabel(track, index), + value: track.id, + selected: track.id === hls.audioTrack, + onClick: () => setHlsTrack(track.id), + })); + }; + const hasAudioTracks = () => { + if (getHlsTracks().length > 0) { + return true; + } + return getNativeTracks().length > 0; + }; + const menuItems = () => { + const hlsTracks = buildHlsMenuItems(); + if (hlsTracks.length > 0) { + return hlsTracks; + } + const nativeTracks = getNativeTracks(); + const trackItems = []; + for (let i = 0; i < nativeTracks?.length; ++i) { + const trackItem = { + label: nativeTracks[i].label || "Default", + value: nativeTracks[i].label, + selected: nativeTracks[i].enabled, + onClick: () => setNativeTrack(nativeTracks[i]), + }; + trackItems.push(trackItem); + } + return trackItems; + }; + const getSelectedTrackLabel = () => { + const selectedHlsTrack = getSelectedHlsTrack(); + if (selectedHlsTrack) { + const tracks = getHlsTracks(); + const index = tracks.findIndex(track => track.id === selectedHlsTrack.id); + return formatHlsTrackLabel(selectedHlsTrack, index); + } + return getSelectedNativeTrack()?.label ?? null; + }; + const menuItem = () => { + return { + ...options, + value: getSelectedTrackLabel(), + enabled: hasAudioTracks(), + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default audioTrack; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/audio-track-selector/index.js.map b/dist/core/plugins/settings/selectors/audio-track-selector/index.js.map new file mode 100644 index 0000000..63fc031 --- /dev/null +++ b/dist/core/plugins/settings/selectors/audio-track-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/audio-track-selector/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts b/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts new file mode 100644 index 0000000..66d5efc --- /dev/null +++ b/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts @@ -0,0 +1,30 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../types"; +interface SpeedMenuOptions extends TachPlayerMenuItemOptions { + speeds: Array<{ + label: string; + value: number; + }>; +} +declare const playbackRate: (player: Player, options?: SpeedMenuOptions) => { + menuItems: () => { + label: string; + selectable: boolean; + selected: boolean; + onClick: () => number | undefined; + }[]; + menuItem: () => { + enabled: boolean; + speeds: Array<{ + label: string; + value: number; + }>; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default playbackRate; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts.map b/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts.map new file mode 100644 index 0000000..ae4efda --- /dev/null +++ b/dist/core/plugins/settings/selectors/playback-rate-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/playback-rate-selector/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAgBxD,UAAU,gBAAiB,SAAQ,yBAAyB;IAC3D,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,QAAA,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,UAAS,gBAA2B;;;;;;;;;gBAHjE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;;;;;;;CAwB/C,CAAC;AAEF,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/playback-rate-selector/index.js b/dist/core/plugins/settings/selectors/playback-rate-selector/index.js new file mode 100644 index 0000000..967d51f --- /dev/null +++ b/dist/core/plugins/settings/selectors/playback-rate-selector/index.js @@ -0,0 +1,35 @@ +const defaults = { + label: "Скорость воспроизведения", + selected: false, + selectable: false, + speeds: [ + { label: "0.5x", value: 0.5 }, + { label: "Обычная", value: 1 }, + { label: "1.5x", value: 1.5 }, + { label: "1.75x", value: 1.75 }, + { label: "2x", value: 2 }, + ], + className: "speed-selector", +}; +const playbackRate = (player, options = defaults) => { + const menuItems = () => options.speeds.map(speed => { + return { + label: speed.label, + selectable: true, + selected: speed.value === player.playbackRate(), + onClick: () => player.playbackRate(speed.value), + }; + }); + const menuItem = () => { + return { + ...options, + enabled: true, + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default playbackRate; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/playback-rate-selector/index.js.map b/dist/core/plugins/settings/selectors/playback-rate-selector/index.js.map new file mode 100644 index 0000000..d9c60fe --- /dev/null +++ b/dist/core/plugins/settings/selectors/playback-rate-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/playback-rate-selector/index.ts"],"names":[],"mappings":"AAIA,MAAM,QAAQ,GAAG;IAChB,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE;QACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;QAC7B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE;QAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;QAC7B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;QAC/B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;KACzB;IACD,SAAS,EAAE,gBAAgB;CAC3B,CAAC;AAMF,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,UAA4B,QAAQ,EAAE,EAAE;IAC7E,MAAM,SAAS,GAAG,GAAG,EAAE,CACtB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC1B,OAAO;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,YAAY,EAAE;YAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;SAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,OAAO;YACN,GAAG,OAAO;YACV,OAAO,EAAE,IAAI;SACb,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACN,SAAS;QACT,QAAQ;KACR,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts b/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts new file mode 100644 index 0000000..1b1d54f --- /dev/null +++ b/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts @@ -0,0 +1,39 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../types"; +interface QualityMenuOptions extends TachPlayerMenuItemOptions { +} +declare const qualityRate: (player: Player, options?: QualityMenuOptions) => { + menuItems: () => { + label: string; + value: string; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; + setMenuUpdateCallback: () => void; +} | { + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; + menuItems: () => { + label: string; + value: number; + selected: boolean; + onClick: () => void; + }[]; + setMenuUpdateCallback: (cb: () => void) => void; +}; +export default qualityRate; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts.map b/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts.map new file mode 100644 index 0000000..23c1430 --- /dev/null +++ b/dist/core/plugins/settings/selectors/quality-rate-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/quality-rate-selector/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAgBxD,UAAU,kBAAmB,SAAQ,yBAAyB;CAAG;AAEjE,QAAA,MAAM,WAAW,GAChB,QAAQ,MAAM,EACd,UAAS,kBAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAyHH,MAAM,IAAI;CAgB7C,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/quality-rate-selector/index.js b/dist/core/plugins/settings/selectors/quality-rate-selector/index.js new file mode 100644 index 0000000..0ae1cae --- /dev/null +++ b/dist/core/plugins/settings/selectors/quality-rate-selector/index.js @@ -0,0 +1,125 @@ +import Hls from "hls.js"; +const defaults = { + label: "Качество", + selected: false, + selectable: false, + className: "quality-selector", +}; +const qualityRate = (player, options = defaults) => { + const hls = player.hlsInstance; + let onMenuUpdate = null; + if (!hls) { + return { + menuItems: () => [ + { label: "Авто", value: "auto", selected: true, onClick: () => { } }, + ], + menuItem: () => ({ ...options, enabled: false }), + setMenuUpdateCallback: () => { }, + }; + } + // Инициализация состояния уровней качества + let levels = []; + let isMenuInitialized = false; + const updateLevels = () => { + if (hls.levels?.length > 0) { + levels = hls.levels; + if (!isMenuInitialized) { + isMenuInitialized = true; + } + if (onMenuUpdate) { + onMenuUpdate(); + } + } + }; + // Обновляем уровни при загрузке манифеста + hls.on(Hls.Events.MANIFEST_PARSED, () => { + updateLevels(); + }); + // Проверяем, есть ли уже доступные уровни + if (hls.levels && hls.levels?.length > 0) { + levels = hls.levels; + } + const getPixels = (l) => (l.width > l.height ? l.height : l.width); + const formatBitrate = (bps) => (bps / 1000000).toFixed(1).replace(/\.0$/, "") + " Мбит"; + const getCurrentAutoLevel = () => { + const current = levels[hls.currentLevel]; + return current ? `${getPixels(current)}p` : ""; + }; + const getCurrentManualLevel = () => { + const manual = levels[hls.manualLevel]; + return manual + ? `${getPixels(manual)}p / ${formatBitrate(manual.bitrate)}` + : "Качество"; + }; + const menuItem = () => { + return { + ...options, + enabled: levels?.length > 0, + label: levels?.length === 0 + ? "Качество" + : levels?.length === 1 + ? "Авто" + : hls.autoLevelEnabled + ? `Авто (${getCurrentAutoLevel()})` + : getCurrentManualLevel(), + }; + }; + const setQuality = (quality) => { + if (!levels?.length) + return; + if (quality === 'auto') { + hls.currentLevel = -1; + } + else if (typeof quality === 'number') { + hls.currentLevel = quality; + } + }; + const menuItems = () => { + const isAuto = hls.autoLevelEnabled; + // Если доступен только один уровень качества, показываем только "Авто" + if (levels?.length <= 1) { + return [{ + label: "Авто", + value: -1, + selected: true, + onClick: () => setQuality('auto'), + }]; + } + const items = levels.map((level, index) => { + const label = `${getPixels(level)}p / ${formatBitrate(level.bitrate)}`; + const selected = !isAuto && hls.currentLevel === index; + return { + label, + value: index, + selected, + onClick: () => setQuality(index), + }; + }); + items.sort((a, b) => b.value - a.value); + // Добавляем "Авто" с информацией о текущем качестве только если есть выбор + items.push({ + label: isAuto ? `Авто (${getCurrentAutoLevel()})` : "Авто", + value: -1, + selected: isAuto, + onClick: () => setQuality('auto'), + }); + return items; + }; + // Позволяет установить внешний колбэк на обновление меню + const setMenuUpdateCallback = (cb) => { + onMenuUpdate = cb; + // Если уже есть уровни качества, сразу обновляем меню + if (levels?.length > 0) { + requestAnimationFrame(() => cb()); + } + }; + // Подписка на смену уровня (в т.ч. в авто режиме) + hls.on(Hls.Events.LEVEL_SWITCHED, () => { + if (onMenuUpdate) { + onMenuUpdate(); // триггерим обновление главного меню + } + }); + return { menuItem, menuItems, setMenuUpdateCallback }; +}; +export default qualityRate; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/quality-rate-selector/index.js.map b/dist/core/plugins/settings/selectors/quality-rate-selector/index.js.map new file mode 100644 index 0000000..05df50c --- /dev/null +++ b/dist/core/plugins/settings/selectors/quality-rate-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/quality-rate-selector/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,QAAQ,CAAC;AAKzB,MAAM,QAAQ,GAAG;IAChB,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,kBAAkB;CAC7B,CAAC;AAWF,MAAM,WAAW,GAAG,CACnB,MAAc,EACd,UAA8B,QAAQ,EACrC,EAAE;IACH,MAAM,GAAG,GAAqB,MAAc,CAAC,WAAW,CAAC;IACzD,IAAI,YAAY,GAAwB,IAAI,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;YACN,SAAS,EAAE,GAAG,EAAE,CAAC;gBAChB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE;aACnE;YACD,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAChD,qBAAqB,EAAE,GAAG,EAAE,GAAE,CAAC;SAC/B,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,IAAI,MAAM,GAAe,EAAE,CAAC;IAC5B,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAE9B,MAAM,YAAY,GAAG,GAAG,EAAE;QACzB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACxB,iBAAiB,GAAG,IAAI,CAAC;YAC1B,CAAC;YACD,IAAI,YAAY,EAAE,CAAC;gBAClB,YAAY,EAAE,CAAC;YAChB,CAAC;QACF,CAAC;IACF,CAAC,CAAC;IAEF,0CAA0C;IAC1C,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE;QACvC,YAAY,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,0CAA0C;IAC1C,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IACxB,CAAC;IAEJ,MAAM,SAAS,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE7E,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE,CACrC,CAAC,GAAG,GAAG,OAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC;IAE5D,MAAM,mBAAmB,GAAG,GAAG,EAAE;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,GAAG,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvC,OAAO,MAAM;YACZ,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC5D,CAAC,CAAC,UAAU,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,OAAO;YACN,GAAG,OAAO;YACV,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC;YAC3B,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;gBAC1B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC;oBACrB,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,GAAG,CAAC,gBAAgB;wBACrB,CAAC,CAAC,SAAS,mBAAmB,EAAE,GAAG;wBACnC,CAAC,CAAC,qBAAqB,EAAE;SAC5B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,OAAwB,EAAQ,EAAE;QACrD,IAAI,CAAC,MAAM,EAAE,MAAM;YAAE,OAAO;QAE5B,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACxB,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QACvB,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACxC,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,GAAG,EAAE;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC;QAEpC,uEAAuE;QACvE,IAAI,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC;oBACP,KAAK,EAAE,MAAM;oBACb,KAAK,EAAE,CAAC,CAAC;oBACT,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;iBACjC,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACvE,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC;YAEvD,OAAO;gBACN,KAAK;gBACL,KAAK,EAAE,KAAK;gBACZ,QAAQ;gBACR,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;aAChC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAExC,2EAA2E;QAC3E,KAAK,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM;YAC1D,KAAK,EAAE,CAAC,CAAC;YACT,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;SACjC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACd,CAAC,CAAC;IAEF,yDAAyD;IACzD,MAAM,qBAAqB,GAAG,CAAC,EAAc,EAAE,EAAE;QAChD,YAAY,GAAG,EAAE,CAAC;QAClB,sDAAsD;QACtD,IAAI,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,qBAAqB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;IACF,CAAC,CAAC;IAEF,kDAAkD;IAClD,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE;QACtC,IAAI,YAAY,EAAE,CAAC;YAClB,YAAY,EAAE,CAAC,CAAC,qCAAqC;QACtD,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC;AACvD,CAAC,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts b/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts new file mode 100644 index 0000000..3db606b --- /dev/null +++ b/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts @@ -0,0 +1,26 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../types"; +interface QualityMenuOptions extends TachPlayerMenuItemOptions { +} +declare const textTracks: (player: Player & { + textTracks: () => { + tracks_?: TextTrack[]; + }; +}, options?: QualityMenuOptions) => { + menuItems: () => { + label: any; + value: any; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default textTracks; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts.map b/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts.map new file mode 100644 index 0000000..189d179 --- /dev/null +++ b/dist/core/plugins/settings/selectors/text-track-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/text-track-selector/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AASxD,UAAU,kBAAmB,SAAQ,yBAAyB;CAAG;AAEjE,QAAA,MAAM,UAAU,GACf,QAAQ,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM;QAAE,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;KAAE,CAAA;CAAE,EAChE,UAAS,kBAA6B;;;;;;;;;;;;;;;CAgDtC,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/text-track-selector/index.js b/dist/core/plugins/settings/selectors/text-track-selector/index.js new file mode 100644 index 0000000..4fc33cf --- /dev/null +++ b/dist/core/plugins/settings/selectors/text-track-selector/index.js @@ -0,0 +1,49 @@ +const defaults = { + label: "Субтитры", + selected: false, + selectable: false, + className: "subs-selector", +}; +const textTracks = (player, options = defaults) => { + const menuItems = () => { + const textTracks = player.textTracks().tracks_; + const trackItems = []; + for (let i = 0; i < textTracks?.length; ++i) { + if (textTracks[i].mode === "hidden") { + continue; + } + const trackItem = { + label: textTracks[i].label, + value: textTracks[i].label, + selected: textTracks[i].mode === "showing", + onClick: () => setTrack(textTracks[i]), + }; + trackItems.push(trackItem); + } + return trackItems; + }; + const setTrack = (track) => { + const textTracks = player.textTracks().tracks_; + for (let i = 0; i < textTracks?.length; ++i) { + if (textTracks[i].mode === "hidden") { + continue; + } + if (textTracks[i].label === track.label) + textTracks[i].mode = "showing"; + else + textTracks[i].mode = "disabled"; + } + }; + const menuItem = () => { + return { + ...options, + enabled: menuItems().length > 0, + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default textTracks; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/selectors/text-track-selector/index.js.map b/dist/core/plugins/settings/selectors/text-track-selector/index.js.map new file mode 100644 index 0000000..fa95eed --- /dev/null +++ b/dist/core/plugins/settings/selectors/text-track-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/core/plugins/settings/selectors/text-track-selector/index.ts"],"names":[],"mappings":"AAIA,MAAM,QAAQ,GAAG;IAChB,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,eAAe;CAC1B,CAAC;AAIF,MAAM,UAAU,GAAG,CAClB,MAAgE,EAChE,UAA8B,QAAQ,EACrC,EAAE;IACH,MAAM,SAAS,GAAG,GAAG,EAAE;QACtB,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC;QAC/C,MAAM,UAAU,GAAG,EAAE,CAAC;QAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7C,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,SAAS;YACV,CAAC;YAED,MAAM,SAAS,GAAG;gBACjB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;gBAC1B,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;gBAC1B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS;gBAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;aACtC,CAAC;YAEF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAE,EAAE;QACrC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC;QAE/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7C,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,SAAS;YACV,CAAC;YAED,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;gBAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;;gBACnE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC;QACtC,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,OAAO;YACN,GAAG,OAAO;YACV,OAAO,EAAE,SAAS,EAAE,CAAC,MAAM,GAAG,CAAC;SAC/B,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACN,SAAS;QACT,QAAQ;KACR,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/settings/settings.css b/dist/core/plugins/settings/settings.css new file mode 100644 index 0000000..e885a8c --- /dev/null +++ b/dist/core/plugins/settings/settings.css @@ -0,0 +1,93 @@ +.video-js { + .vjs-control-bar { + .vjs-settings-button { + .vjs-menu { + z-index: 10 !important; + &.vjs-lock-showing { + width: 100%; + + .vjs-menu-content { + height: fit-content; + bottom: 3em; + width: 340px; + left: -220px; + } + } + } + } + } + + &.vjs-mobile-ui { + .vjs-control-bar { + .vjs-settings-button { + .vjs-menu { + &.vjs-lock-showing { + width: 100%; + position: fixed; + + .vjs-menu-content { + border-radius: 0; + width: 100vw; + height: 100vh; + padding-top: 50vh; + padding-left: 20px; + padding-right: 20px; + padding-bottom: 5px; + max-height: 100vh; + position: fixed; + top: 0; + left: 0; + /* top: 85%; + left: 50%; */ + /* transform: translate(-50%, -85%); */ + + background: rgba( + 0, + 0, + 0, + 0.5 + ); /* затемнение в области паддингов */ + + &:hover { + border-radius: 0 !important; + } + + &::before { + content: ""; + position: absolute; + top: 50vh; + left: 20px; + right: 20px; + bottom: 5px; + background: var(--Default-BgDarken); + border-radius: 10px; /* желаемый border-radius */ + } + + .vjs-menu-item { + position: relative; + z-index: 2; + border-radius: 0; + + &:hover { + border-radius: 0 !important; + } + } + + @media (orientation: landscape) { + padding-top: 20px; + padding-left: 25vw; + padding-right: 25vw; + + &::before { + top: 20px; + left: 25vw; + right: 25vw; + } + } + } + } + } + } + } + } +} diff --git a/dist/core/plugins/settings/types.d.ts b/dist/core/plugins/settings/types.d.ts new file mode 100644 index 0000000..35ce6b7 --- /dev/null +++ b/dist/core/plugins/settings/types.d.ts @@ -0,0 +1,10 @@ +export interface TachPlayerMenuItemOptions { + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; +} +export interface TachPlayerPlugin { +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/settings/types.d.ts.map b/dist/core/plugins/settings/types.d.ts.map new file mode 100644 index 0000000..c1e4f0a --- /dev/null +++ b/dist/core/plugins/settings/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/plugins/settings/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;CAAG"} \ No newline at end of file diff --git a/dist/core/plugins/settings/types.js b/dist/core/plugins/settings/types.js new file mode 100644 index 0000000..718fd38 --- /dev/null +++ b/dist/core/plugins/settings/types.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/core/plugins/settings/types.js.map b/dist/core/plugins/settings/types.js.map new file mode 100644 index 0000000..67952d0 --- /dev/null +++ b/dist/core/plugins/settings/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/plugins/settings/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/core/plugins/skip-buttons.css b/dist/core/plugins/skip-buttons.css new file mode 100644 index 0000000..822315f --- /dev/null +++ b/dist/core/plugins/skip-buttons.css @@ -0,0 +1,126 @@ +.video-js { + .vjs-skip-button-component { + position: absolute; + top: 0; + width: calc(50% - 48px); + height: calc(100% - 73px); + + opacity: 1; + transition: opacity 1s; + + &.vjs-skip-backward { + left: 0; + } + + &.vjs-skip-forward { + right: 0; + } + + .vjs-skip-button { + position: relative; + width: 100%; + height: 100%; + + &:focus { + outline: none; + box-shadow: none; + } + + .icon-placeholder { + width: 30px; + height: 30px; + align-content: center; + position: absolute; + top: calc(50% + calc(48px / 2)); + } + + .scroll-info { + width: 100%; + height: calc(100% + 73px); + position: absolute; + top: 0; + + padding: 6%; + border-radius: 50%; + box-sizing: border-box; + + align-content: center; + + color: var(--Light-theme-Default-White, #fff); + text-align: center; + /* app/bold/Headline */ + font-family: Inter; + font-size: 1.3vw; + font-style: normal; + font-weight: 400; + + display: flex; + flex-direction: column; + justify-content: center; + + .scroll-icon { + display: flex; + width: 100%; + justify-content: center; + pointer-events: none; + } + + .scroll-text { + margin-top: 4px; + } + + @media (min-width: 1200px) { + font-size: 1vw; + } + } + + &.vjs-skip-button-backward { + .icon-placeholder { + right: 10px; + background-repeat: no-repeat; + background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M31.8191 5.58705C29.3458 4.53678 26.6859 3.99697 23.9988 4.00001C17.4569 4.00039 11.6487 7.14174 8 11.9982V8.00001C8 6.89544 7.10457 6.00001 6 6.00001C4.89543 6.00001 4 6.89544 4 8.00001V24C4 25.1046 4.89543 26 6 26C7.10457 26 8 25.1046 8 24C8 15.1636 15.1636 8.00001 24 8.00001L24.0024 8.00001C26.151 7.99745 28.278 8.42902 30.2557 9.26884C32.2334 10.1087 34.021 11.3394 35.5113 12.8872C36.2774 13.6829 37.5435 13.7069 38.3392 12.9407C39.1349 12.1746 39.1589 10.9085 38.3927 10.1128C36.5287 8.17687 34.2928 6.63748 31.8191 5.58705ZM42 22C40.8954 22 40 22.8954 40 24C40 32.8364 32.8364 40 24 40H23.9973C19.8528 40.0056 15.8691 38.3968 12.8908 35.5148C12.0971 34.7466 10.8309 34.7674 10.0628 35.5612C9.29464 36.3549 9.31542 37.6211 10.1092 38.3892C13.8348 41.9945 18.8182 44.007 24.0027 44L24 42V44H24.0027C35.047 43.9985 44 35.0447 44 24C44 22.8954 43.1046 22 42 22Z' fill='white'/%3E%3C/svg%3E") no-repeat center / 24px 24px; + } + .scroll-info { + left: -65%; + align-items: end; + background: linear-gradient( + 270deg, + rgba(0, 0, 0, 0.25) 0%, + rgba(0, 0, 0, 0) 73.42% + ); + } + } + + &.vjs-skip-button-forward { + .icon-placeholder { + left: 10px; + background-repeat: no-repeat; + background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16.1809 5.58705C18.6542 4.53678 21.3141 3.99697 24.0012 4.00001C30.5431 4.00039 36.3513 7.14174 40 11.9982V8.00001C40 6.89544 40.8954 6.00001 42 6.00001C43.1046 6.00001 44 6.89544 44 8.00001V24C44 25.1046 43.1046 26 42 26C40.8954 26 40 25.1046 40 24C40 15.1636 32.8364 8.00001 24 8.00001L23.9976 8.00001C21.849 7.99745 19.722 8.42902 17.7443 9.26884C15.7666 10.1087 13.979 11.3394 12.4887 12.8872C11.7226 13.6829 10.4565 13.7069 9.66082 12.9407C8.86512 12.1746 8.84114 10.9085 9.60727 10.1128C11.4713 8.17687 13.7072 6.63748 16.1809 5.58705ZM6 22C7.10457 22 8 22.8954 8 24C8 32.8364 15.1636 40 24 40H24.0027C28.1472 40.0056 32.1309 38.3968 35.1092 35.5148C35.9029 34.7466 37.1691 34.7674 37.9372 35.5612C38.7054 36.3549 38.6846 37.6211 37.8908 38.3892C34.1652 41.9945 29.1818 44.007 23.9973 44L24 42V44H23.9973C12.953 43.9985 4 35.0447 4 24C4 22.8954 4.89543 22 6 22Z' fill='white'/%3E%3C/svg%3E") no-repeat center / 24px 24px; + } + .scroll-info { + align-items: start; + right: -65%; + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 0.25) 0%, + rgba(0, 0, 0, 0) 73.42% + ); + } + } + } + } + + &.vjs-user-inactive { + .vjs-skip-button-component { + opacity: 0; + pointer-events: none; + } + } + + /* &.vjs-hls-live, */ + &.vjs-controls-disabled { + .vjs-skip-button-component { + display: none; + } + } +} diff --git a/dist/core/plugins/skip-buttons.d.ts b/dist/core/plugins/skip-buttons.d.ts new file mode 100644 index 0000000..26d80ad --- /dev/null +++ b/dist/core/plugins/skip-buttons.d.ts @@ -0,0 +1,8 @@ +import type Player from "video.js/dist/types/player"; +import "./skip-buttons.css"; +export interface SkipButtonsOptions { + skip: number; +} +declare const skipButtonsPlugin: (this: Player, options: SkipButtonsOptions) => void; +export default skipButtonsPlugin; +//# sourceMappingURL=skip-buttons.d.ts.map \ No newline at end of file diff --git a/dist/core/plugins/skip-buttons.d.ts.map b/dist/core/plugins/skip-buttons.d.ts.map new file mode 100644 index 0000000..e3073c2 --- /dev/null +++ b/dist/core/plugins/skip-buttons.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"skip-buttons.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/skip-buttons.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AAErD,OAAO,oBAAoB,CAAC;AAE5B,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;CACb;AAoID,QAAA,MAAM,iBAAiB,GAAa,MAAM,MAAM,EAAE,SAAS,kBAAkB,SAoD5E,CAAC;AAIF,eAAe,iBAAiB,CAAC"} \ No newline at end of file diff --git a/dist/core/plugins/skip-buttons.js b/dist/core/plugins/skip-buttons.js new file mode 100644 index 0000000..1efbeee --- /dev/null +++ b/dist/core/plugins/skip-buttons.js @@ -0,0 +1,150 @@ +import videojs from "video.js"; +import "./skip-buttons.css"; +const BACKWARD_SCROLL_ICON = ``; +const FORWARD_SCROLL_ICON = ``; +const wakePlayerUI = (player) => { + const playerWithActivity = player; + playerWithActivity.reportUserActivity?.(); + playerWithActivity.userActive?.(true); + player.el()?.focus?.(); +}; +const secondsLabel = (accumulated) => { + const seconds = Math.abs(accumulated); + const mod10 = seconds % 10; + const mod100 = seconds % 100; + if (mod10 === 1 && mod100 !== 11) { + return `${seconds} секунду`; + } + if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) { + return `${seconds} секунды`; + } + return `${seconds} секунд`; +}; +const createSkipButton = (player, skip, direction) => { + const button = document.createElement("button"); + button.type = "button"; + button.className = `vjs-skip-button vjs-skip-button-${direction}`; + const icon = document.createElement("span"); + icon.className = "icon-placeholder"; + icon.textContent = String(skip); + button.appendChild(icon); + const scrollInfo = document.createElement("div"); + scrollInfo.className = "scroll-info"; + scrollInfo.style.display = "none"; + const scrollIcon = document.createElement("span"); + scrollIcon.className = `scroll-icon scroll-icon-${direction}`; + scrollIcon.innerHTML = + direction === "backward" ? BACKWARD_SCROLL_ICON : FORWARD_SCROLL_ICON; + scrollInfo.appendChild(scrollIcon); + const scrollText = document.createElement("span"); + scrollText.className = "scroll-text"; + scrollInfo.appendChild(scrollText); + button.appendChild(scrollInfo); + let accumulated = 0; + let timer = null; + const renderScrollInfo = () => { + if (accumulated === 0) { + scrollInfo.style.display = "none"; + scrollText.textContent = ""; + return; + } + scrollInfo.style.display = "flex"; + scrollText.textContent = secondsLabel(accumulated); + }; + button.addEventListener("click", () => { + wakePlayerUI(player); + accumulated += direction === "forward" ? skip : -skip; + renderScrollInfo(); + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(() => { + const currentTime = player.currentTime() || 0; + player.currentTime(currentTime + accumulated); + wakePlayerUI(player); + accumulated = 0; + renderScrollInfo(); + }, 500); + }); + return button; +}; +class SkipButtonComponent extends videojs.getComponent("Component") { + constructor() { + super(...arguments); + this.element = null; + } + createEl() { + const direction = this.options_.direction; + const skip = Number(this.options_.skip) || 10; + const el = super.createEl("div", { + className: `vjs-skip-button-component vjs-skip-${direction}`, + }); + this.element = createSkipButton(this.player(), skip, direction); + el.appendChild(this.element); + return el; + } +} +class SkipBackwardButtonComponent extends SkipButtonComponent { + constructor(player, options) { + options.direction = "backward"; + super(player, options); + } +} +class SkipForwardButtonComponent extends SkipButtonComponent { + constructor(player, options) { + options.direction = "forward"; + super(player, options); + } +} +videojs.registerComponent("SkipBackwardButtonComponent", SkipBackwardButtonComponent); +videojs.registerComponent("SkipForwardButtonComponent", SkipForwardButtonComponent); +const skipButtonsPlugin = function (options) { + const player = this; + player.ready(() => { + player.addChild("SkipBackwardButtonComponent", { skip: options.skip }); + player.addChild("SkipForwardButtonComponent", { skip: options.skip }); + const triggerSkip = (direction) => { + const selector = `.vjs-skip-button-${direction}`; + const button = player.el().querySelector(selector); + wakePlayerUI(player); + button?.click(); + }; + const onKeydown = (event) => { + const active = document.activeElement; + const tag = active?.tagName; + const isEditable = tag === "INPUT" || + tag === "TEXTAREA" || + tag === "SELECT" || + active?.getAttribute("contenteditable") === "true"; + if (isEditable) { + return; + } + if (event.key === " " || event.code === "Space") { + event.preventDefault(); + wakePlayerUI(player); + if (player.paused()) { + void player.play(); + } + else { + player.pause(); + } + return; + } + if (event.key === "ArrowRight") { + event.preventDefault(); + triggerSkip("forward"); + } + else if (event.key === "ArrowLeft") { + event.preventDefault(); + triggerSkip("backward"); + } + }; + document.addEventListener("keydown", onKeydown); + player.on("dispose", () => { + document.removeEventListener("keydown", onKeydown); + }); + }); +}; +videojs.registerPlugin("skipButtons", skipButtonsPlugin); +export default skipButtonsPlugin; +//# sourceMappingURL=skip-buttons.js.map \ No newline at end of file diff --git a/dist/core/plugins/skip-buttons.js.map b/dist/core/plugins/skip-buttons.js.map new file mode 100644 index 0000000..e3c811f --- /dev/null +++ b/dist/core/plugins/skip-buttons.js.map @@ -0,0 +1 @@ +{"version":3,"file":"skip-buttons.js","sourceRoot":"","sources":["../../../src/core/plugins/skip-buttons.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/token-provider.d.ts b/dist/core/token-provider.d.ts new file mode 100644 index 0000000..12463cb --- /dev/null +++ b/dist/core/token-provider.d.ts @@ -0,0 +1,5 @@ +export type VideoPlayerToken = string | null | undefined | Promise; +export type VideoPlayerTokenProvider = () => VideoPlayerToken; +export declare const setVideoPlayerTokenProvider: (provider?: VideoPlayerTokenProvider | null) => void; +export declare const resolveVideoPlayerToken: () => Promise; +//# sourceMappingURL=token-provider.d.ts.map \ No newline at end of file diff --git a/dist/core/token-provider.d.ts.map b/dist/core/token-provider.d.ts.map new file mode 100644 index 0000000..460c6ef --- /dev/null +++ b/dist/core/token-provider.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"token-provider.d.ts","sourceRoot":"","sources":["../../src/core/token-provider.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,IAAI,GACJ,SAAS,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEtC,MAAM,MAAM,wBAAwB,GAAG,MAAM,gBAAgB,CAAC;AAI9D,eAAO,MAAM,2BAA2B,GACvC,WAAW,wBAAwB,GAAG,IAAI,SAG1C,CAAC;AAEF,eAAO,MAAM,uBAAuB,0CAMnC,CAAC"} \ No newline at end of file diff --git a/dist/core/token-provider.js b/dist/core/token-provider.js new file mode 100644 index 0000000..08b1e5a --- /dev/null +++ b/dist/core/token-provider.js @@ -0,0 +1,11 @@ +let tokenProvider = null; +export const setVideoPlayerTokenProvider = (provider) => { + tokenProvider = provider ?? null; +}; +export const resolveVideoPlayerToken = async () => { + if (!tokenProvider) { + return null; + } + return tokenProvider(); +}; +//# sourceMappingURL=token-provider.js.map \ No newline at end of file diff --git a/dist/core/token-provider.js.map b/dist/core/token-provider.js.map new file mode 100644 index 0000000..955f7e4 --- /dev/null +++ b/dist/core/token-provider.js.map @@ -0,0 +1 @@ +{"version":3,"file":"token-provider.js","sourceRoot":"","sources":["../../src/core/token-provider.ts"],"names":[],"mappings":"AAQA,IAAI,aAAa,GAAoC,IAAI,CAAC;AAE1D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAC1C,QAA0C,EACzC,EAAE;IACH,aAAa,GAAG,QAAQ,IAAI,IAAI,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,IAAI,EAAE;IACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,aAAa,EAAE,CAAC;AACxB,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/react/index.d.ts b/dist/react/index.d.ts new file mode 100644 index 0000000..c2076e1 --- /dev/null +++ b/dist/react/index.d.ts @@ -0,0 +1,3 @@ +export { VideoPlayer as VideoPlayerSsr, type IVideoPlayerProps, default, } from "./video-player/video-player"; +export type { IVideoJSOptions, IVideoJSProps, IVideoJSSource, PreloadType, VideoJsPlayer, } from "./video-player/components/video-js/types"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/index.d.ts.map b/dist/react/index.d.ts.map new file mode 100644 index 0000000..2198c96 --- /dev/null +++ b/dist/react/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,IAAI,cAAc,EAC7B,KAAK,iBAAiB,EACtB,OAAO,GACP,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACX,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,GACb,MAAM,0CAA0C,CAAC"} \ No newline at end of file diff --git a/dist/react/index.js b/dist/react/index.js new file mode 100644 index 0000000..a8ac890 --- /dev/null +++ b/dist/react/index.js @@ -0,0 +1,2 @@ +export { VideoPlayer as VideoPlayerSsr, default, } from "./video-player/video-player"; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/index.js.map b/dist/react/index.js.map new file mode 100644 index 0000000..58d3625 --- /dev/null +++ b/dist/react/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,IAAI,cAAc,EAE7B,OAAO,GACP,MAAM,6BAA6B,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/player-extension/index.d.ts b/dist/react/video-player/components/player-extension/index.d.ts new file mode 100644 index 0000000..f1e28dd --- /dev/null +++ b/dist/react/video-player/components/player-extension/index.d.ts @@ -0,0 +1,10 @@ +import { type ReactNode, type Ref } from "react"; +import { IBaseComponentProps } from "../../shared/types"; +interface IPlayerExtensionProps extends IBaseComponentProps { + className?: string; + children: ReactNode; + conteinerRef?: Ref; +} +declare const PlayerExtension: ({ className, children, conteinerRef, ...rest }: IPlayerExtensionProps) => import("react/jsx-runtime").JSX.Element; +export default PlayerExtension; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/player-extension/index.d.ts.map b/dist/react/video-player/components/player-extension/index.d.ts.map new file mode 100644 index 0000000..5aeb7c7 --- /dev/null +++ b/dist/react/video-player/components/player-extension/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/react/video-player/components/player-extension/index.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAKxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,UAAU,qBAAsB,SAAQ,mBAAmB;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,YAAY,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;CACxB;AAED,QAAA,MAAM,eAAe,GAAI,gDAKtB,qBAAqB,4CAUvB,CAAC;AAEF,eAAe,eAAe,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/player-extension/index.js b/dist/react/video-player/components/player-extension/index.js new file mode 100644 index 0000000..3d3d784 --- /dev/null +++ b/dist/react/video-player/components/player-extension/index.js @@ -0,0 +1,8 @@ +import { jsx as _jsx } from "react/jsx-runtime"; +import cn from "classnames"; +import baseStyles from "../../video.module.scss"; +const PlayerExtension = ({ className, children, conteinerRef, ...rest }) => { + return (_jsx("div", { ref: conteinerRef, className: cn([baseStyles.videoMain, className]), ...rest, children: children })); +}; +export default PlayerExtension; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/player-extension/index.js.map b/dist/react/video-player/components/player-extension/index.js.map new file mode 100644 index 0000000..075050f --- /dev/null +++ b/dist/react/video-player/components/player-extension/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/react/video-player/components/player-extension/index.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,UAAU,MAAM,yBAAyB,CAAC;AASjD,MAAM,eAAe,GAAG,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,GAAG,IAAI,EACgB,EAAE,EAAE;IAC3B,OAAO,CACN,cACC,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,KAC5C,IAAI,YAEP,QAAQ,GACJ,CACN,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/qr-scanner/index.d.ts b/dist/react/video-player/components/qr-scanner/index.d.ts new file mode 100644 index 0000000..87c0980 --- /dev/null +++ b/dist/react/video-player/components/qr-scanner/index.d.ts @@ -0,0 +1,25 @@ +import React from "react"; +import Player from "video.js/dist/types/player"; +interface VideoQRScannerPluginProps { + player: Player | null; + enabled?: boolean; + /** + * Интервал между запусками сканирования в миллисекундах. + * По умолчанию 200 мс. + */ + scanInterval?: number; + /** + * Масштаб для сканирования (0 < scanningScale <= 1). + * Значение меньше 1 уменьшает разрешение для ускорения обработки. + * По умолчанию 1. + */ + scanningScale?: number; + /** + * Количество неудачных попыток обнаружения QR-кода до снятия маски. + * По умолчанию 2.a + */ + maxFailedAttempts?: number; +} +declare const VideoQRScannerPlugin: React.FC; +export default VideoQRScannerPlugin; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/qr-scanner/index.d.ts.map b/dist/react/video-player/components/qr-scanner/index.d.ts.map new file mode 100644 index 0000000..428bc82 --- /dev/null +++ b/dist/react/video-player/components/qr-scanner/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/react/video-player/components/qr-scanner/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAIhD,UAAU,yBAAyB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAqR7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/qr-scanner/index.js b/dist/react/video-player/components/qr-scanner/index.js new file mode 100644 index 0000000..a745b7c --- /dev/null +++ b/dist/react/video-player/components/qr-scanner/index.js @@ -0,0 +1,209 @@ +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { createPortal } from "react-dom"; +import { Popover } from "antd"; +import QrScanner from "qr-scanner"; +import { CloseOutlined } from "@ant-design/icons"; +const VideoQRScannerPlugin = ({ player, enabled = true, scanInterval = 200, scanningScale = 1, maxFailedAttempts = 2, }) => { + const canvasRef = useRef(null); + const [detectedQr, setDetectedQr] = useState(null); + const animationFrameRef = useRef(null); + const ignoredQRCodes = useRef(new Set()); + const [playerEl, setPlayerEl] = useState(null); + const lastScanTimeRef = useRef(0); + const isScanningRef = useRef(false); + // Счётчик неудачных попыток обнаружения QR, если код уже отображается + const failedAttemptsRef = useRef(0); + // Для получения актуального значения detectedQr внутри асинхронного колбэка + const detectedQrRef = useRef(null); + useEffect(() => { + detectedQrRef.current = detectedQr; + }, [detectedQr]); + // Изначально устанавливаем контейнер для портала как элемент плеера + useEffect(() => { + if (player) { + setPlayerEl(player.el()); + } + }, [player]); + // Обновление контейнера при переходе в полноэкранный режим + useEffect(() => { + const handleFullscreenChange = () => { + if (document.fullscreenElement) { + setPlayerEl(document.fullscreenElement); + } + else if (player) { + setPlayerEl(player.el()); + } + }; + document.addEventListener("fullscreenchange", handleFullscreenChange); + return () => { + document.removeEventListener("fullscreenchange", handleFullscreenChange); + }; + }, [player]); + const scanFrame = useCallback(async () => { + if (!player || player.paused() || !canvasRef.current || !enabled) + return; + const now = performance.now(); + if (now - lastScanTimeRef.current < scanInterval) { + animationFrameRef.current = requestAnimationFrame(scanFrame); + return; + } + lastScanTimeRef.current = now; + // Предотвращаем параллельное выполнение сканирования + if (isScanningRef.current) { + animationFrameRef.current = requestAnimationFrame(scanFrame); + return; + } + isScanningRef.current = true; + const videoEl = player.tech(true).el(); + const canvas = canvasRef.current; + const ctx = canvas.getContext("2d"); + if (!ctx) { + isScanningRef.current = false; + return; + } + // Получаем оригинальные размеры видео + const originalVideoWidth = videoEl.videoWidth; + const originalVideoHeight = videoEl.videoHeight; + // Устанавливаем canvas с пониженным разрешением для сканирования + canvas.width = originalVideoWidth * scanningScale; + canvas.height = originalVideoHeight * scanningScale; + // Рисуем видео в canvas с пониженным разрешением + ctx.drawImage(videoEl, 0, 0, canvas.width, canvas.height); + try { + const result = await QrScanner.scanImage(canvas, { + returnDetailedScanResult: true, + }); + if (result && + result.data && + result.cornerPoints?.length === 4 && + !ignoredQRCodes.current.has(result.data)) { + // Сброс неудачных попыток при успешном обнаружении + failedAttemptsRef.current = 0; + // Преобразуем координаты из масштабированного canvas в координаты оригинального видео + const points = result.cornerPoints.map(p => ({ + x: p.x / scanningScale, + y: p.y / scanningScale, + })); + const minX = Math.min(...points.map(p => p.x)); + const minY = Math.min(...points.map(p => p.y)); + const maxX = Math.max(...points.map(p => p.x)); + const maxY = Math.max(...points.map(p => p.y)); + // Получаем размеры отображаемого видео + const rect = videoEl.getBoundingClientRect(); + const displayScale = Math.min(rect.width / originalVideoWidth, rect.height / originalVideoHeight); + const offsetX = (rect.width - originalVideoWidth * displayScale) / 2; + const offsetY = (rect.height - originalVideoHeight * displayScale) / 2; + const qrWidth = (maxX - minX) * displayScale; + const qrHeight = (maxY - minY) * displayScale; + const padding = 8; + const x = minX * displayScale + offsetX - padding; + const y = minY * displayScale + offsetY - padding; + setDetectedQr({ + data: result.data, + position: new DOMRect(x, y, qrWidth + padding * 2, qrHeight + padding * 2), + }); + } + else { + // Если код не найден, и он уже отображался, даем maxFailedAttempts попыток + if (detectedQrRef.current) { + failedAttemptsRef.current += 1; + if (failedAttemptsRef.current >= maxFailedAttempts) { + setDetectedQr(null); + failedAttemptsRef.current = 0; + } + } + } + } + catch (error) { + // В случае ошибки аналогичная логика: если код уже отображался — даем maxFailedAttempts попыток + if (detectedQrRef.current) { + failedAttemptsRef.current += 1; + if (failedAttemptsRef.current >= maxFailedAttempts) { + setDetectedQr(null); + failedAttemptsRef.current = 0; + } + } + } + finally { + isScanningRef.current = false; + } + animationFrameRef.current = requestAnimationFrame(scanFrame); + }, [player, enabled, scanInterval, scanningScale, maxFailedAttempts]); + useEffect(() => { + if (!player || !enabled) + return; + const startScanning = () => { + if (animationFrameRef.current) + cancelAnimationFrame(animationFrameRef.current); + animationFrameRef.current = requestAnimationFrame(scanFrame); + }; + const stopScanning = () => { + if (animationFrameRef.current) { + cancelAnimationFrame(animationFrameRef.current); + animationFrameRef.current = null; + } + setDetectedQr(null); + }; + player.on("play", startScanning); + player.on("pause", stopScanning); + player.on("ended", stopScanning); + window.addEventListener("resize", startScanning); + return () => { + stopScanning(); + player.off("play", startScanning); + player.off("pause", stopScanning); + player.off("ended", stopScanning); + window.removeEventListener("resize", startScanning); + }; + }, [player, enabled, scanFrame]); + const ignoreQRCode = () => { + if (detectedQr) { + ignoredQRCodes.current.add(detectedQr.data); + setDetectedQr(null); + } + }; + return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, style: { display: "none" } }), detectedQr && + playerEl && + createPortal(_jsx(Popover, { getPopupContainer: () => playerEl, content: _jsx("a", { href: detectedQr.data, target: "_blank", rel: "noreferrer", referrerPolicy: "no-referrer", style: { color: "#1677ff" }, children: detectedQr.data }), placement: "top", children: _jsxs("div", { style: { + position: "absolute", + left: detectedQr.position.x, + top: detectedQr.position.y, + width: detectedQr.position.width, + height: detectedQr.position.height, + pointerEvents: "auto", + cursor: "pointer", + zIndex: 10, + }, children: [["top-left", "top-right", "bottom-left", "bottom-right"].map(corner => (_jsx("div", { style: { + position: "absolute", + width: 20, + height: 20, + border: "3px solid var(--Accent-Primary)", + borderRadius: 4, + ...(corner.includes("top") ? { top: 0 } : { bottom: 0 }), + ...(corner.includes("left") ? { left: 0 } : { right: 0 }), + borderTop: corner.includes("bottom") + ? "none" + : "3px solid var(--Accent-Primary)", + borderBottom: corner.includes("top") + ? "none" + : "3px solid var(--Accent-Primary)", + borderLeft: corner.includes("right") + ? "none" + : "3px solid var(--Accent-Primary)", + borderRight: corner.includes("left") + ? "none" + : "3px solid var(--Accent-Primary)", + } }, corner))), _jsx(CloseOutlined, { style: { + color: "#ff4d4f", + position: "absolute", + top: "-8px", + right: "-8px", + background: "white", + borderRadius: "50%", + padding: "2px", + cursor: "pointer", + }, onClick: ignoreQRCode })] }) }), playerEl)] })); +}; +export default VideoQRScannerPlugin; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/qr-scanner/index.js.map b/dist/react/video-player/components/qr-scanner/index.js.map new file mode 100644 index 0000000..0d2182f --- /dev/null +++ b/dist/react/video-player/components/qr-scanner/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/react/video-player/components/qr-scanner/index.tsx"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/default.css b/dist/react/video-player/components/video-js/default.css new file mode 100644 index 0000000..cb092df --- /dev/null +++ b/dist/react/video-player/components/video-js/default.css @@ -0,0 +1,2226 @@ +.vjs-svg-icon { + display: inline-block; + background-repeat: no-repeat; + background-position: center; + fill: currentColor; + height: 1.8em; + width: 1.8em; +} +.vjs-svg-icon:before { + content: none !important; +} + +.vjs-svg-icon:hover, +.vjs-control:focus .vjs-svg-icon { + filter: drop-shadow(0 0 0.25em #fff); +} + +.vjs-modal-dialog .vjs-modal-dialog-content, +.video-js .vjs-modal-dialog, +.vjs-button > .vjs-icon-placeholder:before, +.video-js .vjs-big-play-button .vjs-icon-placeholder:before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.vjs-button > .vjs-icon-placeholder:before, +.video-js .vjs-big-play-button .vjs-icon-placeholder:before { + text-align: center; +} + +@font-face { + font-family: VideoJS; + src: url(data:application/font-woff;charset=utf-8;base64,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) + format("woff"); + font-weight: normal; + font-style: normal; +} +.vjs-icon-play, +.video-js .vjs-play-control .vjs-icon-placeholder, +.video-js .vjs-big-play-button .vjs-icon-placeholder:before { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-play:before, +.video-js .vjs-play-control .vjs-icon-placeholder:before, +.video-js .vjs-big-play-button .vjs-icon-placeholder:before { + content: "\f101"; +} + +.vjs-icon-play-circle { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-play-circle:before { + content: "\f102"; +} + +.vjs-icon-pause, +.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-pause:before, +.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before { + content: "\f103"; +} + +.vjs-icon-volume-mute, +.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-volume-mute:before, +.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before { + content: "\f104"; +} + +.vjs-icon-volume-low, +.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-volume-low:before, +.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before { + content: "\f105"; +} + +.vjs-icon-volume-mid, +.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-volume-mid:before, +.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before { + content: "\f106"; +} + +.vjs-icon-volume-high, +.video-js .vjs-mute-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-volume-high:before, +.video-js .vjs-mute-control .vjs-icon-placeholder:before { + content: "\f107"; +} + +.vjs-icon-fullscreen-enter, +.video-js .vjs-fullscreen-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-fullscreen-enter:before, +.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before { + content: "\f108"; +} + +.vjs-icon-fullscreen-exit, +.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-fullscreen-exit:before, +.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before { + content: "\f109"; +} + +.vjs-icon-spinner { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-spinner:before { + content: "\f10a"; +} + +.vjs-icon-subtitles, +.video-js .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js .vjs-subtitles-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-subtitles:before, +.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-GB) + .vjs-subs-caps-button + .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-IE) + .vjs-subs-caps-button + .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-AU) + .vjs-subs-caps-button + .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-NZ) + .vjs-subs-caps-button + .vjs-icon-placeholder:before, +.video-js .vjs-subtitles-button .vjs-icon-placeholder:before { + content: "\f10b"; +} + +.vjs-icon-captions, +.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js .vjs-captions-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-captions:before, +.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js .vjs-captions-button .vjs-icon-placeholder:before { + content: "\f10c"; +} + +.vjs-icon-hd { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-hd:before { + content: "\f10d"; +} + +.vjs-icon-chapters, +.video-js .vjs-chapters-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-chapters:before, +.video-js .vjs-chapters-button .vjs-icon-placeholder:before { + content: "\f10e"; +} + +.vjs-icon-downloading { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-downloading:before { + content: "\f10f"; +} + +.vjs-icon-file-download { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-file-download:before { + content: "\f110"; +} + +.vjs-icon-file-download-done { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-file-download-done:before { + content: "\f111"; +} + +.vjs-icon-file-download-off { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-file-download-off:before { + content: "\f112"; +} + +.vjs-icon-share { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-share:before { + content: "\f113"; +} + +.vjs-icon-cog { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-cog:before { + content: "\f114"; +} + +.vjs-icon-square { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-square:before { + content: "\f115"; +} + +.vjs-icon-circle, +.vjs-seek-to-live-control .vjs-icon-placeholder, +.video-js .vjs-volume-level, +.video-js .vjs-play-progress { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-circle:before, +.vjs-seek-to-live-control .vjs-icon-placeholder:before, +.video-js .vjs-volume-level:before, +.video-js .vjs-play-progress:before { + content: "\f116"; +} + +.vjs-icon-circle-outline { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-circle-outline:before { + content: "\f117"; +} + +.vjs-icon-circle-inner-circle { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-circle-inner-circle:before { + content: "\f118"; +} + +.vjs-icon-cancel, +.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-cancel:before, +.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before { + content: "\f119"; +} + +.vjs-icon-repeat { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-repeat:before { + content: "\f11a"; +} + +.vjs-icon-replay, +.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-replay:before, +.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before { + content: "\f11b"; +} + +.vjs-icon-replay-5, +.video-js .vjs-skip-backward-5 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-replay-5:before, +.video-js .vjs-skip-backward-5 .vjs-icon-placeholder:before { + content: "\f11c"; +} + +.vjs-icon-replay-10, +.video-js .vjs-skip-backward-10 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-replay-10:before, +.video-js .vjs-skip-backward-10 .vjs-icon-placeholder:before { + content: "\f11d"; +} + +.vjs-icon-replay-30, +.video-js .vjs-skip-backward-30 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-replay-30:before, +.video-js .vjs-skip-backward-30 .vjs-icon-placeholder:before { + content: "\f11e"; +} + +.vjs-icon-forward-5, +.video-js .vjs-skip-forward-5 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-forward-5:before, +.video-js .vjs-skip-forward-5 .vjs-icon-placeholder:before { + content: "\f11f"; +} + +.vjs-icon-forward-10, +.video-js .vjs-skip-forward-10 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-forward-10:before, +.video-js .vjs-skip-forward-10 .vjs-icon-placeholder:before { + content: "\f120"; +} + +.vjs-icon-forward-30, +.video-js .vjs-skip-forward-30 .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-forward-30:before, +.video-js .vjs-skip-forward-30 .vjs-icon-placeholder:before { + content: "\f121"; +} + +.vjs-icon-audio, +.video-js .vjs-audio-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-audio:before, +.video-js .vjs-audio-button .vjs-icon-placeholder:before { + content: "\f122"; +} + +.vjs-icon-next-item { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-next-item:before { + content: "\f123"; +} + +.vjs-icon-previous-item { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-previous-item:before { + content: "\f124"; +} + +.vjs-icon-shuffle { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-shuffle:before { + content: "\f125"; +} + +.vjs-icon-cast { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-cast:before { + content: "\f126"; +} + +.vjs-icon-picture-in-picture-enter, +.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-picture-in-picture-enter:before, +.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before { + content: "\f127"; +} + +.vjs-icon-picture-in-picture-exit, +.video-js.vjs-picture-in-picture + .vjs-picture-in-picture-control + .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-picture-in-picture-exit:before, +.video-js.vjs-picture-in-picture + .vjs-picture-in-picture-control + .vjs-icon-placeholder:before { + content: "\f128"; +} + +.vjs-icon-facebook { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-facebook:before { + content: "\f129"; +} + +.vjs-icon-linkedin { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-linkedin:before { + content: "\f12a"; +} + +.vjs-icon-twitter { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-twitter:before { + content: "\f12b"; +} + +.vjs-icon-tumblr { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-tumblr:before { + content: "\f12c"; +} + +.vjs-icon-pinterest { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-pinterest:before { + content: "\f12d"; +} + +.vjs-icon-audio-description, +.video-js .vjs-descriptions-button .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-audio-description:before, +.video-js .vjs-descriptions-button .vjs-icon-placeholder:before { + content: "\f12e"; +} + +.video-js { + display: inline-block; + vertical-align: top; + box-sizing: border-box; + color: #fff; + background-color: #000; + position: relative; + padding: 0; + font-size: 10px; + line-height: 1; + font-weight: normal; + font-style: normal; + font-family: Arial, Helvetica, sans-serif; + word-break: initial; +} +.video-js:-moz-full-screen { + position: absolute; +} +.video-js:-webkit-full-screen { + width: 100% !important; + height: 100% !important; +} + +.video-js[tabindex="-1"] { + outline: none; +} + +.video-js *, +.video-js *:before, +.video-js *:after { + box-sizing: inherit; +} + +.video-js ul { + font-family: inherit; + font-size: inherit; + line-height: inherit; + list-style-position: outside; + margin-left: 0; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; +} + +.video-js.vjs-fluid, +.video-js.vjs-16-9, +.video-js.vjs-4-3, +.video-js.vjs-9-16, +.video-js.vjs-1-1 { + width: 100%; + max-width: 100%; +} + +.video-js.vjs-fluid:not(.vjs-audio-only-mode), +.video-js.vjs-16-9:not(.vjs-audio-only-mode), +.video-js.vjs-4-3:not(.vjs-audio-only-mode), +.video-js.vjs-9-16:not(.vjs-audio-only-mode), +.video-js.vjs-1-1:not(.vjs-audio-only-mode) { + height: 0; +} + +.video-js.vjs-16-9:not(.vjs-audio-only-mode) { + padding-top: 56.25%; +} + +.video-js.vjs-4-3:not(.vjs-audio-only-mode) { + padding-top: 75%; +} + +.video-js.vjs-9-16:not(.vjs-audio-only-mode) { + padding-top: 177.7777777778%; +} + +.video-js.vjs-1-1:not(.vjs-audio-only-mode) { + padding-top: 100%; +} + +.video-js.vjs-fill:not(.vjs-audio-only-mode) { + width: 100%; + height: 100%; +} + +.video-js .vjs-tech { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.video-js.vjs-audio-only-mode .vjs-tech { + display: none; +} + +body.vjs-full-window, +body.vjs-pip-window { + padding: 0; + margin: 0; + height: 100%; +} + +.vjs-full-window .video-js.vjs-fullscreen, +body.vjs-pip-window .video-js { + position: fixed; + overflow: hidden; + z-index: 1000; + left: 0; + top: 0; + bottom: 0; + right: 0; +} + +.video-js.vjs-fullscreen:not(.vjs-ios-native-fs), +body.vjs-pip-window .video-js { + width: 100% !important; + height: 100% !important; + padding-top: 0 !important; + display: block; +} + +.video-js.vjs-fullscreen.vjs-user-inactive { + cursor: none; +} + +.vjs-pip-container .vjs-pip-text { + position: absolute; + bottom: 10%; + font-size: 2em; + background-color: rgba(0, 0, 0, 0.7); + padding: 0.5em; + text-align: center; + width: 100%; +} + +.vjs-layout-tiny.vjs-pip-container .vjs-pip-text, +.vjs-layout-x-small.vjs-pip-container .vjs-pip-text, +.vjs-layout-small.vjs-pip-container .vjs-pip-text { + bottom: 0; + font-size: 1.4em; +} + +.vjs-hidden { + display: none !important; +} + +.vjs-disabled { + opacity: 0.5; + cursor: default; +} + +.video-js .vjs-offscreen { + height: 1px; + left: -9999px; + position: absolute; + top: 0; + width: 1px; +} + +.vjs-lock-showing { + display: block !important; + opacity: 1 !important; + visibility: visible !important; +} + +.vjs-no-js { + padding: 20px; + color: #fff; + background-color: #000; + font-size: 18px; + font-family: Arial, Helvetica, sans-serif; + text-align: center; + width: 300px; + height: 150px; + margin: 0px auto; +} + +.vjs-no-js a, +.vjs-no-js a:visited { + color: #66a8cc; +} + +.video-js .vjs-big-play-button { + font-size: 3em; + line-height: 1.5em; + height: 1.63332em; + width: 3em; + display: block; + position: absolute; + top: 50%; + left: 50%; + padding: 0; + margin-top: -0.81666em; + margin-left: -1.5em; + cursor: pointer; + opacity: 1; + border: 0.06666em solid #fff; + background-color: #2b333f; + background-color: rgba(43, 51, 63, 0.7); + border-radius: 0.3em; + transition: all 0.4s; +} +.vjs-big-play-button .vjs-svg-icon { + width: 1em; + height: 1em; + position: absolute; + top: 50%; + left: 50%; + line-height: 1; + transform: translate(-50%, -50%); +} + +.video-js:hover .vjs-big-play-button, +.video-js .vjs-big-play-button:focus { + border-color: #fff; + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); + transition: all 0s; +} + +.vjs-controls-disabled .vjs-big-play-button, +.vjs-has-started .vjs-big-play-button, +.vjs-using-native-controls .vjs-big-play-button, +.vjs-error .vjs-big-play-button { + display: none; +} + +.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause:not( + .vjs-seeking, + .vjs-scrubbing, + .vjs-error + ) + .vjs-big-play-button { + display: block; +} + +.video-js button { + background: none; + border: none; + color: inherit; + display: inline-block; + font-size: inherit; + line-height: inherit; + text-transform: none; + text-decoration: none; + transition: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.video-js.vjs-spatial-navigation-enabled .vjs-button:focus { + outline: 0.0625em solid white; + box-shadow: none; +} + +.vjs-control .vjs-button { + width: 100%; + height: 100%; +} + +.video-js .vjs-control.vjs-close-button { + cursor: pointer; + height: 3em; + position: absolute; + right: 0; + top: 0.5em; + z-index: 2; +} +.video-js .vjs-modal-dialog { + background: rgba(0, 0, 0, 0.8); + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0.8), + rgba(255, 255, 255, 0) + ); + overflow: auto; +} + +.video-js .vjs-modal-dialog > * { + box-sizing: border-box; +} + +.vjs-modal-dialog .vjs-modal-dialog-content { + font-size: 1.2em; + line-height: 1.5; + padding: 20px 24px; + z-index: 1; +} + +.vjs-menu-button { + cursor: pointer; +} + +.vjs-menu-button.vjs-disabled { + cursor: default; +} + +.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu { + display: none; +} + +.vjs-menu .vjs-menu-content { + display: block; + padding: 0; + margin: 0; + font-family: Arial, Helvetica, sans-serif; + overflow: auto; +} + +.vjs-menu .vjs-menu-content > * { + box-sizing: border-box; +} + +.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu { + display: none; +} + +.vjs-menu li { + display: flex; + justify-content: center; + list-style: none; + margin: 0; + padding: 0.2em 0; + line-height: 1.4em; + font-size: 1.2em; + text-align: center; + text-transform: lowercase; +} + +.vjs-menu li.vjs-menu-item:focus, +.vjs-menu li.vjs-menu-item:hover, +.js-focus-visible .vjs-menu li.vjs-menu-item:hover { + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); +} + +.vjs-menu li.vjs-selected, +.vjs-menu li.vjs-selected:focus, +.vjs-menu li.vjs-selected:hover, +.js-focus-visible .vjs-menu li.vjs-selected:hover { + background-color: #fff; + color: #2b333f; +} +.vjs-menu li.vjs-selected .vjs-svg-icon, +.vjs-menu li.vjs-selected:focus .vjs-svg-icon, +.vjs-menu li.vjs-selected:hover .vjs-svg-icon, +.js-focus-visible .vjs-menu li.vjs-selected:hover .vjs-svg-icon { + fill: #000000; +} + +.video-js .vjs-menu *:not(.vjs-selected):focus:not(:focus-visible), +.js-focus-visible .vjs-menu *:not(.vjs-selected):focus:not(.focus-visible) { + background: none; +} + +.vjs-menu li.vjs-menu-title { + text-align: center; + text-transform: uppercase; + font-size: 1em; + line-height: 2em; + padding: 0; + margin: 0 0 0.3em 0; + font-weight: bold; + cursor: default; +} + +.vjs-menu-button-popup .vjs-menu { + display: none; + position: absolute; + bottom: 0; + width: 10em; + left: -3em; + height: 0em; + margin-bottom: 1.5em; + border-top-color: rgba(43, 51, 63, 0.7); +} + +.vjs-pip-window .vjs-menu-button-popup .vjs-menu { + left: unset; + right: 1em; +} + +.vjs-menu-button-popup .vjs-menu .vjs-menu-content { + background-color: #2b333f; + background-color: rgba(43, 51, 63, 0.7); + position: absolute; + width: 100%; + bottom: 1.5em; + max-height: 15em; +} + +.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 5em; +} + +.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 10em; +} + +.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 14em; +} + +.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 25em; +} + +.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu, +.vjs-menu-button-popup .vjs-menu.vjs-lock-showing { + display: block; +} + +.video-js .vjs-menu-button-inline { + transition: all 0.4s; + overflow: hidden; +} + +.video-js .vjs-menu-button-inline:before { + width: 2.222222222em; +} + +.video-js .vjs-menu-button-inline:hover, +.video-js .vjs-menu-button-inline:focus, +.video-js .vjs-menu-button-inline.vjs-slider-active { + width: 12em; +} + +.vjs-menu-button-inline .vjs-menu { + opacity: 0; + height: 100%; + width: auto; + position: absolute; + left: 4em; + top: 0; + padding: 0; + margin: 0; + transition: all 0.4s; +} + +.vjs-menu-button-inline:hover .vjs-menu, +.vjs-menu-button-inline:focus .vjs-menu, +.vjs-menu-button-inline.vjs-slider-active .vjs-menu { + display: block; + opacity: 1; +} + +.vjs-menu-button-inline .vjs-menu-content { + width: auto; + height: 100%; + margin: 0; + overflow: hidden; +} + +.video-js .vjs-control-bar { + display: none; + width: 100%; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 3em; + background-color: #2b333f; + background-color: rgba(43, 51, 63, 0.7); +} + +.video-js.vjs-spatial-navigation-enabled .vjs-control-bar { + gap: 1px; +} + +.video-js:not(.vjs-controls-disabled, .vjs-using-native-controls, .vjs-error) + .vjs-control-bar.vjs-lock-showing { + display: flex !important; +} + +.vjs-has-started .vjs-control-bar, +.vjs-audio-only-mode .vjs-control-bar { + display: flex; + visibility: visible; + opacity: 1; + transition: + visibility 0.1s, + opacity 0.1s; +} + +.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { + visibility: visible; + opacity: 0; + pointer-events: none; + transition: + visibility 1s, + opacity 1s; +} + +.vjs-controls-disabled .vjs-control-bar, +.vjs-using-native-controls .vjs-control-bar, +.vjs-error .vjs-control-bar { + display: none !important; +} + +.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar, +.vjs-audio-only-mode.vjs-has-started.vjs-user-inactive.vjs-playing + .vjs-control-bar { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +.video-js .vjs-control { + position: relative; + text-align: center; + margin: 0; + padding: 0; + height: 100%; + width: 4em; + flex: none; +} + +.video-js .vjs-control.vjs-visible-text { + width: auto; + padding-left: 1em; + padding-right: 1em; +} + +.vjs-button > .vjs-icon-placeholder:before { + font-size: 1.8em; + line-height: 1.67; +} + +.vjs-button > .vjs-icon-placeholder { + display: block; +} + +.vjs-button > .vjs-svg-icon { + display: inline-block; +} + +.video-js .vjs-control:focus:before, +.video-js .vjs-control:hover:before, +.video-js .vjs-control:focus { + text-shadow: 0em 0em 1em white; +} + +.video-js *:not(.vjs-visible-text) > .vjs-control-text { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.video-js .vjs-custom-control-spacer { + display: none; +} + +.video-js .vjs-progress-control { + cursor: pointer; + flex: auto; + display: flex; + align-items: center; + min-width: 4em; + touch-action: none; +} + +.video-js .vjs-progress-control.disabled { + cursor: default; +} + +.vjs-hls-live .vjs-progress-control { + display: none; +} + +.vjs-live .vjs-progress-control { + display: none; +} + + +.vjs-hls-liveui .vjs-progress-control { + display: flex; + align-items: center; +} + +.video-js .vjs-progress-holder { + flex: auto; + transition: all 0.2s; + height: 0.3em; +} + +.video-js .vjs-progress-control .vjs-progress-holder { + margin: 0 10px; +} + +.video-js .vjs-progress-control:hover .vjs-progress-holder { + font-size: 1.6666666667em; +} + +.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled { + font-size: 1em; +} + +.video-js .vjs-progress-holder .vjs-play-progress, +.video-js .vjs-progress-holder .vjs-load-progress, +.video-js .vjs-progress-holder .vjs-load-progress div { + position: absolute; + display: block; + height: 100%; + margin: 0; + padding: 0; + width: 0; +} + +.video-js .vjs-play-progress { + background-color: #fff; +} +.video-js .vjs-play-progress:before { + font-size: 0.9em; + position: absolute; + right: -0.5em; + line-height: 0.35em; + z-index: 1; +} + +.vjs-svg-icons-enabled .vjs-play-progress:before { + content: none !important; +} + +.vjs-play-progress .vjs-svg-icon { + position: absolute; + top: -0.35em; + right: -0.4em; + width: 0.9em; + height: 0.9em; + pointer-events: none; + line-height: 0.15em; + z-index: 1; +} + +.video-js .vjs-load-progress { + background: rgba(115, 133, 159, 0.5); +} + +.video-js .vjs-load-progress div { + background: rgba(115, 133, 159, 0.75); +} + +.video-js .vjs-time-tooltip { + background-color: #fff; + background-color: rgba(255, 255, 255, 0.8); + border-radius: 0.3em; + color: #000; + float: right; + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; + padding: 6px 8px 8px 8px; + pointer-events: none; + position: absolute; + top: -3.4em; + visibility: hidden; + z-index: 1; +} + +.video-js .vjs-progress-holder:focus .vjs-time-tooltip { + display: none; +} + +.video-js .vjs-progress-control:hover .vjs-time-tooltip, +.video-js + .vjs-progress-control:hover + .vjs-progress-holder:focus + .vjs-time-tooltip { + display: block; + font-size: 0.6em; + visibility: visible; +} + +.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip { + font-size: 1em; +} + +.video-js .vjs-progress-control .vjs-mouse-display { + display: none; + position: absolute; + width: 1px; + height: 100%; + background-color: #000; + z-index: 1; +} + +.video-js .vjs-progress-control:hover .vjs-mouse-display { + display: block; +} + +.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display { + visibility: hidden; + opacity: 0; + transition: + visibility 1s, + opacity 1s; +} + +.vjs-mouse-display .vjs-time-tooltip { + color: #fff; + background-color: #000; + background-color: rgba(0, 0, 0, 0.8); +} + +.video-js .vjs-slider { + position: relative; + cursor: pointer; + padding: 0; + margin: 0 0.45em 0 0.45em; + /* iOS Safari */ + -webkit-touch-callout: none; + /* Safari, and Chrome 53 */ + -webkit-user-select: none; + /* Non-prefixed version, currently supported by Chrome and Opera */ + -moz-user-select: none; + user-select: none; + background-color: #73859f; + background-color: rgba(115, 133, 159, 0.5); +} + +.video-js .vjs-slider.disabled { + cursor: default; +} + +.video-js .vjs-slider:focus { + text-shadow: 0em 0em 1em white; + box-shadow: 0 0 1em #fff; +} + +.video-js.vjs-spatial-navigation-enabled .vjs-slider:focus { + outline: 0.0625em solid white; +} + +.video-js .vjs-mute-control { + cursor: pointer; + flex: none; +} +.video-js .vjs-volume-control { + cursor: pointer; + margin-right: 1em; + display: flex; +} + +.video-js .vjs-volume-control.vjs-volume-horizontal { + width: 5em; +} + +.video-js .vjs-volume-panel .vjs-volume-control { + visibility: visible; + opacity: 0; + width: 1px; + height: 1px; + margin-left: -1px; +} + +.video-js .vjs-volume-panel { + transition: width 1s; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control, +.video-js .vjs-volume-panel:active .vjs-volume-control, +.video-js .vjs-volume-panel:focus .vjs-volume-control, +.video-js .vjs-volume-panel .vjs-volume-control:active, +.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control, +.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active { + visibility: visible; + opacity: 1; + position: relative; + transition: + visibility 0.1s, + opacity 0.1s, + height 0.1s, + width 0.1s, + left 0s, + top 0s; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal, +.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal, +.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal, +.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal, +.video-js + .vjs-volume-panel.vjs-hover + .vjs-mute-control + ~ .vjs-volume-control.vjs-volume-horizontal, +.video-js + .vjs-volume-panel + .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal { + width: 5em; + height: 3em; + margin-right: 0; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical, +.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical, +.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical, +.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical, +.video-js + .vjs-volume-panel.vjs-hover + .vjs-mute-control + ~ .vjs-volume-control.vjs-volume-vertical, +.video-js + .vjs-volume-panel + .vjs-volume-control.vjs-slider-active.vjs-volume-vertical { + left: -3.5em; + transition: left 0s; +} +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover, +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active { + width: 100px; + transition: width 0.1s; +} +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only { + width: 4em; +} + +.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { + height: 8em; + width: 3em; + left: -3000em; + transition: + visibility 1s, + opacity 1s, + height 1s 1s, + width 1s 1s, + left 1s 1s, + top 1s 1s; +} + +.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal { + transition: + visibility 1s, + opacity 1s, + height 1s 1s, + width 1s, + left 1s 1s, + top 1s 1s; +} + +.video-js .vjs-volume-panel { + display: flex; +} + +.video-js .vjs-volume-bar { + margin: 1.35em 0.45em; +} + +.vjs-volume-bar.vjs-slider-horizontal { + width: 5em; + height: 0.3em; +} + +.vjs-volume-bar.vjs-slider-vertical { + width: 0.3em; + height: 5em; + margin: 1.35em auto; +} + +.video-js .vjs-volume-level { + position: absolute; + bottom: 0; + left: 0; + background-color: #fff; +} +.video-js .vjs-volume-level:before { + position: absolute; + font-size: 0.9em; + z-index: 1; +} + +.vjs-slider-vertical .vjs-volume-level { + width: 0.3em; +} +.vjs-slider-vertical .vjs-volume-level:before { + top: -0.5em; + left: -0.3em; + z-index: 1; +} + +.vjs-svg-icons-enabled .vjs-volume-level:before { + content: none; +} + +.vjs-volume-level .vjs-svg-icon { + position: absolute; + width: 0.9em; + height: 0.9em; + pointer-events: none; + z-index: 1; +} + +.vjs-slider-horizontal .vjs-volume-level { + height: 0.3em; +} +.vjs-slider-horizontal .vjs-volume-level:before { + line-height: 0.35em; + right: -0.5em; +} + +.vjs-slider-horizontal .vjs-volume-level .vjs-svg-icon { + right: -0.3em; + transform: translateY(-50%); +} + +.vjs-slider-vertical .vjs-volume-level .vjs-svg-icon { + top: -0.55em; + transform: translateX(-50%); +} + +.video-js .vjs-volume-panel.vjs-volume-panel-vertical { + width: 4em; +} + +.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level { + height: 100%; +} + +.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level { + width: 100%; +} + +.video-js .vjs-volume-vertical { + width: 3em; + height: 8em; + bottom: 8em; + background-color: #2b333f; + background-color: rgba(43, 51, 63, 0.7); +} + +.video-js .vjs-volume-horizontal .vjs-menu { + left: -2em; +} + +.video-js .vjs-volume-tooltip { + background-color: #fff; + background-color: rgba(255, 255, 255, 0.8); + border-radius: 0.3em; + color: #000; + float: right; + font-family: Arial, Helvetica, sans-serif; + font-size: 1em; + padding: 6px 8px 8px 8px; + pointer-events: none; + position: absolute; + top: -3.4em; + visibility: hidden; + z-index: 1; +} + +.video-js .vjs-volume-control:hover .vjs-volume-tooltip, +.video-js + .vjs-volume-control:hover + .vjs-progress-holder:focus + .vjs-volume-tooltip { + display: block; + font-size: 1em; + visibility: visible; +} + +.video-js .vjs-volume-vertical:hover .vjs-volume-tooltip, +.video-js + .vjs-volume-vertical:hover + .vjs-progress-holder:focus + .vjs-volume-tooltip { + left: 1em; + top: -12px; +} + +.video-js .vjs-volume-control.disabled:hover .vjs-volume-tooltip { + font-size: 1em; +} + +.video-js .vjs-volume-control .vjs-mouse-display { + display: none; + position: absolute; + width: 100%; + height: 1px; + background-color: #000; + z-index: 1; +} + +.video-js .vjs-volume-horizontal .vjs-mouse-display { + width: 1px; + height: 100%; +} + +.video-js .vjs-volume-control:hover .vjs-mouse-display { + display: block; +} + +.video-js.vjs-user-inactive .vjs-volume-control .vjs-mouse-display { + visibility: hidden; + opacity: 0; + transition: + visibility 1s, + opacity 1s; +} + +.vjs-mouse-display .vjs-volume-tooltip { + color: #fff; + background-color: #000; + background-color: rgba(0, 0, 0, 0.8); +} + +.vjs-poster { + display: inline-block; + vertical-align: middle; + cursor: pointer; + margin: 0; + padding: 0; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 100%; +} + +.vjs-has-started .vjs-poster, +.vjs-using-native-controls .vjs-poster { + display: none; +} + +.vjs-audio.vjs-has-started .vjs-poster, +.vjs-has-started.vjs-audio-poster-mode .vjs-poster, +.vjs-pip-container.vjs-has-started .vjs-poster { + display: block; +} + +.vjs-poster img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.video-js .vjs-hls-live-control { + display: flex; + align-items: flex-start; + flex: auto; + font-size: 1em; + line-height: 3em; +} + +.video-js:not(.vjs-hls-live) .vjs-hls-live-control, +.video-js.vjs-hls-liveui .vjs-hls-live-control { + display: none; +} + +.video-js .vjs-seek-to-live-control { + align-items: center; + cursor: pointer; + flex: none; + display: inline-flex; + height: 100%; + padding-left: 0.5em; + padding-right: 0.5em; + font-size: 1em; + line-height: 3em; + width: auto; + min-width: 4em; +} + +.video-js.vjs-hls-live:not(.vjs-hls-liveui) .vjs-seek-to-live-control, +.video-js:not(.vjs-hls-live) .vjs-seek-to-live-control { + display: none; +} + +.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge { + cursor: auto; +} + +.vjs-seek-to-live-control .vjs-icon-placeholder { + margin-right: 0.5em; + color: #888; +} + +.vjs-svg-icons-enabled .vjs-seek-to-live-control { + line-height: 0; +} + +.vjs-seek-to-live-control .vjs-svg-icon { + width: 1em; + height: 1em; + pointer-events: none; + fill: #888888; +} + +.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder { + color: red; +} + +.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-svg-icon { + fill: red; +} + +.video-js .vjs-time-control { + flex: none; + font-size: 1em; + line-height: 3em; + min-width: 2em; + width: auto; + padding-left: 1em; + padding-right: 1em; +} + +.vjs-live .vjs-time-control, +.vjs-live .vjs-time-divider, +.vjs-hls-live .vjs-time-control, +.vjs-hls-live .vjs-time-divider, +.video-js .vjs-current-time, +.video-js .vjs-duration { + display: none; +} + +.vjs-time-divider { + display: none; + line-height: 3em; +} + +.vjs-normalise-time-controls:not(.vjs-hls-live) .vjs-time-control { + display: flex; +} + +.video-js .vjs-play-control { + cursor: pointer; +} + +.video-js .vjs-play-control .vjs-icon-placeholder { + flex: none; +} + +.vjs-text-track-display { + position: absolute; + bottom: 3em; + left: 0; + right: 0; + top: 0; + pointer-events: none; +} + +.vjs-error .vjs-text-track-display { + display: none; +} + +.video-js.vjs-controls-disabled .vjs-text-track-display, +.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display { + bottom: 1em; +} + +.video-js .vjs-text-track { + font-size: 1.4em; + text-align: center; + margin-bottom: 0.1em; +} + +.vjs-subtitles { + color: #fff; +} + +.vjs-captions { + color: #fc6; +} + +.vjs-tt-cue { + display: block; +} + +video::-webkit-media-text-track-display { + transform: translateY(-3em); +} + +.video-js.vjs-controls-disabled video::-webkit-media-text-track-display, +.video-js.vjs-user-inactive.vjs-playing + video::-webkit-media-text-track-display { + transform: translateY(-1.5em); +} + +.video-js.vjs-force-center-align-cues .vjs-text-track-cue { + text-align: center !important; + width: 80% !important; +} + +@supports not (inset: 10px) { + .video-js .vjs-text-track-display > div { + top: 0; + right: 0; + bottom: 0; + left: 0; + } +} +.video-js .vjs-picture-in-picture-control { + cursor: pointer; + flex: none; +} +.video-js.vjs-audio-only-mode .vjs-picture-in-picture-control, +.vjs-pip-window .vjs-picture-in-picture-control { + display: none; +} + +.video-js .vjs-fullscreen-control { + cursor: pointer; + flex: none; +} +.video-js.vjs-audio-only-mode .vjs-fullscreen-control, +.vjs-pip-window .vjs-fullscreen-control { + display: none; +} + +.vjs-playback-rate > .vjs-menu-button, +.vjs-playback-rate .vjs-playback-rate-value { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.vjs-playback-rate .vjs-playback-rate-value { + pointer-events: none; + font-size: 1.5em; + line-height: 2; + text-align: center; +} + +.vjs-playback-rate .vjs-menu { + width: 4em; + left: 0em; +} + +.vjs-error .vjs-error-display .vjs-modal-dialog-content { + font-size: 1.4em; + text-align: center; +} + +.vjs-loading-spinner { + display: none; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + opacity: 0.85; + text-align: left; + border: 0.6em solid rgba(43, 51, 63, 0.7); + box-sizing: border-box; + background-clip: padding-box; + width: 5em; + height: 5em; + border-radius: 50%; + visibility: hidden; +} + +.vjs-seeking .vjs-loading-spinner, +.vjs-waiting .vjs-loading-spinner { + display: flex; + justify-content: center; + align-items: center; + animation: vjs-spinner-show 0s linear 0.3s forwards; +} + +.vjs-error .vjs-loading-spinner { + display: none; +} + +.vjs-loading-spinner:before, +.vjs-loading-spinner:after { + content: ""; + position: absolute; + box-sizing: inherit; + width: inherit; + height: inherit; + border-radius: inherit; + opacity: 1; + border: inherit; + border-color: transparent; + border-top-color: white; +} + +.vjs-seeking .vjs-loading-spinner:before, +.vjs-seeking .vjs-loading-spinner:after, +.vjs-waiting .vjs-loading-spinner:before, +.vjs-waiting .vjs-loading-spinner:after { + animation: + vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, + vjs-spinner-fade 1.1s linear infinite; +} + +.vjs-seeking .vjs-loading-spinner:before, +.vjs-waiting .vjs-loading-spinner:before { + border-top-color: rgb(255, 255, 255); +} + +.vjs-seeking .vjs-loading-spinner:after, +.vjs-waiting .vjs-loading-spinner:after { + border-top-color: rgb(255, 255, 255); + animation-delay: 0.44s; +} + +@keyframes vjs-spinner-show { + to { + visibility: visible; + } +} +@keyframes vjs-spinner-spin { + 100% { + transform: rotate(360deg); + } +} +@keyframes vjs-spinner-fade { + 0% { + border-top-color: #73859f; + } + 20% { + border-top-color: #73859f; + } + 35% { + border-top-color: white; + } + 60% { + border-top-color: #73859f; + } + 100% { + border-top-color: #73859f; + } +} +.video-js.vjs-audio-only-mode .vjs-captions-button { + display: none; +} + +.vjs-chapters-button .vjs-menu ul { + width: 24em; +} + +.video-js.vjs-audio-only-mode .vjs-descriptions-button { + display: none; +} + +.vjs-subs-caps-button + .vjs-menu .vjs-captions-menu-item .vjs-svg-icon { + width: 1.5em; + height: 1.5em; +} + +.video-js + .vjs-subs-caps-button + + .vjs-menu + .vjs-captions-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder { + vertical-align: middle; + display: inline-block; + margin-bottom: -0.1em; +} + +.video-js + .vjs-subs-caps-button + + .vjs-menu + .vjs-captions-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder:before { + font-family: VideoJS; + content: "\f10c"; + font-size: 1.5em; + line-height: inherit; +} + +.video-js.vjs-audio-only-mode .vjs-subs-caps-button { + display: none; +} + +.video-js + .vjs-audio-button + + .vjs-menu + .vjs-descriptions-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder, +.video-js + .vjs-audio-button + + .vjs-menu + .vjs-main-desc-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder { + vertical-align: middle; + display: inline-block; + margin-bottom: -0.1em; +} + +.video-js + .vjs-audio-button + + .vjs-menu + .vjs-descriptions-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder:before, +.video-js + .vjs-audio-button + + .vjs-menu + .vjs-main-desc-menu-item + .vjs-menu-item-text + .vjs-icon-placeholder:before { + font-family: VideoJS; + content: " \f12e"; + font-size: 1.5em; + line-height: inherit; +} + +.video-js.vjs-layout-small .vjs-current-time, +.video-js.vjs-layout-small .vjs-time-divider, +.video-js.vjs-layout-small .vjs-duration, +.video-js.vjs-layout-small .vjs-remaining-time, +.video-js.vjs-layout-small .vjs-playback-rate, +.video-js.vjs-layout-small .vjs-volume-control, +.video-js.vjs-layout-x-small .vjs-current-time, +.video-js.vjs-layout-x-small .vjs-time-divider, +.video-js.vjs-layout-x-small .vjs-duration, +.video-js.vjs-layout-x-small .vjs-remaining-time, +.video-js.vjs-layout-x-small .vjs-playback-rate, +.video-js.vjs-layout-x-small .vjs-volume-control, +.video-js.vjs-layout-tiny .vjs-current-time, +.video-js.vjs-layout-tiny .vjs-time-divider, +.video-js.vjs-layout-tiny .vjs-duration, +.video-js.vjs-layout-tiny .vjs-remaining-time, +.video-js.vjs-layout-tiny .vjs-playback-rate, +.video-js.vjs-layout-tiny .vjs-volume-control { + display: none; +} +.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js.vjs-layout-small + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, +.video-js.vjs-layout-small + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover, +.video-js.vjs-layout-x-small + .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js.vjs-layout-x-small + .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js.vjs-layout-x-small + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, +.video-js.vjs-layout-x-small + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover, +.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js.vjs-layout-tiny + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, +.video-js.vjs-layout-tiny + .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover { + width: auto; + width: initial; +} +.video-js.vjs-layout-x-small .vjs-progress-control, +.video-js.vjs-layout-tiny .vjs-progress-control { + display: none; +} +.video-js.vjs-layout-x-small .vjs-custom-control-spacer { + flex: auto; + display: block; +} + +.vjs-modal-dialog.vjs-text-track-settings { + background-color: #2b333f; + background-color: rgba(43, 51, 63, 0.75); + color: #fff; + height: 70%; +} +.vjs-spatial-navigation-enabled .vjs-modal-dialog.vjs-text-track-settings { + height: 80%; +} + +.vjs-error .vjs-text-track-settings { + display: none; +} + +.vjs-text-track-settings .vjs-modal-dialog-content { + display: table; +} + +.vjs-text-track-settings .vjs-track-settings-colors, +.vjs-text-track-settings .vjs-track-settings-font, +.vjs-text-track-settings .vjs-track-settings-controls { + display: table-cell; +} + +.vjs-text-track-settings .vjs-track-settings-controls { + text-align: right; + vertical-align: bottom; +} + +@supports (display: grid) { + .vjs-text-track-settings .vjs-modal-dialog-content { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; + padding: 20px 24px 0px 24px; + } + .vjs-track-settings-controls .vjs-default-button { + margin-bottom: 20px; + } + .vjs-text-track-settings .vjs-track-settings-controls { + grid-column: 1/-1; + } + .vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content, + .vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content, + .vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content { + grid-template-columns: 1fr; + } +} +.vjs-text-track-settings select { + font-size: inherit; +} + +.vjs-track-setting > select { + margin-right: 1em; + margin-bottom: 0.5em; +} + +.vjs-text-track-settings fieldset { + margin: 10px; + border: none; +} + +.vjs-text-track-settings fieldset span { + display: inline-block; + padding: 0 0.6em 0.8em; +} + +.vjs-text-track-settings fieldset span > select { + max-width: 7.3em; +} + +.vjs-text-track-settings legend { + color: #fff; + font-weight: bold; + font-size: 1.2em; +} + +.vjs-text-track-settings .vjs-label { + margin: 0 0.5em 0.5em 0; +} + +.vjs-track-settings-controls button:focus, +.vjs-track-settings-controls button:active { + outline-style: solid; + outline-width: medium; + background-image: linear-gradient(0deg, #fff 88%, #73859f 100%); +} + +.vjs-track-settings-controls button:hover { + color: rgba(43, 51, 63, 0.75); +} + +.vjs-track-settings-controls button { + background-color: #fff; + background-image: linear-gradient(-180deg, #fff 88%, #73859f 100%); + color: #2b333f; + cursor: pointer; + border-radius: 2px; +} + +.vjs-track-settings-controls .vjs-default-button { + margin-right: 1em; +} + +.vjs-title-bar { + background: rgba(0, 0, 0, 0.9); + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0.9) 0%, + rgba(0, 0, 0, 0.7) 60%, + rgba(0, 0, 0, 0) 100% + ); + font-size: 1.2em; + line-height: 1.5; + transition: opacity 0.1s; + padding: 0.666em 1.333em 4em; + pointer-events: none; + position: absolute; + top: 0; + width: 100%; +} + +.vjs-error .vjs-title-bar { + display: none; +} + +.vjs-title-bar-title, +.vjs-title-bar-description { + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.vjs-title-bar-title { + font-weight: bold; + margin-bottom: 0.333em; +} + +.vjs-playing.vjs-user-inactive .vjs-title-bar { + opacity: 0; + transition: opacity 1s; +} + +.video-js .vjs-skip-forward-5 { + cursor: pointer; +} +.video-js .vjs-skip-forward-10 { + cursor: pointer; +} +.video-js .vjs-skip-forward-30 { + cursor: pointer; +} +.video-js .vjs-skip-backward-5 { + cursor: pointer; +} +.video-js .vjs-skip-backward-10 { + cursor: pointer; +} +.video-js .vjs-skip-backward-30 { + cursor: pointer; +} +.video-js .vjs-transient-button { + position: absolute; + height: 3em; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(50, 50, 50, 0.5); + cursor: pointer; + opacity: 1; + transition: opacity 1s; +} + +.video-js:not(.vjs-has-started) .vjs-transient-button { + display: none; +} + +.video-js.not-hover .vjs-transient-button:not(.force-display), +.video-js.vjs-user-inactive .vjs-transient-button:not(.force-display) { + opacity: 0; +} + +.video-js .vjs-transient-button span { + padding: 0 0.5em; +} + +.video-js .vjs-transient-button.vjs-left { + left: 1em; +} + +.video-js .vjs-transient-button.vjs-right { + right: 1em; +} + +.video-js .vjs-transient-button.vjs-top { + top: 1em; +} + +.video-js .vjs-transient-button.vjs-near-top { + top: 4em; +} + +.video-js .vjs-transient-button.vjs-bottom { + bottom: 4em; +} + +.video-js .vjs-transient-button:hover { + background-color: rgba(50, 50, 50, 0.9); +} + +@media print { + .video-js > *:not(.vjs-tech):not(.vjs-poster) { + visibility: hidden; + } +} +.vjs-resize-manager { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: none; + z-index: -1000; +} + +.js-focus-visible .video-js *:focus:not(.focus-visible) { + outline: none; +} + +.video-js *:focus:not(:focus-visible) { + outline: none; +} diff --git a/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts b/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts new file mode 100644 index 0000000..3bacda5 --- /dev/null +++ b/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts @@ -0,0 +1,4 @@ +import { IVideoJSProps } from "./types"; +declare const VideoJS: ({ options, classNames, onReady, className, initialTime, full, withRewind, }: IVideoJSProps) => import("react/jsx-runtime").JSX.Element; +export default VideoJS; +//# sourceMappingURL=hls-or-videojs-player.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts.map b/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts.map new file mode 100644 index 0000000..d8c3292 --- /dev/null +++ b/dist/react/video-player/components/video-js/hls-or-videojs-player.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"hls-or-videojs-player.d.ts","sourceRoot":"","sources":["../../../../../src/react/video-player/components/video-js/hls-or-videojs-player.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAiB,MAAM,SAAS,CAAC;AAIvD,QAAA,MAAM,OAAO,GAAI,6EAQd,aAAa,4CA6Ff,CAAC;AAEF,eAAe,OAAO,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/hls-or-videojs-player.js b/dist/react/video-player/components/video-js/hls-or-videojs-player.js new file mode 100644 index 0000000..1a8467a --- /dev/null +++ b/dist/react/video-player/components/video-js/hls-or-videojs-player.js @@ -0,0 +1,89 @@ +"use client"; +import { jsx as _jsx } from "react/jsx-runtime"; +import cn from "classnames"; +import styles from "./videojs.module.scss"; +import { useEffect, useMemo, useRef } from "react"; +import { isIOS, isMobile } from "react-device-detect"; +import { VideoPlayerRuntime, } from "../../../../core"; +const DEFAULT_SOURCE_TYPE = "application/x-mpegurl"; +const VideoJS = ({ options, classNames = [], onReady, className, initialTime = 0, full = false, withRewind = true, }) => { + const videoContainerRef = useRef(null); + const runtimeRef = useRef(null); + const onReadyRef = useRef(onReady); + useEffect(() => { + onReadyRef.current = onReady; + }, [onReady]); + const runtimeOptions = useMemo(() => { + const source = options.sources?.[0]; + return { + source: { + src: source?.src ?? "", + type: source?.type ?? DEFAULT_SOURCE_TYPE, + }, + strategy: "auto", + preload: options.preload, + autoplay: options.autoplay, + controls: options.controls, + responsive: options.responsive, + aspectRatio: options.aspectRatio, + fluid: options.fluid, + muted: options.muted, + poster: options.poster, + preferHQ: options.preferHQ ?? false, + debug: options.debug ?? false, + initialTime, + isIOS, + isMobile, + full, + withRewind, + skipSeconds: 10, + classNames, + onPlayerReady: player => { + onReadyRef.current?.(player); + }, + }; + }, [ + options.sources, + options.preload, + options.autoplay, + options.controls, + options.responsive, + options.aspectRatio, + options.fluid, + options.muted, + options.poster, + options.preferHQ, + options.debug, + initialTime, + full, + withRewind, + classNames, + ]); + useEffect(() => { + const container = videoContainerRef.current; + if (!container || runtimeRef.current) { + return; + } + const runtime = new VideoPlayerRuntime(); + runtimeRef.current = runtime; + void runtime.init({ + container, + ...runtimeOptions, + }); + return () => { + runtime.dispose(); + runtimeRef.current = null; + }; + // init once; subsequent prop updates go through runtime.update + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + useEffect(() => { + if (!runtimeRef.current) { + return; + } + void runtimeRef.current.update(runtimeOptions); + }, [runtimeOptions]); + return (_jsx("div", { className: cn([styles.player, className]), "data-vjs-player": true, children: _jsx("div", { ref: videoContainerRef, className: cn([styles.player, className]) }) })); +}; +export default VideoJS; +//# sourceMappingURL=hls-or-videojs-player.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/hls-or-videojs-player.js.map b/dist/react/video-player/components/video-js/hls-or-videojs-player.js.map new file mode 100644 index 0000000..e331ec3 --- /dev/null +++ b/dist/react/video-player/components/video-js/hls-or-videojs-player.js.map @@ -0,0 +1 @@ +{"version":3,"file":"hls-or-videojs-player.js","sourceRoot":"","sources":["../../../../../src/react/video-player/components/video-js/hls-or-videojs-player.tsx"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/index.d.ts b/dist/react/video-player/components/video-js/index.d.ts new file mode 100644 index 0000000..257ce8b --- /dev/null +++ b/dist/react/video-player/components/video-js/index.d.ts @@ -0,0 +1,3 @@ +import SelectPlayer from "./hls-or-videojs-player"; +export default SelectPlayer; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/index.d.ts.map b/dist/react/video-player/components/video-js/index.d.ts.map new file mode 100644 index 0000000..3ff7d96 --- /dev/null +++ b/dist/react/video-player/components/video-js/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/react/video-player/components/video-js/index.tsx"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAEnD,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/index.js b/dist/react/video-player/components/video-js/index.js new file mode 100644 index 0000000..62f1a49 --- /dev/null +++ b/dist/react/video-player/components/video-js/index.js @@ -0,0 +1,3 @@ +import SelectPlayer from "./hls-or-videojs-player"; +export default SelectPlayer; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/index.js.map b/dist/react/video-player/components/video-js/index.js.map new file mode 100644 index 0000000..c11b4ad --- /dev/null +++ b/dist/react/video-player/components/video-js/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/react/video-player/components/video-js/index.tsx"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAEnD,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts new file mode 100644 index 0000000..852934e --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts @@ -0,0 +1,4 @@ +import Player from "video.js/dist/types/player"; +declare function bigPlayPauseButtonPlugin(this: Player): void; +export default bigPlayPauseButtonPlugin; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts.map new file mode 100644 index 0000000..fb52209 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/big-play-pause-button/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAkBhD,iBAAS,wBAAwB,CAAC,IAAI,EAAE,MAAM,QAO7C;AAID,eAAe,wBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js new file mode 100644 index 0000000..7b19095 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js @@ -0,0 +1,26 @@ +import videojs from "video.js"; +const BigPlayButton = videojs.getComponent("BigPlayButton"); +class BigPlayPauseButton extends BigPlayButton { + handleClick(e) { + const player = this.player(); + if (player.paused()) { + player.play(); + } + else { + player.pause(); + } + } +} +videojs.registerComponent("BigPlayPauseButton", BigPlayPauseButton); +// Функция плагина с аннотацией типа this +function bigPlayPauseButtonPlugin() { + const player = this; + const defaultButton = player.getChild("bigPlayButton"); + if (defaultButton) { + defaultButton.dispose(); + } + player.addChild("BigPlayPauseButton", {}); +} +videojs.registerPlugin("bigPlayPauseButton", bigPlayPauseButtonPlugin); +export default bigPlayPauseButtonPlugin; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js.map b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js.map new file mode 100644 index 0000000..4c4865c --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/big-play-pause-button/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/big-play-pause-button/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAG/B,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;AAE5D,MAAM,kBAAmB,SAAQ,aAAa;IAC7C,WAAW,CAAC,CAAmB;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAY,CAAC;QAEvC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACF,CAAC;CACD;AAED,OAAO,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;AACpE,yCAAyC;AACzC,SAAS,wBAAwB;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACvD,IAAI,aAAa,EAAE,CAAC;QACnB,aAAa,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,OAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC;AAEvE,eAAe,wBAAwB,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts new file mode 100644 index 0000000..3eca6f0 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts @@ -0,0 +1,38 @@ +import Component from "video.js/dist/types/component"; +import Player from "video.js/dist/types/player"; +import TachVideoMenu from "../tach-video-menu"; +import TachVideoMenuItem from "../tach-video-menu-item"; +declare const MenuButton: typeof Component; +export default class TachVideoMenuButton extends MenuButton { + private hideThreshold_; + private buttonPressed_; + private menu; + private menuButton_; + items: TachVideoMenuItem[]; + /** + * Button constructor. + * + * @param {Player} player - videojs player instance + */ + constructor(player: Player, title: string, name: string); + /** + * Creates button items. + * + * @return {TachVideoMenuItem[]} - Button items + */ + createItems(): TachVideoMenuItem[]; + /** + * Создаёт меню и добавляет в него все пункты. + * + * @return {Menu} - Сконструированное меню + */ + createMenu(): TachVideoMenu; + /** + * Обновление меню без его пересоздания. + * + * @return {Menu} - Обновлённое меню + */ + update(): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts.map new file mode 100644 index 0000000..7c243d7 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,+BAA+B,CAAC;AACtD,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AAExD,QAAA,MAAM,UAAU,kBAAqC,CAAC;AAStD,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,UAAU;IAC1D,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,WAAW,CAAa;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAM;IAEvC;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAiBvD;;;;OAIG;IACH,WAAW,IAAI,iBAAiB,EAAE;IAIlC;;;;OAIG;IACH,UAAU;IAsBV;;;;OAIG;IACH,MAAM;CA6BN"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js new file mode 100644 index 0000000..abc713d --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js @@ -0,0 +1,90 @@ +import videojs from "video.js"; +import TachVideoMenu from "../tach-video-menu"; +const MenuButton = videojs.getComponent("MenuButton"); +const Menu = videojs.getComponent("Menu"); +export default class TachVideoMenuButton extends MenuButton { + /** + * Button constructor. + * + * @param {Player} player - videojs player instance + */ + constructor(player, title, name) { + super(player, { + title: title, + name: name, + }); + this.hideThreshold_ = 0; + this.buttonPressed_ = false; + this.items = []; + // Перехватываем событие 'mouseenter' на уровне захвата и предотвращаем его дальнейшее распространение + const el = this.menuButton_.el(); + el.addEventListener("mouseenter", e => { + e.stopImmediatePropagation(); + }, true); + } + /** + * Creates button items. + * + * @return {TachVideoMenuItem[]} - Button items + */ + createItems() { + return []; + } + /** + * Создаёт меню и добавляет в него все пункты. + * + * @return {Menu} - Сконструированное меню + */ + createMenu() { + const menu = new TachVideoMenu(this.player_, { + menuButton: this, + }); + this.hideThreshold_ = 0; + this.items = this.createItems(); + if (this.items) { + // Если метод updateItems присутствует, используем его для обновления списка + if (typeof menu.updateItems === "function") { + menu.updateItems(this.items); + } + else { + // Если по какой-то причине обновление недоступно, добавляем элементы по одному + this.items.forEach(item => menu.addItem(item)); + } + } + return menu; + } + /** + * Обновление меню без его пересоздания. + * + * @return {Menu} - Обновлённое меню + */ + update() { + // Если меню уже создано и поддерживает updateItems, обновляем его содержимое + if (this.menu && typeof this.menu.updateItems === "function") { + this.items = this.createItems(); + this.menu.updateItems(this.items); + } + else { + // Если меню ещё не создано, создаём его + this.menu = this.createMenu(); + } + this.addChild(this.menu); + /** + * Track the state of the menu button + * + * @type {Boolean} + * @private + */ + this.buttonPressed_ = false; + this.menuButton_.el_.setAttribute("aria-expanded", "false"); + if (this.items && this.items?.length <= this.hideThreshold_) { + this.hide(); + this.menu.contentEl().removeAttribute("role"); + } + else { + this.show(); + this.menu.contentEl().setAttribute("role", "menu"); + } + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js.map new file mode 100644 index 0000000..e21eb5b --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu-button/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts new file mode 100644 index 0000000..73fee41 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts @@ -0,0 +1,33 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions, TachPlayerPlugin } from "../../types"; +import TachVideoMenuButton from "../tach-video-menu-button"; +declare const VideoJsMenuItemClass: typeof import("video.js/dist/types/component").default; +export interface ITachPlayerMenuItem extends TachPlayerMenuItemOptions { + onClick: () => void; + enabled?: boolean; + value?: unknown; +} +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenuItem extends VideoJsMenuItemClass { + private item; + private button; + private plugin; + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {ITachVideoMenuItem} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player: Player, item: ITachPlayerMenuItem, button: TachVideoMenuButton, plugin: TachPlayerPlugin); + /** + * Click event for menu item. + */ + handleClick(): void; + selected(val: boolean): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts.map new file mode 100644 index 0000000..b1ff1b4 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAG5D,QAAA,MAAM,oBAAoB,wDAAmC,CAAC;AAG9D,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACrE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,oBAAoB;IAClE,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAmB;IAEjC;;;;;;;OAOG;gBAEF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,gBAAgB;IAczB;;OAEG;IACH,WAAW;IAWX,QAAQ,CAAC,GAAG,EAAE,OAAO;CAIrB"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js new file mode 100644 index 0000000..e8f3e8d --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js @@ -0,0 +1,45 @@ +import videojs from "video.js"; +// Concrete classes +const VideoJsMenuItemClass = videojs.getComponent("MenuItem"); +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenuItem extends VideoJsMenuItemClass { + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {ITachVideoMenuItem} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player, item, button, plugin) { + super(player, { + label: item.label, + selectable: item.selectable || true, + selected: item.selected || false, + }); + this.item = item; + this.button = button; + this.plugin = plugin; + item.className && this.addClass(item.className); + } + /** + * Click event for menu item. + */ + handleClick() { + if (this.item.onClick) { + // Reset other menu items selected status. + for (let i = 0; i < this.button.items?.length; ++i) { + this.button.items[i].selected(false); + } + this.selected(true); + return this.item.onClick(); + } + } + selected(val) { + //@ts-expect-error // getComponent reduant + super.selected(val); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js.map new file mode 100644 index 0000000..eb1dd83 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu-item/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAM/B,mBAAmB;AACnB,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;AAS9D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,oBAAoB;IAKlE;;;;;;;OAOG;IACH,YACC,MAAc,EACd,IAAyB,EACzB,MAA2B,EAC3B,MAAwB;QAExB,KAAK,CAAC,MAAM,EAAE;YACb,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;SACzB,CAAC,CAAC;QACV,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,WAAW;QACV,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvB,0CAA0C;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;gBACpD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;IACF,CAAC;IAED,QAAQ,CAAC,GAAY;QACpB,0CAA0C;QAC1C,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;CACD"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts new file mode 100644 index 0000000..409c59e --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts @@ -0,0 +1,33 @@ +import Player from "video.js/dist/types/player"; +import TachVideoMenuButton from "../tach-video-menu-button"; +import TachVideoMenuItem from "../tach-video-menu-item"; +declare const VideoJsMenuClass: typeof import("video.js/dist/types/component").default; +type BaseMenuOptions = ConstructorParameters[1]; +interface TachMenuOptions extends NonNullable { + menuButton: TachVideoMenuButton; +} +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenu extends VideoJsMenuClass { + private menuOpened_; + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {TachPlayerMenuItemOptions} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player: Player, options: TachMenuOptions); + hide(): void; + show(): void; + addItem(item: TachVideoMenuItem): void; + /** + * Обновляет пункты меню. + * @param {Array} newItems - Массив новых компонентов или их имён, которые будут добавлены в меню. + */ + updateItems(newItems: TachVideoMenuItem[]): void; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts.map new file mode 100644 index 0000000..dc20097 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAC5D,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AAGxD,QAAA,MAAM,gBAAgB,wDAA+B,CAAC;AAMtD,KAAK,eAAe,GAAG,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,UAAU,eAAgB,SAAQ,WAAW,CAAC,eAAe,CAAC;IAC7D,UAAU,EAAE,mBAAmB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,gBAAgB;IAC1D,OAAO,CAAC,WAAW,CAAkB;IACrC;;;;;;;OAOG;gBACS,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe;IAUpD,IAAI;IAMJ,IAAI;IAMJ,OAAO,CAAC,IAAI,EAAE,iBAAiB;IAK/B;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,iBAAiB,EAAE;CAczC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js new file mode 100644 index 0000000..8e1caa8 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js @@ -0,0 +1,56 @@ +import videojs from "video.js"; +// Concrete classes +const VideoJsMenuClass = videojs.getComponent("Menu"); +/** + * Extend vjs menu item class. + */ +export default class TachVideoMenu extends VideoJsMenuClass { + /** + * Menu item constructor. + * + * @param {Player} player - vjs player + * @param {TachPlayerMenuItemOptions} item - Item object + * @param {ConcreteButton} button - The containing button. + * @param {TachPlayerPlugin} plugin - This plugin instance. + */ + constructor(player, options) { + super(player, options); + this.menuOpened_ = false; + player.on("userinactive", () => { + if (this.menuOpened_) { + player.userActive(true); + } + }); + } + hide() { + this.menuOpened_ = false; + // Вызов родительского метода скрытия + super.hide(); + } + show() { + this.menuOpened_ = true; + // Вызов родительского метода скрытия + super.show(); + } + addItem(item) { + //@ts-expect-error getComponent reduant method + super.addItem(item); + } + /** + * Обновляет пункты меню. + * @param {Array} newItems - Массив новых компонентов или их имён, которые будут добавлены в меню. + */ + updateItems(newItems) { + // Получаем текущих потомков + const currentChildren = this.children().slice(); + // Удаляем все остальные дочерние компоненты. + currentChildren.forEach(child => { + this.removeChild(child); + }); + // Добавляем новые пункты меню. + newItems.forEach(item => { + this.addItem(item); + }); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js.map b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js.map new file mode 100644 index 0000000..2a1920b --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/components/tach-video-menu/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../src/react/video-player/components/video-js/plugins/components/tach-video-menu/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAC;AAM/B,mBAAmB;AACnB,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAWtD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,gBAAgB;IAE1D;;;;;;;OAOG;IACH,YAAY,MAAc,EAAE,OAAwB;QACnD,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAVhB,gBAAW,GAAY,KAAK,CAAC;QAYpC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,IAAI;QACH,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,qCAAqC;QACrC,KAAK,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,IAAI;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,qCAAqC;QACrC,KAAK,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAuB;QAC9B,8CAA8C;QAC9C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,QAA6B;QACxC,4BAA4B;QAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC;QAEhD,6CAA6C;QAC7C,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC/B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/index.d.ts b/dist/react/video-player/components/video-js/plugins/settings/index.d.ts new file mode 100644 index 0000000..599d4e2 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/index.d.ts @@ -0,0 +1,52 @@ +import Component from "video.js/dist/types/component"; +import Plugin from "video.js/dist/types/plugin"; +import "./settings.css"; +import { VideoJsPlayer } from "../../types"; +interface SettingsButtonOptions { +} +interface PlayerWithControlBar extends VideoJsPlayer { + controlBar: Component; +} +declare const BasePlugin: typeof Plugin; +declare class SettingsButton extends BasePlugin { + private options; + private mainMenu; + private settingsButton; + private buttonInstance; + private backButton; + private playbackRateButton; + private qualityRateButton; + private audioTracksButton; + private textTracksButton; + constructor(player: PlayerWithControlBar, options: SettingsButtonOptions); + /** + * Инициализация плагина: создание кнопки настроек и привязка событий + */ + private initialize; + /** + * Привязка событий плеера (например, для обновления меню) + */ + private bindPlayerEvents; + /** + * Создание кнопки настроек и определение пунктов меню. + * Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню. + */ + private createSettingsButton; + /** + * Обёртка для создания экземпляра пункта меню. + * + * @param item - объект настроек пункта меню + * @returns экземпляр TachVideoMenuItem + */ + private getMenuItem; + /** + * Устанавливает (обновляет) пункты меню плагина. + * + * @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию) + * @param skipBackButton - если true, не добавлять кнопку "Назад" + * @param forceShow - если true, принудительно показать меню после обновления + */ + private setMenu; +} +export default SettingsButton; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/settings/index.d.ts.map new file mode 100644 index 0000000..859fa30 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/settings/index.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,+BAA+B,CAAC;AAEtD,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAYhD,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,UAAU,qBAAqB;CAE9B;AAGD,UAAU,oBAAqB,SAAQ,aAAa;IACnD,UAAU,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,UAAU,EAAmC,OAAO,MAAM,CAAC;AAKjE,cAAM,cAAe,SAAQ,UAAU;IACtC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAa;IAGnC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,qBAAqB;IAMxE;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA8D5B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;OAMG;YACW,OAAO;CA8CrB;AAID,eAAe,cAAc,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/index.js b/dist/react/video-player/components/video-js/plugins/settings/index.js new file mode 100644 index 0000000..799f81f --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/index.js @@ -0,0 +1,141 @@ +import videojs from "video.js"; +import TachVideoMenuButton from "../components/tach-video-menu-button"; +import TachVideoMenuItem from "../components/tach-video-menu-item"; +import audioTrackSelector from "./selectors/audio-track-selector"; +import playbackRateSelector from "./selectors/playback-rate-selector"; +import qualityRateSelector from "./selectors/quality-rate-selector"; +import textTracksSelector from "./selectors/text-track-selector"; +import "./settings.css"; +const BasePlugin = videojs.getPlugin("plugin"); +// Значения опций по умолчанию +const defaults = {}; +class SettingsButton extends BasePlugin { + constructor(player, options) { + super(player); + this.mainMenu = []; + this.options = videojs.obj.merge(defaults, options); + this.player.ready(() => this.initialize()); + } + /** + * Инициализация плагина: создание кнопки настроек и привязка событий + */ + initialize() { + this.createSettingsButton(); + this.bindPlayerEvents(); + } + /** + * Привязка событий плеера (например, для обновления меню) + */ + bindPlayerEvents() { + // При необходимости можно привязать событие, например: + // this.settingsButton.on("click", this.setMenu.bind(this, undefined, false, true)); + } + /** + * Создание кнопки настроек и определение пунктов меню. + * Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню. + */ + createSettingsButton() { + const player = this.player; + // Создаем кнопку настроек с помощью компонента TachVideoMenuButton + this.settingsButton = new TachVideoMenuButton(player, "Settings", "Settings"); + this.buttonInstance = player.controlBar.addChild(this.settingsButton, { + componentClass: "settingsButton", + }); + this.buttonInstance.addClass("vjs-settings-button"); + // Определяем кнопку "Назад" для возврата в главное меню + this.backButton = { + label: "Назад", + value: this.mainMenu, + selectable: false, + selected: false, + onClick: () => this.setMenu(undefined, true, true), + className: "settings-back", + }; + // Создаем фабрики для дополнительных настроек + const { menuItem: audioMenuItem, menuItems: audioMenuItems } = audioTrackSelector(player); + this.audioTracksButton = () => ({ + ...audioMenuItem(), + onClick: () => this.setMenu(audioMenuItems(), false, true), + }); + const { menuItem: textMenuItem, menuItems: textMenuItems } = textTracksSelector(player); + this.textTracksButton = () => ({ + ...textMenuItem(), + onClick: () => this.setMenu(textMenuItems(), false, true), + }); + const { menuItem: playbackMenuItem, menuItems: playbackMenuItems } = playbackRateSelector(player); + this.playbackRateButton = () => ({ + ...playbackMenuItem(), + onClick: () => this.setMenu(playbackMenuItems(), false, true), + }); + // В createSettingsButton замени этот участок: + const qualitySelector = qualityRateSelector(player); + this.qualityRateButton = () => ({ + ...qualitySelector.menuItem(), // пересоздание при каждом открытии меню + onClick: () => this.setMenu(qualitySelector.menuItems(), false, true), + }); + // Подписка на автообновление, когда hls переключает уровень + qualitySelector.setMenuUpdateCallback(() => { + this.setMenu(undefined, true); // Обновить главное меню без перезахода + }); + // Инициализируем меню с кнопками по умолчанию без показа + this.setMenu(undefined, true, false); + } + /** + * Обёртка для создания экземпляра пункта меню. + * + * @param item - объект настроек пункта меню + * @returns экземпляр TachVideoMenuItem + */ + getMenuItem(item) { + return new TachVideoMenuItem(this.player, item, this.settingsButton, this); + } + /** + * Устанавливает (обновляет) пункты меню плагина. + * + * @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию) + * @param skipBackButton - если true, не добавлять кнопку "Назад" + * @param forceShow - если true, принудительно показать меню после обновления + */ + async setMenu(items = [], skipBackButton = false, forceShow = false) { + const menuButtons = []; + if (!skipBackButton) { + menuButtons.push(this.backButton); + } + if (items?.length === 0) { + // Если не переданы конкретные пункты меню – используем кнопки по умолчанию + const defaultButtons = [ + this.playbackRateButton, + this.qualityRateButton, + this.textTracksButton, + this.audioTracksButton, + ]; + defaultButtons.forEach(createButton => { + const btn = createButton(); + if (btn.enabled) { + menuButtons.push(btn); + } + }); + } + else { + menuButtons.push(...items); + } + // Формируем список пунктов меню: вместо пересоздания меню, назначаем функцию, + // возвращающую актуальный список пунктов, и вызываем метод обновления. + this.settingsButton.createItems = () => menuButtons.map(item => this.getMenuItem(item)); + await this.settingsButton.update(); + // Если требуется принудительно показать меню, эмулируем клик по кнопке меню + if (forceShow) { + const menuElement = this.buttonInstance.el().querySelector(".vjs-menu"); + const menuButton = this.buttonInstance + .el() + .querySelector(".vjs-menu-button"); + if (menuElement && menuButton) { + menuButton.click(); + } + } + } +} +// Регистрируем плагин в Video.js +videojs.registerPlugin("settingsMenu", SettingsButton); +export default SettingsButton; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/index.js.map b/dist/react/video-player/components/video-js/plugins/settings/index.js.map new file mode 100644 index 0000000..4cbf6e9 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/settings/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts new file mode 100644 index 0000000..9cc2e5d --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts @@ -0,0 +1,27 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../../types"; +interface TrackMenuOptions extends TachPlayerMenuItemOptions { +} +declare const audioTrack: (player: Player, options?: TrackMenuOptions) => { + menuItems: () => { + label: string; + value: number; + selected: boolean; + onClick: () => void; + }[] | { + label: string; + value: string | undefined; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + value: string | null; + enabled: boolean; + label: string; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default audioTrack; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts.map new file mode 100644 index 0000000..7c0fca3 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAS3D,UAAU,gBAAiB,SAAQ,yBAAyB;CAAG;AAe/D,QAAA,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,UAAS,gBAA2B;;;;;;;;;;;;;;;;;;;;CAmJvE,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js new file mode 100644 index 0000000..2d5db34 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js @@ -0,0 +1,125 @@ +const defaults = { + label: "Язык", + selected: false, + selectable: false, + className: "audio-selector", +}; +const audioTrack = (player, options = defaults) => { + const playerWithTracks = player; + const getNativeTrackList = () => { + if (typeof playerWithTracks.audioTracks !== "function") { + return undefined; + } + return playerWithTracks.audioTracks(); + }; + const getNativeTracks = () => { + return getNativeTrackList()?.tracks_ ?? []; + }; + const setNativeTrack = (track) => { + const audioTracks = getNativeTracks(); + for (let i = 0; i < audioTracks.length; ++i) { + audioTracks[i].enabled = audioTracks[i] === track; + } + }; + const getSelectedNativeTrack = () => { + const audioTracks = getNativeTracks(); + for (let i = 0; i < audioTracks.length; ++i) { + if (audioTracks[i].enabled === true) { + return audioTracks[i]; + } + } + return null; + }; + const getHlsInstance = () => playerWithTracks.hlsInstance ?? null; + const getHlsTracks = () => { + const hls = getHlsInstance(); + return hls?.audioTracks ?? []; + }; + const setHlsTrack = (trackId) => { + const hls = getHlsInstance(); + if (!hls) + return; + hls.audioTrack = trackId; + }; + const getSelectedHlsTrack = () => { + const hls = getHlsInstance(); + if (!hls) + return null; + const tracks = getHlsTracks(); + const currentId = hls.audioTrack; + return tracks.find(track => track.id === currentId) ?? null; + }; + const formatHlsTrackLabel = (track, index) => { + if (track.name?.trim()) { + return track.name.trim(); + } + if (track.lang?.trim()) { + return track.lang.trim().toUpperCase(); + } + const fallbackIndex = typeof index === "number" + ? index + 1 + : typeof track.id === "number" + ? track.id + 1 + : 1; + return `Дорожка ${fallbackIndex}`; + }; + const buildHlsMenuItems = () => { + const hls = getHlsInstance(); + const hlsTracks = getHlsTracks(); + if (!hls || hlsTracks.length === 0) { + return []; + } + return hlsTracks.map((track, index) => ({ + label: formatHlsTrackLabel(track, index), + value: track.id, + selected: track.id === hls.audioTrack, + onClick: () => setHlsTrack(track.id), + })); + }; + const hasAudioTracks = () => { + if (getHlsTracks().length > 0) { + return true; + } + return getNativeTracks().length > 0; + }; + const menuItems = () => { + const hlsTracks = buildHlsMenuItems(); + if (hlsTracks.length > 0) { + return hlsTracks; + } + const nativeTracks = getNativeTracks(); + const trackItems = []; + for (let i = 0; i < nativeTracks?.length; ++i) { + const trackItem = { + label: nativeTracks[i].label || "Default", + value: nativeTracks[i].label, + selected: nativeTracks[i].enabled, + onClick: () => setNativeTrack(nativeTracks[i]), + }; + trackItems.push(trackItem); + } + return trackItems; + }; + const getSelectedTrackLabel = () => { + const selectedHlsTrack = getSelectedHlsTrack(); + if (selectedHlsTrack) { + const tracks = getHlsTracks(); + const index = tracks.findIndex(track => track.id === selectedHlsTrack.id); + return formatHlsTrackLabel(selectedHlsTrack, index); + } + return getSelectedNativeTrack()?.label ?? null; + }; + const menuItem = () => { + return { + ...options, + value: getSelectedTrackLabel(), + enabled: hasAudioTracks(), + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default audioTrack; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js.map new file mode 100644 index 0000000..e3806e4 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/audio-track-selector/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts new file mode 100644 index 0000000..c34e16f --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts @@ -0,0 +1,30 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../../types"; +interface SpeedMenuOptions extends TachPlayerMenuItemOptions { + speeds: Array<{ + label: string; + value: number; + }>; +} +declare const playbackRate: (player: Player, options?: SpeedMenuOptions) => { + menuItems: () => { + label: string; + selectable: boolean; + selected: boolean; + onClick: () => number | undefined; + }[]; + menuItem: () => { + enabled: boolean; + speeds: Array<{ + label: string; + value: number; + }>; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default playbackRate; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts.map new file mode 100644 index 0000000..52aab1a --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAgB3D,UAAU,gBAAiB,SAAQ,yBAAyB;IAC3D,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,QAAA,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,UAAS,gBAA2B;;;;;;;;;gBAHjE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;;;;;;;CAwB/C,CAAC;AAEF,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js new file mode 100644 index 0000000..967d51f --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js @@ -0,0 +1,35 @@ +const defaults = { + label: "Скорость воспроизведения", + selected: false, + selectable: false, + speeds: [ + { label: "0.5x", value: 0.5 }, + { label: "Обычная", value: 1 }, + { label: "1.5x", value: 1.5 }, + { label: "1.75x", value: 1.75 }, + { label: "2x", value: 2 }, + ], + className: "speed-selector", +}; +const playbackRate = (player, options = defaults) => { + const menuItems = () => options.speeds.map(speed => { + return { + label: speed.label, + selectable: true, + selected: speed.value === player.playbackRate(), + onClick: () => player.playbackRate(speed.value), + }; + }); + const menuItem = () => { + return { + ...options, + enabled: true, + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default playbackRate; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js.map new file mode 100644 index 0000000..b190ff6 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/playback-rate-selector/index.ts"],"names":[],"mappings":"AAIA,MAAM,QAAQ,GAAG;IAChB,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE;QACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;QAC7B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE;QAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;QAC7B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;QAC/B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE;KACzB;IACD,SAAS,EAAE,gBAAgB;CAC3B,CAAC;AAMF,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,UAA4B,QAAQ,EAAE,EAAE;IAC7E,MAAM,SAAS,GAAG,GAAG,EAAE,CACtB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC1B,OAAO;YACN,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,YAAY,EAAE;YAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;SAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,OAAO;YACN,GAAG,OAAO;YACV,OAAO,EAAE,IAAI;SACb,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACN,SAAS;QACT,QAAQ;KACR,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts new file mode 100644 index 0000000..473625c --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts @@ -0,0 +1,39 @@ +import Player from "video.js/dist/types/player"; +import { TachPlayerMenuItemOptions } from "../../../types"; +interface QualityMenuOptions extends TachPlayerMenuItemOptions { +} +declare const qualityRate: (player: Player, options?: QualityMenuOptions) => { + menuItems: () => { + label: string; + value: string; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; + setMenuUpdateCallback: () => void; +} | { + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; + menuItems: () => { + label: string; + value: number; + selected: boolean; + onClick: () => void; + }[]; + setMenuUpdateCallback: (cb: () => void) => void; +}; +export default qualityRate; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts.map new file mode 100644 index 0000000..4f13c50 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAgB3D,UAAU,kBAAmB,SAAQ,yBAAyB;CAAG;AAEjE,QAAA,MAAM,WAAW,GAChB,QAAQ,MAAM,EACd,UAAS,kBAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAyHH,MAAM,IAAI;CAgB7C,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js new file mode 100644 index 0000000..0ae1cae --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js @@ -0,0 +1,125 @@ +import Hls from "hls.js"; +const defaults = { + label: "Качество", + selected: false, + selectable: false, + className: "quality-selector", +}; +const qualityRate = (player, options = defaults) => { + const hls = player.hlsInstance; + let onMenuUpdate = null; + if (!hls) { + return { + menuItems: () => [ + { label: "Авто", value: "auto", selected: true, onClick: () => { } }, + ], + menuItem: () => ({ ...options, enabled: false }), + setMenuUpdateCallback: () => { }, + }; + } + // Инициализация состояния уровней качества + let levels = []; + let isMenuInitialized = false; + const updateLevels = () => { + if (hls.levels?.length > 0) { + levels = hls.levels; + if (!isMenuInitialized) { + isMenuInitialized = true; + } + if (onMenuUpdate) { + onMenuUpdate(); + } + } + }; + // Обновляем уровни при загрузке манифеста + hls.on(Hls.Events.MANIFEST_PARSED, () => { + updateLevels(); + }); + // Проверяем, есть ли уже доступные уровни + if (hls.levels && hls.levels?.length > 0) { + levels = hls.levels; + } + const getPixels = (l) => (l.width > l.height ? l.height : l.width); + const formatBitrate = (bps) => (bps / 1000000).toFixed(1).replace(/\.0$/, "") + " Мбит"; + const getCurrentAutoLevel = () => { + const current = levels[hls.currentLevel]; + return current ? `${getPixels(current)}p` : ""; + }; + const getCurrentManualLevel = () => { + const manual = levels[hls.manualLevel]; + return manual + ? `${getPixels(manual)}p / ${formatBitrate(manual.bitrate)}` + : "Качество"; + }; + const menuItem = () => { + return { + ...options, + enabled: levels?.length > 0, + label: levels?.length === 0 + ? "Качество" + : levels?.length === 1 + ? "Авто" + : hls.autoLevelEnabled + ? `Авто (${getCurrentAutoLevel()})` + : getCurrentManualLevel(), + }; + }; + const setQuality = (quality) => { + if (!levels?.length) + return; + if (quality === 'auto') { + hls.currentLevel = -1; + } + else if (typeof quality === 'number') { + hls.currentLevel = quality; + } + }; + const menuItems = () => { + const isAuto = hls.autoLevelEnabled; + // Если доступен только один уровень качества, показываем только "Авто" + if (levels?.length <= 1) { + return [{ + label: "Авто", + value: -1, + selected: true, + onClick: () => setQuality('auto'), + }]; + } + const items = levels.map((level, index) => { + const label = `${getPixels(level)}p / ${formatBitrate(level.bitrate)}`; + const selected = !isAuto && hls.currentLevel === index; + return { + label, + value: index, + selected, + onClick: () => setQuality(index), + }; + }); + items.sort((a, b) => b.value - a.value); + // Добавляем "Авто" с информацией о текущем качестве только если есть выбор + items.push({ + label: isAuto ? `Авто (${getCurrentAutoLevel()})` : "Авто", + value: -1, + selected: isAuto, + onClick: () => setQuality('auto'), + }); + return items; + }; + // Позволяет установить внешний колбэк на обновление меню + const setMenuUpdateCallback = (cb) => { + onMenuUpdate = cb; + // Если уже есть уровни качества, сразу обновляем меню + if (levels?.length > 0) { + requestAnimationFrame(() => cb()); + } + }; + // Подписка на смену уровня (в т.ч. в авто режиме) + hls.on(Hls.Events.LEVEL_SWITCHED, () => { + if (onMenuUpdate) { + onMenuUpdate(); // триггерим обновление главного меню + } + }); + return { menuItem, menuItems, setMenuUpdateCallback }; +}; +export default qualityRate; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js.map new file mode 100644 index 0000000..8d1579b --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/quality-rate-selector/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts new file mode 100644 index 0000000..36627d6 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts @@ -0,0 +1,22 @@ +import { VideoJsPlayer } from "../../../../types"; +import { TachPlayerMenuItemOptions } from "../../../types"; +interface QualityMenuOptions extends TachPlayerMenuItemOptions { +} +declare const textTracks: (player: VideoJsPlayer, options?: QualityMenuOptions) => { + menuItems: () => { + label: any; + value: any; + selected: boolean; + onClick: () => void; + }[]; + menuItem: () => { + enabled: boolean; + label: string; + value?: any; + selectable?: boolean; + selected?: boolean; + className?: string; + }; +}; +export default textTracks; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts.map new file mode 100644 index 0000000..d6ee308 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAS3D,UAAU,kBAAmB,SAAQ,yBAAyB;CAAG;AAEjE,QAAA,MAAM,UAAU,GACf,QAAQ,aAAa,EACrB,UAAS,kBAA6B;;;;;;;;;;;;;;;CAgDtC,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js new file mode 100644 index 0000000..4fc33cf --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js @@ -0,0 +1,49 @@ +const defaults = { + label: "Субтитры", + selected: false, + selectable: false, + className: "subs-selector", +}; +const textTracks = (player, options = defaults) => { + const menuItems = () => { + const textTracks = player.textTracks().tracks_; + const trackItems = []; + for (let i = 0; i < textTracks?.length; ++i) { + if (textTracks[i].mode === "hidden") { + continue; + } + const trackItem = { + label: textTracks[i].label, + value: textTracks[i].label, + selected: textTracks[i].mode === "showing", + onClick: () => setTrack(textTracks[i]), + }; + trackItems.push(trackItem); + } + return trackItems; + }; + const setTrack = (track) => { + const textTracks = player.textTracks().tracks_; + for (let i = 0; i < textTracks?.length; ++i) { + if (textTracks[i].mode === "hidden") { + continue; + } + if (textTracks[i].label === track.label) + textTracks[i].mode = "showing"; + else + textTracks[i].mode = "disabled"; + } + }; + const menuItem = () => { + return { + ...options, + enabled: menuItems().length > 0, + }; + }; + return { + menuItems, + menuItem, + }; +}; +export default textTracks; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js.map b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js.map new file mode 100644 index 0000000..2e05948 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../../src/react/video-player/components/video-js/plugins/settings/selectors/text-track-selector/index.ts"],"names":[],"mappings":"AAGA,MAAM,QAAQ,GAAG;IAChB,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,eAAe;CAC1B,CAAC;AAIF,MAAM,UAAU,GAAG,CAClB,MAAqB,EACrB,UAA8B,QAAQ,EACrC,EAAE;IACH,MAAM,SAAS,GAAG,GAAG,EAAE;QACtB,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC;QAC/C,MAAM,UAAU,GAAG,EAAE,CAAC;QAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7C,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,SAAS;YACV,CAAC;YAED,MAAM,SAAS,GAAG;gBACjB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;gBAC1B,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;gBAC1B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS;gBAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;aACtC,CAAC;YAEF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAE,EAAE;QACrC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC;QAE/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7C,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,SAAS;YACV,CAAC;YAED,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;gBAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;;gBACnE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC;QACtC,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,OAAO;YACN,GAAG,OAAO;YACV,OAAO,EAAE,SAAS,EAAE,CAAC,MAAM,GAAG,CAAC;SAC/B,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACN,SAAS;QACT,QAAQ;KACR,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/settings/settings.css b/dist/react/video-player/components/video-js/plugins/settings/settings.css new file mode 100644 index 0000000..e885a8c --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/settings/settings.css @@ -0,0 +1,93 @@ +.video-js { + .vjs-control-bar { + .vjs-settings-button { + .vjs-menu { + z-index: 10 !important; + &.vjs-lock-showing { + width: 100%; + + .vjs-menu-content { + height: fit-content; + bottom: 3em; + width: 340px; + left: -220px; + } + } + } + } + } + + &.vjs-mobile-ui { + .vjs-control-bar { + .vjs-settings-button { + .vjs-menu { + &.vjs-lock-showing { + width: 100%; + position: fixed; + + .vjs-menu-content { + border-radius: 0; + width: 100vw; + height: 100vh; + padding-top: 50vh; + padding-left: 20px; + padding-right: 20px; + padding-bottom: 5px; + max-height: 100vh; + position: fixed; + top: 0; + left: 0; + /* top: 85%; + left: 50%; */ + /* transform: translate(-50%, -85%); */ + + background: rgba( + 0, + 0, + 0, + 0.5 + ); /* затемнение в области паддингов */ + + &:hover { + border-radius: 0 !important; + } + + &::before { + content: ""; + position: absolute; + top: 50vh; + left: 20px; + right: 20px; + bottom: 5px; + background: var(--Default-BgDarken); + border-radius: 10px; /* желаемый border-radius */ + } + + .vjs-menu-item { + position: relative; + z-index: 2; + border-radius: 0; + + &:hover { + border-radius: 0 !important; + } + } + + @media (orientation: landscape) { + padding-top: 20px; + padding-left: 25vw; + padding-right: 25vw; + + &::before { + top: 20px; + left: 25vw; + right: 25vw; + } + } + } + } + } + } + } + } +} diff --git a/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts new file mode 100644 index 0000000..a8963c0 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts @@ -0,0 +1,8 @@ +import Player from "video.js/dist/types/player"; +import "./skip-buttons.css"; +export interface SkipButtonsOptions { + skip: number; +} +declare const skipButtonsPlugin: (this: Player, options: SkipButtonsOptions) => void; +export default skipButtonsPlugin; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map new file mode 100644 index 0000000..107f138 --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/skip-buttons/index.tsx"],"names":[],"mappings":"AAKA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAKhD,OAAO,oBAAoB,CAAC;AAM5B,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;CACb;AAgID,QAAA,MAAM,iBAAiB,GAAa,MAAM,MAAM,EAAE,SAAS,kBAAkB,SAsD5E,CAAC;AAIF,eAAe,iBAAiB,CAAC"} \ No newline at end of file diff --git a/dist/react/video-player/components/video-js/plugins/skip-buttons/index.js b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.js new file mode 100644 index 0000000..3a2d96b --- /dev/null +++ b/dist/react/video-player/components/video-js/plugins/skip-buttons/index.js @@ -0,0 +1,145 @@ +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +// skipButtonsPlugin.tsx +import React from "react"; +import { createRoot } from "react-dom/client"; +import videojs from "video.js"; +import BackwardSvg from "./skip-backward.svg"; +import ForwardSvg from "./skip-forward.svg"; +import "./skip-buttons.css"; +import { numWord } from "../../../../shared/math"; +const renderSvg = (asset) => { + if (typeof asset === "string") { + return _jsx("img", { src: asset, alt: "", "aria-hidden": "true" }); + } + const SvgComponent = asset; + return _jsx(SvgComponent, {}); +}; +const SkipButton = ({ player, skip, direction }) => { + // Накопленная сумма перемотки + const [accumulated, setAccumulated] = React.useState(0); + // Храним ID таймера debounce + const timerRef = React.useRef(null); + // Используем ref для мгновенного доступа к накопленному значению + const accumulatedRef = React.useRef(0); + const handleClick = () => { + // Вычисляем новое накопленное значение + const newAccumulated = direction === "forward" + ? accumulatedRef.current + skip + : accumulatedRef.current - skip; + accumulatedRef.current = newAccumulated; + setAccumulated(newAccumulated); + // Сбрасываем предыдущий таймер + if (timerRef.current) { + clearTimeout(timerRef.current); + } + // Устанавливаем debounce (500 мс) + timerRef.current = setTimeout(() => { + const currentTime = player.currentTime() || 0; + const newTime = currentTime + accumulatedRef.current; + player.currentTime(newTime); + // Сбрасываем накопленное значение + accumulatedRef.current = 0; + setAccumulated(0); + }, 500); + }; + return (_jsxs("button", { onClick: handleClick, className: `vjs-skip-button vjs-skip-button-${direction}`, children: [_jsx("span", { className: "icon-placeholder", children: skip }), accumulated ? (_jsxs("div", { className: "scroll-info", children: [direction === "backward" + ? renderSvg(BackwardSvg) + : renderSvg(ForwardSvg), `${Math.abs(accumulated)} ${numWord(accumulated, ["секунду", "секунды", "секунд"])}`] })) : null] })); +}; +// Базовый Video.js компонент, обёртывающий React-компонент +class SkipButtonComponent extends videojs.getComponent("Component") { + constructor() { + super(...arguments); + this.reactRoot = null; + } + createEl() { + const direction = this.options_.direction; + const el = super.createEl("div", { + className: `vjs-skip-button-component vjs-skip-${direction}`, + }); + // Рендерим React-компонент сразу внутри созданного элемента + this.reactRoot = createRoot(el); + this.reactRoot.render(_jsx(SkipButton, { player: this.player(), skip: this.options_.skip, direction: direction })); + return el; + } + dispose() { + if (this.reactRoot) { + this.reactRoot.unmount(); + this.reactRoot = null; + } + super.dispose(); + } +} +// Компонент для кнопки перемотки назад – задаём direction через options +class SkipBackwardButtonComponent extends SkipButtonComponent { + constructor(player, options) { + options.direction = "backward"; + super(player, options); + } +} +// Компонент для кнопки перемотки вперёд – задаём direction через options +class SkipForwardButtonComponent extends SkipButtonComponent { + constructor(player, options) { + options.direction = "forward"; + super(player, options); + } +} +// Регистрируем компоненты в Video.js +videojs.registerComponent("SkipBackwardButtonComponent", SkipBackwardButtonComponent); +videojs.registerComponent("SkipForwardButtonComponent", SkipForwardButtonComponent); +// Плагин, который добавляет два отдельных компонента через player.addChild +const skipButtonsPlugin = function (options) { + const player = this; + player.ready(() => { + // 1) Добавляем кнопки + player.addChild("SkipBackwardButtonComponent", { skip: options.skip }); + player.addChild("SkipForwardButtonComponent", { skip: options.skip }); + // 2) Вспомогательная функция, которая находит кнопку и вызывает click() + const triggerSkipClick = (direction) => { + // Ищем именно + ); +}; + +// Базовый Video.js компонент, обёртывающий React-компонент +class SkipButtonComponent extends videojs.getComponent("Component") { + private reactRoot: Root | null = null; + + createEl(): HTMLElement { + const direction = this.options_.direction; + const el = super.createEl("div", { + className: `vjs-skip-button-component vjs-skip-${direction}`, + }) as HTMLElement; + + // Рендерим React-компонент сразу внутри созданного элемента + this.reactRoot = createRoot(el); + this.reactRoot.render( + , + ); + return el; + } + + dispose() { + if (this.reactRoot) { + this.reactRoot.unmount(); + this.reactRoot = null; + } + super.dispose(); + } +} + +// Компонент для кнопки перемотки назад – задаём direction через options +class SkipBackwardButtonComponent extends SkipButtonComponent { + constructor(player: Player, options: any) { + options.direction = "backward"; + super(player, options); + } +} + +// Компонент для кнопки перемотки вперёд – задаём direction через options +class SkipForwardButtonComponent extends SkipButtonComponent { + constructor(player: Player, options: any) { + options.direction = "forward"; + super(player, options); + } +} + +// Регистрируем компоненты в Video.js +videojs.registerComponent( + "SkipBackwardButtonComponent", + SkipBackwardButtonComponent, +); +videojs.registerComponent( + "SkipForwardButtonComponent", + SkipForwardButtonComponent, +); + +// Плагин, который добавляет два отдельных компонента через player.addChild +const skipButtonsPlugin = function (this: Player, options: SkipButtonsOptions) { + const player = this; + + player.ready(() => { + // 1) Добавляем кнопки + player.addChild("SkipBackwardButtonComponent", { skip: options.skip }); + player.addChild("SkipForwardButtonComponent", { skip: options.skip }); + + // 2) Вспомогательная функция, которая находит кнопку и вызывает click() + const triggerSkipClick = (direction: "forward" | "backward") => { + // Ищем именно