From 8e9ebbfa5695efa3cf580bda049efd960d2edbef Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 5 Feb 2025 06:36:05 +0100 Subject: [PATCH] Separate player in dedicated build * Separate player in a dedicated build, that we can control using vite. We had too many issues with Angular build system and we can now have the same build between the embed and the client. We can also embed SVG directly in the CSS * Upgrade p2p-media-loader to v2 * Update internal infohashes to reflect this p2p-media-loader protocol change (they are updated at PeerTube startup) * Minimum required iOS version is now v14 --- client/.browserslistrc | 2 +- client/.gitignore | 2 + client/angular.json | 7 +- client/package.json | 16 +- .../+video-watch/player-styles.component.scss | 6 +- .../+video-watch/video-watch.component.ts | 8 +- client/src/assets/player/index.ts | 2 - client/src/root-helpers/plugins-manager.ts | 2 +- .../translations-manager.ts | 0 .../src/standalone/build-tools/vite-utils.ts | 0 client/src/standalone/player/package.json | 31 ++ client/src/standalone/player/src/index.ts | 6 + .../src}/peertube-player-local-storage.ts | 0 .../player/src}/peertube-player.ts | 4 +- .../standalone/player/src/sass/player.scss | 2 + .../src/sass/shared}/_player-variables.scss | 2 - .../player/src/sass/shared}/bezels.scss | 0 .../player/src/sass/shared}/context-menu.scss | 4 +- .../player/src/sass/shared}/control-bar.scss | 32 +- .../player/src/sass/shared}/dock.scss | 0 .../player/src/sass/shared}/index.scss | 0 .../player/src/sass/shared}/mobile.scss | 0 .../sass/shared}/offline-notification.scss | 0 .../src/sass/shared}/peertube-skin.scss | 2 +- .../player/src/sass/shared}/playlist.scss | 8 +- .../src/sass/shared}/settings-menu.scss | 2 +- .../player/src/sass/shared}/spinner.scss | 0 .../player/src/sass/shared}/stats.scss | 0 .../player/src/sass/shared}/storyboard.scss | 0 .../player/src/sass/shared}/upnext.scss | 0 .../player/src/sass/svg}/arrow-down.svg | 0 .../player/src/sass/svg}/arrow-up.svg | 0 .../player/src/sass/svg}/big-play-button.svg | 0 .../player/src/sass/svg}/code.svg | 0 .../player/src/sass/svg}/fullscreen.svg | 0 .../player/src/sass/svg}/info.svg | 0 .../player/src/sass/svg}/link-2.svg | 0 .../player/src/sass/svg}/next.svg | 0 .../player/src/sass/svg/playlists.svg | 77 +++ .../player/src/sass/svg}/repeat.svg | 0 .../player/src/sass/svg}/settings.svg | 0 .../player/src/sass/svg}/theater.svg | 0 .../player/src/sass/svg}/tick-white.svg | 0 .../player/src/sass/svg}/volume-mute.svg | 0 .../player/src/sass/svg}/volume.svg | 0 .../src/standalone/player/src/sass/svg/x.svg | 1 + .../src}/shared/bezels/bezels-plugin.ts | 0 .../player/src}/shared/bezels/index.ts | 0 .../player/src}/shared/bezels/pause-bezel.ts | 0 .../player/src}/shared/common/index.ts | 0 .../player/src}/shared/common/utils.ts | 0 .../shared/context-menu/context-menu-item.ts | 0 .../context-menu/context-menu-plugin.ts | 0 .../src}/shared/context-menu/context-menu.ts | 0 .../player/src}/shared/context-menu/index.ts | 0 .../player/src}/shared/context-menu/util.ts | 0 .../control-bar/caption-toggle-button.ts | 0 .../shared/control-bar/chapters-plugin.ts | 0 .../player/src}/shared/control-bar/index.ts | 0 .../control-bar/next-previous-video-button.ts | 0 .../shared/control-bar/p2p-info-button.ts | 0 .../control-bar/peertube-link-button.ts | 0 .../control-bar/peertube-live-display.ts | 0 .../progress-bar-marker-component.ts | 0 .../shared/control-bar/storyboard-plugin.ts | 0 .../src}/shared/control-bar/theater-button.ts | 0 .../src}/shared/control-bar/time-tooltip.ts | 0 .../player/src}/shared/dock/index.ts | 0 .../shared/dock/peertube-dock-component.ts | 0 .../src}/shared/dock/peertube-dock-plugin.ts | 0 .../player/src}/shared/hotkeys/index.ts | 0 .../shared/hotkeys/peertube-hotkeys-plugin.ts | 0 .../player/src}/shared/metrics/index.ts | 0 .../src}/shared/metrics/metrics-plugin.ts | 0 .../player/src}/shared/mobile/index.ts | 0 .../shared/mobile/peertube-mobile-buttons.ts | 0 .../shared/mobile/peertube-mobile-plugin.ts | 0 .../shared/p2p-media-loader/hls-plugin.ts | 35 +- .../src}/shared/p2p-media-loader/index.ts | 0 .../p2p-media-loader-plugin.ts | 84 +-- .../redundancy-url-manager.ts | 22 +- .../p2p-media-loader/segment-url-builder.ts | 3 +- .../p2p-media-loader/segment-validator.ts | 41 +- .../player/src}/shared/peertube/index.ts | 0 .../src}/shared/peertube/peertube-plugin.ts | 0 .../control-bar-options-builder.ts | 0 .../hls-options-builder.ts | 134 ++--- .../shared/player-options-builder/index.ts | 0 .../web-video-options-builder.ts | 0 .../player/src}/shared/playlist/index.ts | 0 .../src}/shared/playlist/playlist-button.ts | 0 .../shared/playlist/playlist-menu-item.ts | 0 .../src}/shared/playlist/playlist-menu.ts | 0 .../src}/shared/playlist/playlist-plugin.ts | 0 .../player/src}/shared/resolutions/index.ts | 0 .../peertube-resolutions-plugin.ts | 0 .../player/src}/shared/settings/index.ts | 0 .../src}/shared/settings/menu-focus-fixed.ts | 0 .../shared/settings/resolution-menu-button.ts | 0 .../shared/settings/resolution-menu-item.ts | 0 .../src}/shared/settings/settings-dialog.ts | 0 .../shared/settings/settings-menu-button.ts | 0 .../shared/settings/settings-menu-item.ts | 0 .../shared/settings/settings-panel-child.ts | 0 .../src}/shared/settings/settings-panel.ts | 0 .../player/src}/shared/stats/index.ts | 0 .../player/src}/shared/stats/stats-card.ts | 2 + .../player/src}/shared/stats/stats-plugin.ts | 0 .../player/src}/shared/upnext/end-card.ts | 0 .../player/src}/shared/upnext/index.ts | 0 .../src}/shared/upnext/upnext-plugin.ts | 0 .../src}/shared/web-video/web-video-plugin.ts | 0 .../player/src}/types/index.ts | 0 .../src}/types/peertube-player-options.ts | 0 .../src}/types/peertube-videojs-typings.ts | 9 +- client/src/standalone/player/tsconfig.json | 6 + client/src/standalone/player/vite.config.mjs | 56 ++ client/src/standalone/videos/embed.scss | 6 +- client/src/standalone/videos/embed.ts | 14 +- .../videos/shared/player-options-builder.ts | 4 +- client/src/standalone/videos/vite.config.mjs | 6 +- client/tsconfig.json | 7 +- client/yarn.lock | 514 +++++++++--------- packages/node-utils/src/crypto.ts | 4 + scripts/build/client.sh | 9 +- scripts/build/embed.sh | 2 + scripts/dev/client.sh | 8 +- scripts/dev/embed.sh | 2 + server/core/controllers/tracker.ts | 15 +- server/core/initializers/constants.ts | 6 +- .../shared/object-to-model-attributes.ts | 2 +- server/core/lib/hls.ts | 21 +- server/core/lib/live/shared/muxing-session.ts | 2 +- server/core/models/video/video-file.ts | 16 +- .../models/video/video-streaming-playlist.ts | 40 +- 135 files changed, 787 insertions(+), 499 deletions(-) delete mode 100644 client/src/assets/player/index.ts rename client/src/{assets/player => root-helpers}/translations-manager.ts (100%) create mode 100644 client/src/standalone/build-tools/vite-utils.ts create mode 100644 client/src/standalone/player/package.json create mode 100644 client/src/standalone/player/src/index.ts rename client/src/{assets/player => standalone/player/src}/peertube-player-local-storage.ts (100%) rename client/src/{assets/player => standalone/player/src}/peertube-player.ts (99%) create mode 100644 client/src/standalone/player/src/sass/player.scss rename client/src/{sass/player => standalone/player/src/sass/shared}/_player-variables.scss (93%) rename client/src/{sass/player => standalone/player/src/sass/shared}/bezels.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/context-menu.scss (89%) rename client/src/{sass/player => standalone/player/src/sass/shared}/control-bar.scss (94%) rename client/src/{sass/player => standalone/player/src/sass/shared}/dock.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/index.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/mobile.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/offline-notification.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/peertube-skin.scss (98%) rename client/src/{sass/player => standalone/player/src/sass/shared}/playlist.scss (91%) rename client/src/{sass/player => standalone/player/src/sass/shared}/settings-menu.scss (97%) rename client/src/{sass/player => standalone/player/src/sass/shared}/spinner.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/stats.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/storyboard.scss (100%) rename client/src/{sass/player => standalone/player/src/sass/shared}/upnext.scss (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/arrow-down.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/arrow-up.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/big-play-button.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/code.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/fullscreen.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/info.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/link-2.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/next.svg (100%) create mode 100644 client/src/standalone/player/src/sass/svg/playlists.svg rename client/src/{assets/player/images => standalone/player/src/sass/svg}/repeat.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/settings.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/theater.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/tick-white.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/volume-mute.svg (100%) rename client/src/{assets/player/images => standalone/player/src/sass/svg}/volume.svg (100%) create mode 100644 client/src/standalone/player/src/sass/svg/x.svg rename client/src/{assets/player => standalone/player/src}/shared/bezels/bezels-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/bezels/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/bezels/pause-bezel.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/common/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/common/utils.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/context-menu/context-menu-item.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/context-menu/context-menu-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/context-menu/context-menu.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/context-menu/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/context-menu/util.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/caption-toggle-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/chapters-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/next-previous-video-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/p2p-info-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/peertube-link-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/peertube-live-display.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/progress-bar-marker-component.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/storyboard-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/theater-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/control-bar/time-tooltip.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/dock/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/dock/peertube-dock-component.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/dock/peertube-dock-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/hotkeys/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/hotkeys/peertube-hotkeys-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/metrics/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/metrics/metrics-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/mobile/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/mobile/peertube-mobile-buttons.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/mobile/peertube-mobile-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/hls-plugin.ts (95%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/p2p-media-loader-plugin.ts (73%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/redundancy-url-manager.ts (67%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/segment-url-builder.ts (80%) rename client/src/{assets/player => standalone/player/src}/shared/p2p-media-loader/segment-validator.ts (76%) rename client/src/{assets/player => standalone/player/src}/shared/peertube/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/peertube/peertube-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/player-options-builder/control-bar-options-builder.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/player-options-builder/hls-options-builder.ts (63%) rename client/src/{assets/player => standalone/player/src}/shared/player-options-builder/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/player-options-builder/web-video-options-builder.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/playlist/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/playlist/playlist-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/playlist/playlist-menu-item.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/playlist/playlist-menu.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/playlist/playlist-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/resolutions/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/resolutions/peertube-resolutions-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/menu-focus-fixed.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/resolution-menu-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/resolution-menu-item.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/settings-dialog.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/settings-menu-button.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/settings-menu-item.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/settings-panel-child.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/settings/settings-panel.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/stats/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/stats/stats-card.ts (99%) rename client/src/{assets/player => standalone/player/src}/shared/stats/stats-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/upnext/end-card.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/upnext/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/upnext/upnext-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/shared/web-video/web-video-plugin.ts (100%) rename client/src/{assets/player => standalone/player/src}/types/index.ts (100%) rename client/src/{assets/player => standalone/player/src}/types/peertube-player-options.ts (100%) rename client/src/{assets/player => standalone/player/src}/types/peertube-videojs-typings.ts (96%) create mode 100644 client/src/standalone/player/tsconfig.json create mode 100644 client/src/standalone/player/vite.config.mjs diff --git a/client/.browserslistrc b/client/.browserslistrc index 9eb6a61de7c..cdc51d7ada5 100644 --- a/client/.browserslistrc +++ b/client/.browserslistrc @@ -1,4 +1,4 @@ last 1 Chrome version last 2 Edge major versions Firefox ESR -ios_saf >= 13.1 +ios_saf >= 14 diff --git a/client/.gitignore b/client/.gitignore index 6523ad810a5..04c0e93f135 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -12,6 +12,8 @@ /e2e/local.log /e2e/browserstack.err /e2e/screenshots +/src/standalone/player/build +/src/standalone/player/dist /src/standalone/embed-player-api/build /src/standalone/embed-player-api/dist /e2e/logs diff --git a/client/angular.json b/client/angular.json index 82c4ad21704..d0277dbbf9d 100644 --- a/client/angular.json +++ b/client/angular.json @@ -183,7 +183,10 @@ "includePaths": [ "src/sass/include", "." - ] + ], + "sass": { + "silenceDeprecations": [ "import", "mixed-decls", "color-functions", "global-builtin" ] + } }, "assets": [ "src/assets/images", @@ -241,7 +244,7 @@ { "type": "anyComponentStyle", "maximumWarning": "6kb", - "maximumError": "100kb" + "maximumError": "120kb" } ], "fileReplacements": [ diff --git a/client/package.json b/client/package.json index ae3b47d645b..7feb9fd0ac3 100644 --- a/client/package.json +++ b/client/package.json @@ -24,10 +24,13 @@ "net": false, "stream": false, "os": false, + "http": false, + "dgram": false, "util": false }, "workspaces": [ - "../packages/*" + "../packages/*", + "./src/standalone/player" ], "typings": "*.d.ts", "devDependencies": { @@ -55,8 +58,6 @@ "@ngx-loading-bar/http-client": "^7.0.0", "@ngx-loading-bar/router": "^7.0.0", "@peertube/maildev": "^1.2.0", - "@peertube/p2p-media-loader-core": "^1.0.20", - "@peertube/p2p-media-loader-hlsjs": "^1.0.20", "@peertube/xliffmerge": "^2.0.3", "@plussub/srt-vtt-parser": "^2.0.5", "@popperjs/core": "^2.11.5", @@ -103,8 +104,11 @@ "markdown-it": "14.1.0", "markdown-it-emoji": "^3.0.0", "ngx-uploadx": "^7.0.0", + "p2p-media-loader-core": "^2.1.1", + "p2p-media-loader-hlsjs": "^2.1.1", "primeng": "^17", "rxjs": "^7.3.0", + "sass-embedded": "^1.83.4", "sha.js": "^2.4.11", "socket.io-client": "^4.5.4", "stylelint": "^16.2.1", @@ -115,9 +119,9 @@ "tslib": "^2.4.0", "typescript": "~5.7.3", "video.js": "^7.19.2", - "vite": "^5.3.1", - "vite-plugin-checker": "^0.7.2", - "vite-plugin-node-polyfills": "^0.22.0", + "vite": "^6.0.11", + "vite-plugin-checker": "^0.8.0", + "vite-plugin-node-polyfills": "^0.23.0", "zone.js": "~0.15.0" }, "dependencies": {} diff --git a/client/src/app/+videos/+video-watch/player-styles.component.scss b/client/src/app/+videos/+video-watch/player-styles.component.scss index c0befc10a74..d2b386a5b47 100644 --- a/client/src/app/+videos/+video-watch/player-styles.component.scss +++ b/client/src/app/+videos/+video-watch/player-styles.component.scss @@ -1,5 +1 @@ -@use 'node_modules/video.js/dist/video-js'; - -$assets-path: '../../assets/'; - -@use '../../../sass/player/index'; +@use '../../../standalone/player/build/peertube-player.css'; diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts index 3454b55b015..75a52aa16aa 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts @@ -47,16 +47,18 @@ import { logger } from '@root-helpers/logger' import { isP2PEnabled, videoRequiresFileToken, videoRequiresUserAuth } from '@root-helpers/video' import debug from 'debug' import { forkJoin, map, Observable, of, Subscription, switchMap } from 'rxjs' +import { environment } from '../../../environments/environment' import { + cleanupVideoWatch, + getStoredTheater, + getStoredVideoWatchHistory, HLSOptions, PeerTubePlayer, PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions, PlayerMode, videojs -} from '../../../assets/player' -import { cleanupVideoWatch, getStoredTheater, getStoredVideoWatchHistory } from '../../../assets/player/peertube-player-local-storage' -import { environment } from '../../../environments/environment' +} from '@peertube/player' import { DateToggleComponent } from '../../shared/shared-main/date/date-toggle.component' import { PluginPlaceholderComponent } from '../../shared/shared-main/plugins/plugin-placeholder.component' import { VideoViewsCounterComponent } from '../../shared/shared-video/video-views-counter.component' diff --git a/client/src/assets/player/index.ts b/client/src/assets/player/index.ts deleted file mode 100644 index d34188ea755..00000000000 --- a/client/src/assets/player/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './peertube-player' -export * from './types' diff --git a/client/src/root-helpers/plugins-manager.ts b/client/src/root-helpers/plugins-manager.ts index b11af1511f1..ea6b6b86908 100644 --- a/client/src/root-helpers/plugins-manager.ts +++ b/client/src/root-helpers/plugins-manager.ts @@ -2,7 +2,7 @@ import debug from 'debug' import { firstValueFrom, ReplaySubject } from 'rxjs' import { first, shareReplay } from 'rxjs/operators' -import { RegisterClientHelpers } from 'src/types/register-client-option.model' +import { RegisterClientHelpers } from '../types/register-client-option.model' import { getExternalAuthHref, getHookType, internalRunHook } from '@peertube/peertube-core-utils' import { ClientDoAction, diff --git a/client/src/assets/player/translations-manager.ts b/client/src/root-helpers/translations-manager.ts similarity index 100% rename from client/src/assets/player/translations-manager.ts rename to client/src/root-helpers/translations-manager.ts diff --git a/client/src/standalone/build-tools/vite-utils.ts b/client/src/standalone/build-tools/vite-utils.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/client/src/standalone/player/package.json b/client/src/standalone/player/package.json new file mode 100644 index 00000000000..940ccb746f9 --- /dev/null +++ b/client/src/standalone/player/package.json @@ -0,0 +1,31 @@ +{ + "name": "@peertube/player", + "private": false, + "version": "0.0.0", + "scripts": { + "build": "rm -rf ./build && ../../../node_modules/.bin/vite build --mode production --config ./vite.config.mjs", + "dev": "../../../node_modules/.bin/vite build --mode dev --watch --config ./vite.config.mjs" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Chocobozzz/PeerTube.git" + }, + "keywords": [ + "peertube", + "embed" + ], + "main": "./build/peertube-player.js", + "exports": { + ".": "./build/peertube-player.js" + }, + "types": "./src/index.ts", + "author": "Chocobozzz", + "license": "AGPL-3.0", + "type": "module", + "sideEffects": true, + "bugs": { + "url": "https://github.com/Chocobozzz/PeerTube/issues" + }, + "homepage": "https://github.com/Chocobozzz/PeerTube#readme", + "dependencies": {} +} diff --git a/client/src/standalone/player/src/index.ts b/client/src/standalone/player/src/index.ts new file mode 100644 index 00000000000..fbea76fb62c --- /dev/null +++ b/client/src/standalone/player/src/index.ts @@ -0,0 +1,6 @@ +export * from './peertube-player' +export * from './peertube-player-local-storage' +export * from '../../../root-helpers/translations-manager' +export * from './types' + +import './sass/player.scss' diff --git a/client/src/assets/player/peertube-player-local-storage.ts b/client/src/standalone/player/src/peertube-player-local-storage.ts similarity index 100% rename from client/src/assets/player/peertube-player-local-storage.ts rename to client/src/standalone/player/src/peertube-player-local-storage.ts diff --git a/client/src/assets/player/peertube-player.ts b/client/src/standalone/player/src/peertube-player.ts similarity index 99% rename from client/src/assets/player/peertube-player.ts rename to client/src/standalone/player/src/peertube-player.ts index 2c4108bbb52..182eb47cccd 100644 --- a/client/src/assets/player/peertube-player.ts +++ b/client/src/standalone/player/src/peertube-player.ts @@ -31,6 +31,8 @@ import './shared/metrics/metrics-plugin' import './shared/p2p-media-loader/hls-plugin' import './shared/p2p-media-loader/p2p-media-loader-plugin' import './shared/web-video/web-video-plugin' +import './shared/dock/peertube-dock-component' +import './shared/dock/peertube-dock-plugin' import videojs, { VideoJsPlayer } from 'video.js' import { logger } from '@root-helpers/logger' import { PluginsManager } from '@root-helpers/plugins-manager' @@ -40,7 +42,7 @@ import { isMobile } from '@root-helpers/web-browser' import { buildVideoLink, decorateVideoLink, isDefaultLocale, pick } from '@peertube/peertube-core-utils' import { saveAverageBandwidth } from './peertube-player-local-storage' import { ControlBarOptionsBuilder, HLSOptionsBuilder, WebVideoOptionsBuilder } from './shared/player-options-builder' -import { TranslationsManager } from './translations-manager' +import { TranslationsManager } from '@root-helpers/translations-manager' import { PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions, PlayerNetworkInfo, VideoJSPluginOptions } from './types' // Change 'Playback Rate' to 'Speed' (smaller for our settings menu) diff --git a/client/src/standalone/player/src/sass/player.scss b/client/src/standalone/player/src/sass/player.scss new file mode 100644 index 00000000000..30d2493bca2 --- /dev/null +++ b/client/src/standalone/player/src/sass/player.scss @@ -0,0 +1,2 @@ +@use '../../../node_modules/video.js/dist/video-js'; +@use './shared/index.scss'; diff --git a/client/src/sass/player/_player-variables.scss b/client/src/standalone/player/src/sass/shared/_player-variables.scss similarity index 93% rename from client/src/sass/player/_player-variables.scss rename to client/src/standalone/player/src/sass/shared/_player-variables.scss index 8691bf6b2bd..9e0f41363fd 100644 --- a/client/src/sass/player/_player-variables.scss +++ b/client/src/standalone/player/src/sass/shared/_player-variables.scss @@ -22,5 +22,3 @@ $control-bar-total-height: $control-bar-height - $control-bar-slider-top; $progress-margin: 10px; $dock-padding: 20px; - -$assets-path: '../../assets/' !default; diff --git a/client/src/sass/player/bezels.scss b/client/src/standalone/player/src/sass/shared/bezels.scss similarity index 100% rename from client/src/sass/player/bezels.scss rename to client/src/standalone/player/src/sass/shared/bezels.scss diff --git a/client/src/sass/player/context-menu.scss b/client/src/standalone/player/src/sass/shared/context-menu.scss similarity index 89% rename from client/src/sass/player/context-menu.scss rename to client/src/standalone/player/src/sass/shared/context-menu.scss index f5b051be252..84f5928d169 100644 --- a/client/src/sass/player/context-menu.scss +++ b/client/src/standalone/player/src/sass/shared/context-menu.scss @@ -50,8 +50,8 @@ $context-menu-width: 350px; @each $icon in $icons { &[class$="-#{$icon}"] { - mask-image: url('#{$assets-path}/player/images/#{$icon}.svg'); - -webkit-mask-image: url('#{$assets-path}/player/images/#{$icon}.svg'); + mask-image: url('./svg/#{$icon}.svg'); + -webkit-mask-image: url('./svg/#{$icon}.svg'); } } diff --git a/client/src/sass/player/control-bar.scss b/client/src/standalone/player/src/sass/shared/control-bar.scss similarity index 94% rename from client/src/sass/player/control-bar.scss rename to client/src/standalone/player/src/sass/shared/control-bar.scss index af54d0ccc97..14d7b1c8b84 100644 --- a/client/src/sass/player/control-bar.scss +++ b/client/src/standalone/player/src/sass/shared/control-bar.scss @@ -270,11 +270,11 @@ $chapter-marker-size: 9px; @include margin-right(2px); &.icon-download { - background-image: url('#{$assets-path}/player/images/arrow-down.svg'); + background-image: url('./svg/arrow-down.svg'); } &.icon-upload { - background-image: url('#{$assets-path}/player/images/arrow-up.svg'); + background-image: url('./svg/arrow-up.svg'); } } } @@ -291,8 +291,8 @@ $chapter-marker-size: 9px; .icon { &.icon-next, &.icon-previous { - mask-image: url('#{$assets-path}/player/images/next.svg'); - -webkit-mask-image: url('#{$assets-path}/player/images/next.svg'); + mask-image: url('./svg/next.svg'); + -webkit-mask-image: url('./svg/next.svg'); mask-size: cover; -webkit-mask-size: cover; @@ -319,7 +319,7 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size; height: $control-bar-icon-size; vertical-align: middle; - background: url('#{$assets-path}/player/images/volume.svg') no-repeat; + background: url('./svg/volume.svg') no-repeat; background-size: contain; &::before { @@ -328,7 +328,7 @@ $chapter-marker-size: 9px; } &.vjs-vol-0 .vjs-icon-placeholder { - background: url('#{$assets-path}/player/images/volume-mute.svg') no-repeat; + background: url('./svg/volume-mute.svg') no-repeat; background-size: contain; } } @@ -415,7 +415,7 @@ $chapter-marker-size: 9px; height: $control-bar-icon-size - 4px; width: $control-bar-icon-size - 4px; vertical-align: middle; - background: url('#{$assets-path}/player/images/settings.svg') no-repeat; + background: url('./svg/settings.svg') no-repeat; background-size: contain; &::before { @@ -448,7 +448,7 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size - 4px; height: $control-bar-icon-size - 4px; vertical-align: middle; - background: url('#{$assets-path}/player/images/theater.svg') no-repeat; + background: url('./svg/theater.svg') no-repeat; background-size: contain; &::before { @@ -493,7 +493,7 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size; height: $control-bar-icon-size; vertical-align: middle; - background: url('#{$assets-path}/player/images/fullscreen.svg') no-repeat; + background: url('./svg/fullscreen.svg') no-repeat; background-size: contain; &::before { @@ -515,14 +515,6 @@ $chapter-marker-size: 9px; .vjs-theater-control { display: none; } - - .vjs-peertube { - .icon, - .download-speed-text, - .upload-speed-text { - display: none !important; - } - } } .video-js.vjs-peertube-skin.vjs-size-570 .vjs-control-bar { @@ -540,6 +532,12 @@ $chapter-marker-size: 9px; .vjs-peertube-displayed { display: none !important; } + + .icon, + .download-speed-text, + .upload-speed-text { + display: none !important; + } } .vjs-peertube-link { diff --git a/client/src/sass/player/dock.scss b/client/src/standalone/player/src/sass/shared/dock.scss similarity index 100% rename from client/src/sass/player/dock.scss rename to client/src/standalone/player/src/sass/shared/dock.scss diff --git a/client/src/sass/player/index.scss b/client/src/standalone/player/src/sass/shared/index.scss similarity index 100% rename from client/src/sass/player/index.scss rename to client/src/standalone/player/src/sass/shared/index.scss diff --git a/client/src/sass/player/mobile.scss b/client/src/standalone/player/src/sass/shared/mobile.scss similarity index 100% rename from client/src/sass/player/mobile.scss rename to client/src/standalone/player/src/sass/shared/mobile.scss diff --git a/client/src/sass/player/offline-notification.scss b/client/src/standalone/player/src/sass/shared/offline-notification.scss similarity index 100% rename from client/src/sass/player/offline-notification.scss rename to client/src/standalone/player/src/sass/shared/offline-notification.scss diff --git a/client/src/sass/player/peertube-skin.scss b/client/src/standalone/player/src/sass/shared/peertube-skin.scss similarity index 98% rename from client/src/sass/player/peertube-skin.scss rename to client/src/standalone/player/src/sass/shared/peertube-skin.scss index ea9f3e3354d..381bde83a08 100644 --- a/client/src/sass/player/peertube-skin.scss +++ b/client/src/standalone/player/src/sass/shared/peertube-skin.scss @@ -60,7 +60,7 @@ body { .vjs-icon-placeholder::before { content: ''; - background-image: url('#{$assets-path}/player/images/big-play-button.svg'); + background-image: url('./svg/big-play-button.svg'); @include big-play-button-triangle-size(45px); } diff --git a/client/src/sass/player/playlist.scss b/client/src/standalone/player/src/sass/shared/playlist.scss similarity index 91% rename from client/src/sass/player/playlist.scss rename to client/src/standalone/player/src/sass/shared/playlist.scss index c3e571b003a..f39a8463b1a 100644 --- a/client/src/sass/player/playlist.scss +++ b/client/src/standalone/player/src/sass/shared/playlist.scss @@ -44,8 +44,8 @@ $playlist-menu-width: 350px; } .cross { - mask-image: url('#{$assets-path}/images/feather/x.svg'); - -webkit-mask-image: url('#{$assets-path}/images/feather/x.svg'); + mask-image: url('./svg/x.svg'); + -webkit-mask-image: url('./svg/x.svg'); mask-size: cover; -webkit-mask-size: cover; @@ -92,8 +92,8 @@ $playlist-menu-width: 350px; } .vjs-playlist-icon { - mask-image: url('#{$assets-path}/images/feather/playlists.svg'); - -webkit-mask-image: url('#{$assets-path}/images/feather/playlists.svg'); + mask-image: url('./svg/playlists.svg'); + -webkit-mask-image: url('./svg/playlists.svg'); mask-size: cover; -webkit-mask-size: cover; diff --git a/client/src/sass/player/settings-menu.scss b/client/src/standalone/player/src/sass/shared/settings-menu.scss similarity index 97% rename from client/src/sass/player/settings-menu.scss rename to client/src/standalone/player/src/sass/shared/settings-menu.scss index d2095e85b62..0353c0b3121 100644 --- a/client/src/sass/player/settings-menu.scss +++ b/client/src/standalone/player/src/sass/shared/settings-menu.scss @@ -145,7 +145,7 @@ $setting-transition-easing: ease-out; position: absolute; content: ' '; margin-top: 1px; - background-image: url('#{$assets-path}/player/images/tick-white.svg'); + background-image: url('./svg/tick-white.svg'); @include icon(15px); @include left(15px); diff --git a/client/src/sass/player/spinner.scss b/client/src/standalone/player/src/sass/shared/spinner.scss similarity index 100% rename from client/src/sass/player/spinner.scss rename to client/src/standalone/player/src/sass/shared/spinner.scss diff --git a/client/src/sass/player/stats.scss b/client/src/standalone/player/src/sass/shared/stats.scss similarity index 100% rename from client/src/sass/player/stats.scss rename to client/src/standalone/player/src/sass/shared/stats.scss diff --git a/client/src/sass/player/storyboard.scss b/client/src/standalone/player/src/sass/shared/storyboard.scss similarity index 100% rename from client/src/sass/player/storyboard.scss rename to client/src/standalone/player/src/sass/shared/storyboard.scss diff --git a/client/src/sass/player/upnext.scss b/client/src/standalone/player/src/sass/shared/upnext.scss similarity index 100% rename from client/src/sass/player/upnext.scss rename to client/src/standalone/player/src/sass/shared/upnext.scss diff --git a/client/src/assets/player/images/arrow-down.svg b/client/src/standalone/player/src/sass/svg/arrow-down.svg similarity index 100% rename from client/src/assets/player/images/arrow-down.svg rename to client/src/standalone/player/src/sass/svg/arrow-down.svg diff --git a/client/src/assets/player/images/arrow-up.svg b/client/src/standalone/player/src/sass/svg/arrow-up.svg similarity index 100% rename from client/src/assets/player/images/arrow-up.svg rename to client/src/standalone/player/src/sass/svg/arrow-up.svg diff --git a/client/src/assets/player/images/big-play-button.svg b/client/src/standalone/player/src/sass/svg/big-play-button.svg similarity index 100% rename from client/src/assets/player/images/big-play-button.svg rename to client/src/standalone/player/src/sass/svg/big-play-button.svg diff --git a/client/src/assets/player/images/code.svg b/client/src/standalone/player/src/sass/svg/code.svg similarity index 100% rename from client/src/assets/player/images/code.svg rename to client/src/standalone/player/src/sass/svg/code.svg diff --git a/client/src/assets/player/images/fullscreen.svg b/client/src/standalone/player/src/sass/svg/fullscreen.svg similarity index 100% rename from client/src/assets/player/images/fullscreen.svg rename to client/src/standalone/player/src/sass/svg/fullscreen.svg diff --git a/client/src/assets/player/images/info.svg b/client/src/standalone/player/src/sass/svg/info.svg similarity index 100% rename from client/src/assets/player/images/info.svg rename to client/src/standalone/player/src/sass/svg/info.svg diff --git a/client/src/assets/player/images/link-2.svg b/client/src/standalone/player/src/sass/svg/link-2.svg similarity index 100% rename from client/src/assets/player/images/link-2.svg rename to client/src/standalone/player/src/sass/svg/link-2.svg diff --git a/client/src/assets/player/images/next.svg b/client/src/standalone/player/src/sass/svg/next.svg similarity index 100% rename from client/src/assets/player/images/next.svg rename to client/src/standalone/player/src/sass/svg/next.svg diff --git a/client/src/standalone/player/src/sass/svg/playlists.svg b/client/src/standalone/player/src/sass/svg/playlists.svg new file mode 100644 index 00000000000..247c073f0ec --- /dev/null +++ b/client/src/standalone/player/src/sass/svg/playlists.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + diff --git a/client/src/assets/player/images/repeat.svg b/client/src/standalone/player/src/sass/svg/repeat.svg similarity index 100% rename from client/src/assets/player/images/repeat.svg rename to client/src/standalone/player/src/sass/svg/repeat.svg diff --git a/client/src/assets/player/images/settings.svg b/client/src/standalone/player/src/sass/svg/settings.svg similarity index 100% rename from client/src/assets/player/images/settings.svg rename to client/src/standalone/player/src/sass/svg/settings.svg diff --git a/client/src/assets/player/images/theater.svg b/client/src/standalone/player/src/sass/svg/theater.svg similarity index 100% rename from client/src/assets/player/images/theater.svg rename to client/src/standalone/player/src/sass/svg/theater.svg diff --git a/client/src/assets/player/images/tick-white.svg b/client/src/standalone/player/src/sass/svg/tick-white.svg similarity index 100% rename from client/src/assets/player/images/tick-white.svg rename to client/src/standalone/player/src/sass/svg/tick-white.svg diff --git a/client/src/assets/player/images/volume-mute.svg b/client/src/standalone/player/src/sass/svg/volume-mute.svg similarity index 100% rename from client/src/assets/player/images/volume-mute.svg rename to client/src/standalone/player/src/sass/svg/volume-mute.svg diff --git a/client/src/assets/player/images/volume.svg b/client/src/standalone/player/src/sass/svg/volume.svg similarity index 100% rename from client/src/assets/player/images/volume.svg rename to client/src/standalone/player/src/sass/svg/volume.svg diff --git a/client/src/standalone/player/src/sass/svg/x.svg b/client/src/standalone/player/src/sass/svg/x.svg new file mode 100644 index 00000000000..7d5875ca8bc --- /dev/null +++ b/client/src/standalone/player/src/sass/svg/x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/src/assets/player/shared/bezels/bezels-plugin.ts b/client/src/standalone/player/src/shared/bezels/bezels-plugin.ts similarity index 100% rename from client/src/assets/player/shared/bezels/bezels-plugin.ts rename to client/src/standalone/player/src/shared/bezels/bezels-plugin.ts diff --git a/client/src/assets/player/shared/bezels/index.ts b/client/src/standalone/player/src/shared/bezels/index.ts similarity index 100% rename from client/src/assets/player/shared/bezels/index.ts rename to client/src/standalone/player/src/shared/bezels/index.ts diff --git a/client/src/assets/player/shared/bezels/pause-bezel.ts b/client/src/standalone/player/src/shared/bezels/pause-bezel.ts similarity index 100% rename from client/src/assets/player/shared/bezels/pause-bezel.ts rename to client/src/standalone/player/src/shared/bezels/pause-bezel.ts diff --git a/client/src/assets/player/shared/common/index.ts b/client/src/standalone/player/src/shared/common/index.ts similarity index 100% rename from client/src/assets/player/shared/common/index.ts rename to client/src/standalone/player/src/shared/common/index.ts diff --git a/client/src/assets/player/shared/common/utils.ts b/client/src/standalone/player/src/shared/common/utils.ts similarity index 100% rename from client/src/assets/player/shared/common/utils.ts rename to client/src/standalone/player/src/shared/common/utils.ts diff --git a/client/src/assets/player/shared/context-menu/context-menu-item.ts b/client/src/standalone/player/src/shared/context-menu/context-menu-item.ts similarity index 100% rename from client/src/assets/player/shared/context-menu/context-menu-item.ts rename to client/src/standalone/player/src/shared/context-menu/context-menu-item.ts diff --git a/client/src/assets/player/shared/context-menu/context-menu-plugin.ts b/client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts similarity index 100% rename from client/src/assets/player/shared/context-menu/context-menu-plugin.ts rename to client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts diff --git a/client/src/assets/player/shared/context-menu/context-menu.ts b/client/src/standalone/player/src/shared/context-menu/context-menu.ts similarity index 100% rename from client/src/assets/player/shared/context-menu/context-menu.ts rename to client/src/standalone/player/src/shared/context-menu/context-menu.ts diff --git a/client/src/assets/player/shared/context-menu/index.ts b/client/src/standalone/player/src/shared/context-menu/index.ts similarity index 100% rename from client/src/assets/player/shared/context-menu/index.ts rename to client/src/standalone/player/src/shared/context-menu/index.ts diff --git a/client/src/assets/player/shared/context-menu/util.ts b/client/src/standalone/player/src/shared/context-menu/util.ts similarity index 100% rename from client/src/assets/player/shared/context-menu/util.ts rename to client/src/standalone/player/src/shared/context-menu/util.ts diff --git a/client/src/assets/player/shared/control-bar/caption-toggle-button.ts b/client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/caption-toggle-button.ts rename to client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts diff --git a/client/src/assets/player/shared/control-bar/chapters-plugin.ts b/client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/chapters-plugin.ts rename to client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts diff --git a/client/src/assets/player/shared/control-bar/index.ts b/client/src/standalone/player/src/shared/control-bar/index.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/index.ts rename to client/src/standalone/player/src/shared/control-bar/index.ts diff --git a/client/src/assets/player/shared/control-bar/next-previous-video-button.ts b/client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/next-previous-video-button.ts rename to client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts diff --git a/client/src/assets/player/shared/control-bar/p2p-info-button.ts b/client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/p2p-info-button.ts rename to client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts diff --git a/client/src/assets/player/shared/control-bar/peertube-link-button.ts b/client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/peertube-link-button.ts rename to client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts diff --git a/client/src/assets/player/shared/control-bar/peertube-live-display.ts b/client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/peertube-live-display.ts rename to client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts diff --git a/client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts b/client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/progress-bar-marker-component.ts rename to client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts diff --git a/client/src/assets/player/shared/control-bar/storyboard-plugin.ts b/client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/storyboard-plugin.ts rename to client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts diff --git a/client/src/assets/player/shared/control-bar/theater-button.ts b/client/src/standalone/player/src/shared/control-bar/theater-button.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/theater-button.ts rename to client/src/standalone/player/src/shared/control-bar/theater-button.ts diff --git a/client/src/assets/player/shared/control-bar/time-tooltip.ts b/client/src/standalone/player/src/shared/control-bar/time-tooltip.ts similarity index 100% rename from client/src/assets/player/shared/control-bar/time-tooltip.ts rename to client/src/standalone/player/src/shared/control-bar/time-tooltip.ts diff --git a/client/src/assets/player/shared/dock/index.ts b/client/src/standalone/player/src/shared/dock/index.ts similarity index 100% rename from client/src/assets/player/shared/dock/index.ts rename to client/src/standalone/player/src/shared/dock/index.ts diff --git a/client/src/assets/player/shared/dock/peertube-dock-component.ts b/client/src/standalone/player/src/shared/dock/peertube-dock-component.ts similarity index 100% rename from client/src/assets/player/shared/dock/peertube-dock-component.ts rename to client/src/standalone/player/src/shared/dock/peertube-dock-component.ts diff --git a/client/src/assets/player/shared/dock/peertube-dock-plugin.ts b/client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts similarity index 100% rename from client/src/assets/player/shared/dock/peertube-dock-plugin.ts rename to client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts diff --git a/client/src/assets/player/shared/hotkeys/index.ts b/client/src/standalone/player/src/shared/hotkeys/index.ts similarity index 100% rename from client/src/assets/player/shared/hotkeys/index.ts rename to client/src/standalone/player/src/shared/hotkeys/index.ts diff --git a/client/src/assets/player/shared/hotkeys/peertube-hotkeys-plugin.ts b/client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts similarity index 100% rename from client/src/assets/player/shared/hotkeys/peertube-hotkeys-plugin.ts rename to client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts diff --git a/client/src/assets/player/shared/metrics/index.ts b/client/src/standalone/player/src/shared/metrics/index.ts similarity index 100% rename from client/src/assets/player/shared/metrics/index.ts rename to client/src/standalone/player/src/shared/metrics/index.ts diff --git a/client/src/assets/player/shared/metrics/metrics-plugin.ts b/client/src/standalone/player/src/shared/metrics/metrics-plugin.ts similarity index 100% rename from client/src/assets/player/shared/metrics/metrics-plugin.ts rename to client/src/standalone/player/src/shared/metrics/metrics-plugin.ts diff --git a/client/src/assets/player/shared/mobile/index.ts b/client/src/standalone/player/src/shared/mobile/index.ts similarity index 100% rename from client/src/assets/player/shared/mobile/index.ts rename to client/src/standalone/player/src/shared/mobile/index.ts diff --git a/client/src/assets/player/shared/mobile/peertube-mobile-buttons.ts b/client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts similarity index 100% rename from client/src/assets/player/shared/mobile/peertube-mobile-buttons.ts rename to client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts diff --git a/client/src/assets/player/shared/mobile/peertube-mobile-plugin.ts b/client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts similarity index 100% rename from client/src/assets/player/shared/mobile/peertube-mobile-plugin.ts rename to client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts diff --git a/client/src/assets/player/shared/p2p-media-loader/hls-plugin.ts b/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts similarity index 95% rename from client/src/assets/player/shared/p2p-media-loader/hls-plugin.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts index fd5fb2525ec..0bd34f8df65 100644 --- a/client/src/assets/player/shared/p2p-media-loader/hls-plugin.ts +++ b/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts @@ -5,6 +5,10 @@ import { logger } from '@root-helpers/logger' import Hlsjs, { ErrorData, Level, LevelSwitchingData, ManifestParsedData } from 'hls.js' import videojs from 'video.js' import { HLSPluginOptions, HlsjsConfigHandlerOptions, PeerTubeResolution, VideoJSTechHLS } from '../../types' +import { HlsJsP2PEngine, HlsWithP2PInstance } from 'p2p-media-loader-hlsjs' +import { omit } from '@peertube/peertube-core-utils' + +const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hlsjs) type ErrorCounts = { [ type: string ]: number @@ -14,8 +18,6 @@ type ErrorCounts = { // Source handler registration // --------------------------------------------------------------------------- -type HookFn = (player: videojs.Player, hljs: Hlsjs) => void - let alreadyRegistered = false const registerSourceHandler = function (vjs: typeof videojs) { @@ -110,8 +112,6 @@ videojs.registerPlugin('hlsjs', HLSJSConfigHandler) // --------------------------------------------------------------------------- export class Html5Hlsjs { - private static hooks: { [id: string]: HookFn[] } = {} - private readonly videoElement: HTMLVideoElement private readonly errorCounts: ErrorCounts = {} private readonly player: videojs.Player @@ -121,7 +121,7 @@ export class Html5Hlsjs { private maxNetworkErrorRecovery = 5 - private hls: Hlsjs + private hls: HlsWithP2PInstance private hlsjsConfig: HLSPluginOptions = null private _duration: number = null @@ -410,10 +410,15 @@ export class Html5Hlsjs { this.videoElement.addEventListener('play', this.handlers.play) } - const loader = this.hlsjsConfig.loaderBuilder() - this.hls = new Hlsjs({ ...this.hlsjsConfig, loader }) + this.hls = new HlsWithP2P({ + ...omit(this.hlsjsConfig, [ 'p2pMediaLoaderOptions' ]), - this.player.trigger('hlsjs-initialized', { hlsjs: this.hls, engine: loader.getEngine() }) + p2p: { + core: this.hlsjsConfig.p2pMediaLoaderOptions + } + }) + + this.player.trigger('hlsjs-initialized', { hlsjs: this.hls }) this.hls.on(Hlsjs.Events.ERROR, (event, data) => this._onError(event, data)) this.hls.on(Hlsjs.Events.MANIFEST_PARSED, (event, data) => this._onMetaData(event, data)) @@ -462,17 +467,21 @@ export class Html5Hlsjs { this.hlsjsConfig.autoStartLoad = true this.player.autoplay('play') - const loader = this.hlsjsConfig.loaderBuilder() - this.hls = new Hlsjs({ - ...this.hlsjsConfig, - loader, + this.hls = new HlsWithP2P({ + ...omit(this.hlsjsConfig, [ 'p2pMediaLoaderOptions' ]), + + p2p: { + core: this.hlsjsConfig.p2pMediaLoaderOptions + }, + startPosition: this.duration() === Infinity ? undefined : currentTime, + startLevel }) - this.player.trigger('hlsjs-initialized', { hlsjs: this.hls, engine: loader.getEngine() }) + this.player.trigger('hlsjs-initialized', { hlsjs: this.hls }) this.hls.on(Hlsjs.Events.ERROR, (event, data) => this._onError(event, data)) this.registerLevelEventSwitch() diff --git a/client/src/assets/player/shared/p2p-media-loader/index.ts b/client/src/standalone/player/src/shared/p2p-media-loader/index.ts similarity index 100% rename from client/src/assets/player/shared/p2p-media-loader/index.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/index.ts diff --git a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts similarity index 73% rename from client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts index abcbd226189..b2c82bb0038 100644 --- a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts +++ b/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts @@ -1,9 +1,9 @@ -import { Events, Segment } from '@peertube/p2p-media-loader-core' -import { Engine, initHlsJsPlayer } from '@peertube/p2p-media-loader-hlsjs' import { addQueryParams } from '@peertube/peertube-core-utils' import { logger } from '@root-helpers/logger' import debug from 'debug' -import Hlsjs from 'hls.js' +import { FragLoadedData, default as Hls, default as Hlsjs } from 'hls.js' +import type { DownloadSource, SegmentErrorDetails, SegmentLoadDetails } from 'p2p-media-loader-core' +import type { HlsWithP2PInstance } from 'p2p-media-loader-hlsjs' import videojs from 'video.js' import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../../types' import { SettingsButton } from '../settings/settings-menu-button' @@ -14,8 +14,7 @@ const Plugin = videojs.getPlugin('plugin') class P2pMediaLoaderPlugin extends Plugin { declare private readonly options: P2PMediaLoaderPluginOptions - declare private hlsjs: Hlsjs - declare private p2pEngine: Engine + declare private hlsjs: HlsWithP2PInstance declare private statsP2PBytes: { pendingDownload: number[] pendingUpload: number[] @@ -33,6 +32,9 @@ class P2pMediaLoaderPlugin extends Plugin { declare private liveEnded: boolean + declare private connectedPeers: Set + declare private totalHTTPPeers: number + constructor (player: videojs.Player, options?: P2PMediaLoaderPluginOptions) { super(player) @@ -76,15 +78,13 @@ class P2pMediaLoaderPlugin extends Plugin { } { - const onHLSJSInitialized = (_: any, { hlsjs, engine }: { hlsjs: Hlsjs, engine: Engine }) => { - this.p2pEngine?.removeAllListeners() - this.p2pEngine?.destroy() + const onHLSJSInitialized = (_: any, { hlsjs }: { hlsjs: HlsWithP2PInstance }) => { + this.hlsjs?.p2pEngine?.destroy() clearInterval(this.networkInfoInterval) this.hlsjs = hlsjs - this.p2pEngine = engine - debugLogger('hls.js initialized, initializing p2p-media-loader plugin', { hlsjs, engine }) + debugLogger('hls.js initialized, initializing p2p-media-loader plugin', { hlsjs }) player.ready(() => this.initializePlugin()) } @@ -116,8 +116,7 @@ class P2pMediaLoaderPlugin extends Plugin { } dispose () { - this.p2pEngine?.removeAllListeners() - this.p2pEngine?.destroy() + this.hlsjs?.p2pEngine?.destroy() this.hlsjs?.destroy() this.options.segmentValidator?.destroy() @@ -152,15 +151,22 @@ class P2pMediaLoaderPlugin extends Plugin { } private initializePlugin () { - initHlsJsPlayer(this.player, this.hlsjs) + this.hlsjs.p2pEngine.addEventListener('onSegmentError', (details: SegmentErrorDetails) => { + if (navigator.onLine === false || this.liveEnded || details.downloadSource !== 'http') return + + const segment = details.segment + logger.clientError(`Segment ${segment.runtimeId} error.`, details) - this.p2pEngine.on(Events.SegmentError, (segment: Segment, err) => { - if (navigator.onLine === false || this.liveEnded) return + if (this.options.redundancyUrlManager) { + this.options.redundancyUrlManager.onSegmentError(segment.url) + } + }) - logger.clientError(`Segment ${segment.id} error.`, err) + this.hlsjs.p2pEngine.addEventListener('onSegmentLoaded', (details: SegmentLoadDetails) => { + if (details.downloadSource !== 'http') return if (this.options.redundancyUrlManager) { - this.options.redundancyUrlManager.removeBySegmentUrl(segment.requestUrl) + this.options.redundancyUrlManager.onSegmentSuccess(details.segmentUrl) } }) @@ -168,7 +174,8 @@ class P2pMediaLoaderPlugin extends Plugin { ? this.options.redundancyUrlManager.countBaseUrls() : 0 - this.statsP2PBytes.peersWithWebSeed = 1 + redundancyUrlsCount + this.totalHTTPPeers = 1 + redundancyUrlsCount + this.statsP2PBytes.peersWithWebSeed = this.totalHTTPPeers this.runStats() @@ -200,30 +207,45 @@ class P2pMediaLoaderPlugin extends Plugin { } private runStats () { - this.p2pEngine.on(Events.PieceBytesDownloaded, (method: string, _segment, bytes: number) => { + this.connectedPeers = new Set() + + if (this.hlsjs.p2pEngine.getConfig().core.mainStream.isP2PDisabled) { + this.hlsjs.on(Hls.Events.FRAG_LOADED, (e, data: FragLoadedData) => { + const bytes = data.frag.stats.loaded + console.log(bytes) + + this.statsHTTPBytes.pendingDownload.push(bytes) + this.statsHTTPBytes.totalDownload += bytes + }) + } + + this.hlsjs.p2pEngine.addEventListener('onChunkDownloaded', (bytes: number, method: DownloadSource) => { const elem = method === 'p2p' ? this.statsP2PBytes : this.statsHTTPBytes elem.pendingDownload.push(bytes) elem.totalDownload += bytes }) - this.p2pEngine.on(Events.PieceBytesUploaded, (method: string, _segment, bytes: number) => { - if (method !== 'p2p') { - logger.error(`Received upload from unknown method ${method}`) - return - } - + this.hlsjs.p2pEngine.addEventListener('onChunkUploaded', (bytes: number) => { this.statsP2PBytes.pendingUpload.push(bytes) this.statsP2PBytes.totalUpload += bytes }) - this.p2pEngine.on(Events.PeerConnect, () => { - this.statsP2PBytes.peersWithWebSeed++ - this.statsP2PBytes.peersP2POnly++ + this.hlsjs.p2pEngine.addEventListener('onPeerConnect', peer => { + if (peer.streamType !== 'main') return + + this.connectedPeers.add(peer.peerId) + this.statsP2PBytes.peersP2POnly = this.connectedPeers.size + + this.statsP2PBytes.peersWithWebSeed = this.totalHTTPPeers + this.statsP2PBytes.peersP2POnly }) - this.p2pEngine.on(Events.PeerClose, () => { - this.statsP2PBytes.peersWithWebSeed-- - this.statsP2PBytes.peersP2POnly-- + this.hlsjs.p2pEngine.addEventListener('onPeerClose', peer => { + if (peer.streamType !== 'main') return + + this.connectedPeers.delete(peer.peerId) + this.statsP2PBytes.peersP2POnly = this.connectedPeers.size + + this.statsP2PBytes.peersWithWebSeed = this.totalHTTPPeers + this.statsP2PBytes.peersP2POnly }) this.networkInfoInterval = setInterval(() => { diff --git a/client/src/assets/player/shared/p2p-media-loader/redundancy-url-manager.ts b/client/src/standalone/player/src/shared/p2p-media-loader/redundancy-url-manager.ts similarity index 67% rename from client/src/assets/player/shared/p2p-media-loader/redundancy-url-manager.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/redundancy-url-manager.ts index ab051ca4450..ec7a219b7fc 100644 --- a/client/src/assets/player/shared/p2p-media-loader/redundancy-url-manager.ts +++ b/client/src/standalone/player/src/shared/p2p-media-loader/redundancy-url-manager.ts @@ -1,22 +1,32 @@ import { logger } from '@root-helpers/logger' class RedundancyUrlManager { + private map = new Map() constructor (private baseUrls: string[] = []) { // empty } - removeBySegmentUrl (segmentUrl: string) { - const baseUrl = getBaseUrl(segmentUrl) + onSegmentError (segmentUrl: string) { + if (!this.map.has(segmentUrl)) return + + const customSegmentUrl = this.map.get(segmentUrl) + this.map.delete(segmentUrl) + + const baseUrl = getBaseUrl(customSegmentUrl) const oldLength = baseUrl.length this.baseUrls = this.baseUrls.filter(u => u !== baseUrl && u !== baseUrl + '/') if (oldLength !== this.baseUrls.length) { - logger.info(`Removed redundancy of segment URL ${segmentUrl}.`) + logger.info(`Removed redundancy of segment URL ${customSegmentUrl}.`) } } + onSegmentSuccess (segmentUrl: string) { + this.map.delete(segmentUrl) + } + buildUrl (url: string) { const max = this.baseUrls.length + 1 const i = this.getRandomInt(max) @@ -26,7 +36,11 @@ class RedundancyUrlManager { const newBaseUrl = this.baseUrls[i] const slashPart = newBaseUrl.endsWith('/') ? '' : '/' - return newBaseUrl + slashPart + getFilename(url) + const newUrl = newBaseUrl + slashPart + getFilename(url) + + this.map.set(url, newUrl) + + return newUrl } countBaseUrls () { diff --git a/client/src/assets/player/shared/p2p-media-loader/segment-url-builder.ts b/client/src/standalone/player/src/shared/p2p-media-loader/segment-url-builder.ts similarity index 80% rename from client/src/assets/player/shared/p2p-media-loader/segment-url-builder.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/segment-url-builder.ts index 8875e5353c1..9cd1d979c11 100644 --- a/client/src/assets/player/shared/p2p-media-loader/segment-url-builder.ts +++ b/client/src/standalone/player/src/shared/p2p-media-loader/segment-url-builder.ts @@ -1,8 +1,9 @@ -import { Segment } from '@peertube/p2p-media-loader-core' +import type { Segment } from 'p2p-media-loader-core' import { RedundancyUrlManager } from './redundancy-url-manager' export function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager | null) { return function segmentBuilder (segment: Segment) { + console.log(segment) if (!redundancyUrlManager) return segment.url return redundancyUrlManager.buildUrl(segment.url) diff --git a/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts b/client/src/standalone/player/src/shared/p2p-media-loader/segment-validator.ts similarity index 76% rename from client/src/assets/player/shared/p2p-media-loader/segment-validator.ts rename to client/src/standalone/player/src/shared/p2p-media-loader/segment-validator.ts index e5f6631171c..d88ba5ebc48 100644 --- a/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts +++ b/client/src/standalone/player/src/shared/p2p-media-loader/segment-validator.ts @@ -1,9 +1,9 @@ -import { Segment } from '@peertube/p2p-media-loader-core' +import type { ByteRange } from 'p2p-media-loader-core' +import { removeQueryParams } from '@peertube/peertube-core-utils' import { logger } from '@root-helpers/logger' import { wait } from '@root-helpers/utils' -import { removeQueryParams } from '@peertube/peertube-core-utils' -import { isSameOrigin } from '../common' import debug from 'debug' +import { isSameOrigin } from '../common' const debugLogger = debug('peertube:player:segment-validator') @@ -12,9 +12,6 @@ type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string const maxRetries = 10 export class SegmentValidator { - - private readonly bytesRangeRegex = /bytes=(\d+)-(\d+)/ - private destroyed = false private segmentJSONPromise: Promise @@ -29,17 +26,18 @@ export class SegmentValidator { }) { } - async validate (segment: Segment, _method: string, _peerId: string, retry = 1) { - if (this.destroyed) return + async validate (url: string, byteRange: ByteRange | undefined, data: ArrayBuffer, retry = 1): Promise { + if (this.destroyed) return false this.loadSha256SegmentsPromiseIfNeeded() - const filename = removeQueryParams(segment.url).split('/').pop() + const filename = removeQueryParams(url).split('/').pop() const segmentValue = (await this.segmentJSONPromise)[filename] if (!segmentValue && retry > maxRetries) { - throw new Error(`Unknown segment name ${filename} in segment validator`) + logger.clientError(`Unknown segment name ${filename} in segment validator`) + return false } if (!segmentValue) { @@ -49,9 +47,7 @@ export class SegmentValidator { this.loadSha256SegmentsPromise() - await this.validate(segment, _method, _peerId, retry + 1) - - return + return this.validate(url, byteRange, data, retry + 1) } let hashShouldBe: string @@ -60,24 +56,25 @@ export class SegmentValidator { if (typeof segmentValue === 'string') { hashShouldBe = segmentValue } else { - const captured = this.bytesRangeRegex.exec(segment.range) - range = captured[1] + '-' + captured[2] + range = byteRange.start + '-' + byteRange.end hashShouldBe = segmentValue[range] } if (hashShouldBe === undefined) { - throw new Error(`Unknown segment name ${filename}/${range} in segment validator`) + logger.clientError(`Unknown segment name ${filename}/${range} in segment validator`) + return false } - debugLogger(`Validating ${filename}` + (segment.range ? ` range ${segment.range}` : '')) + debugLogger(`Validating ${filename}` + (range ? ` range ${range}` : '')) - const calculatedSha = await this.sha256Hex(segment.data) + const calculatedSha = await this.sha256Hex(data) if (calculatedSha !== hashShouldBe) { - throw new Error( - `Hashes does not correspond for segment ${filename}/${range}` + - `(expected: ${hashShouldBe} instead of ${calculatedSha})` + logger.clientError( + `Hashes does not correspond for segment ${filename}/${range} (expected: ${hashShouldBe} instead of ${calculatedSha})` ) + + return true } } @@ -106,7 +103,7 @@ export class SegmentValidator { return fetch(this.options.segmentsSha256Url, { headers }) .then(res => res.json() as Promise) .catch(err => { - logger.error('Cannot get sha256 segments', err) + logger.clientError('Cannot get sha256 segments', err) return {} }) } diff --git a/client/src/assets/player/shared/peertube/index.ts b/client/src/standalone/player/src/shared/peertube/index.ts similarity index 100% rename from client/src/assets/player/shared/peertube/index.ts rename to client/src/standalone/player/src/shared/peertube/index.ts diff --git a/client/src/assets/player/shared/peertube/peertube-plugin.ts b/client/src/standalone/player/src/shared/peertube/peertube-plugin.ts similarity index 100% rename from client/src/assets/player/shared/peertube/peertube-plugin.ts rename to client/src/standalone/player/src/shared/peertube/peertube-plugin.ts diff --git a/client/src/assets/player/shared/player-options-builder/control-bar-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts similarity index 100% rename from client/src/assets/player/shared/player-options-builder/control-bar-options-builder.ts rename to client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts diff --git a/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts similarity index 63% rename from client/src/assets/player/shared/player-options-builder/hls-options-builder.ts rename to client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts index db33c06c3dc..b115013df42 100644 --- a/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts +++ b/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts @@ -1,13 +1,11 @@ -import { HybridLoaderSettings } from '@peertube/p2p-media-loader-core' -import { Engine, HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs' import { getResolutionAndFPSLabel, getResolutionLabel } from '@peertube/peertube-core-utils' import { LiveVideoLatencyMode } from '@peertube/peertube-models' import { logger } from '@root-helpers/logger' -import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' +import debug from 'debug' import { Level } from 'hls.js' +import type { CoreConfig, StreamConfig } from 'p2p-media-loader-core' import { getAverageBandwidthInStore } from '../../peertube-player-local-storage' import { - HLSLoaderClass, HLSPluginOptions, P2PMediaLoaderPluginOptions, PeerTubePlayerConstructorOptions, @@ -15,9 +13,7 @@ import { } from '../../types' import { getRtcConfig, isSameOrigin } from '../common' import { RedundancyUrlManager } from '../p2p-media-loader/redundancy-url-manager' -import { segmentUrlBuilderFactory } from '../p2p-media-loader/segment-url-builder' import { SegmentValidator } from '../p2p-media-loader/segment-validator' -import debug from 'debug' const debugLogger = debug('peertube:player:hls') @@ -58,7 +54,6 @@ export class HLSOptionsBuilder { 'filter:internal.player.p2p-media-loader.options.result', this.getP2PMediaLoaderOptions({ redundancyUrlManager, segmentValidator }) ) - const loaderBuilder = () => new Engine(p2pMediaLoaderConfig).createLoaderClass() as unknown as HLSLoaderClass const p2pMediaLoader: P2PMediaLoaderPluginOptions = { requiresUserAuth: this.options.requiresUserAuth, @@ -73,7 +68,7 @@ export class HLSOptionsBuilder { } const hlsjs = { - hlsjsConfig: this.getHLSJSOptions(loaderBuilder), + hlsjsConfig: this.getHLSJSOptions(p2pMediaLoaderConfig), levelLabelHandler: (level: Level, player: videojs.VideoJsPlayer) => { const resolution = Math.min(level.height || 0, level.width || 0) @@ -99,65 +94,76 @@ export class HLSOptionsBuilder { private getP2PMediaLoaderOptions (options: { redundancyUrlManager: RedundancyUrlManager | null segmentValidator: SegmentValidator | null - }): HlsJsEngineSettings { + }) { const { redundancyUrlManager, segmentValidator } = options - let consumeOnly = false - if ( - (navigator as any)?.connection?.type === 'cellular' || - peertubeLocalStorage.getItem('peertube-videojs-p2p-consume-only') === 'true' // Use for E2E testing - ) { - logger.info('We are on a cellular connection: disabling seeding.') - consumeOnly = true - } - - const trackerAnnounce = this.options.hls.trackerAnnounce + // FIXME: Enable when https://github.com/Novage/p2p-media-loader/issues/428 is implemented + // let consumeOnly = false + // if ( + // (navigator as any)?.connection?.type === 'cellular' || + // peertubeLocalStorage.getItem('peertube-videojs-p2p-consume-only') === 'true' // Use for E2E testing + // ) { + // logger.info('We are on a cellular connection: disabling seeding.') + // consumeOnly = true + // } + + const announceTrackers = this.options.hls.trackerAnnounce .filter(t => t.startsWith('ws')) const specificLiveOrVODOptions = this.options.isLive ? this.getP2PMediaLoaderLiveOptions() : this.getP2PMediaLoaderVODOptions() - return { - loader: { - trackerAnnounce, - rtcConfig: getRtcConfig(this.options.stunServers), + const loaderOptions: Partial = { + announceTrackers, + rtcConfig: getRtcConfig(this.options.stunServers), - simultaneousHttpDownloads: 1, - httpFailedSegmentTimeout: 1000, + httpRequestSetup: (segmentUrlArg, segmentByteRange, requestAbortSignal, requestByteRange) => { + const { requiresUserAuth, requiresPassword } = this.options - xhrSetup: (xhr, url) => { - const { requiresUserAuth, requiresPassword } = this.options + const segmentUrl = redundancyUrlManager + ? redundancyUrlManager.buildUrl(segmentUrlArg) + : segmentUrlArg - if (!(requiresUserAuth || requiresPassword)) return + const headers = new Headers() - if (!isSameOrigin(this.options.serverUrl, url)) return + if (requestByteRange) { + headers.set('Range', `bytes=${requestByteRange.start}-${requestByteRange.end ?? ''}`) + } - if (requiresPassword) xhr.setRequestHeader('x-peertube-video-password', this.options.videoPassword()) - else xhr.setRequestHeader('Authorization', this.options.authorizationHeader()) - }, + if (isSameOrigin(this.options.serverUrl, segmentUrl)) { + if (requiresPassword) { + headers.set('x-peertube-video-password', this.options.videoPassword()) + } else if (requiresUserAuth) { + headers.set('Authorization', this.options.authorizationHeader()) + } + } - segmentValidator: segmentValidator - ? segmentValidator.validate.bind(segmentValidator) - : null, + return Promise.resolve( + new Request(segmentUrl, { + headers, + signal: requestAbortSignal + }) + ) + }, - segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager), + validateP2PSegment: segmentValidator + ? segmentValidator.validate.bind(segmentValidator) + : null, - useP2P: this.options.p2pEnabled, - consumeOnly, + isP2PDisabled: !this.options.p2pEnabled, - ...specificLiveOrVODOptions - }, - segments: { - swarmId: this.options.hls.playlistUrl, - forwardSegmentCount: specificLiveOrVODOptions.p2pDownloadMaxPriority ?? 20 - } + swarmId: this.options.hls.playlistUrl, + + ...specificLiveOrVODOptions } + + return { loader: loaderOptions } } - private getP2PMediaLoaderLiveOptions (): Partial { + private getP2PMediaLoaderLiveOptions (): Partial { const base = { - requiredSegmentsPriority: 1 + highDemandTimeWindow: 4 } const latencyMode = this.options.liveOptions.latencyMode @@ -167,8 +173,7 @@ export class HLSOptionsBuilder { return { ...base, - useP2P: false, - requiredSegmentsPriority: 10 + isP2PDisabled: true } case LiveVideoLatencyMode.HIGH_LATENCY: @@ -179,34 +184,39 @@ export class HLSOptionsBuilder { } } - private getP2PMediaLoaderVODOptions (): Partial { + private getP2PMediaLoaderVODOptions (): Partial { return { - requiredSegmentsPriority: 3, - skipSegmentBuilderPriority: 1, - - cachedSegmentExpiration: 86400000, - cachedSegmentsCount: 100, - - httpDownloadMaxPriority: 9, - httpDownloadProbability: 0.06, - httpDownloadProbabilitySkipIfNoPeers: true, + highDemandTimeWindow: 15, - p2pDownloadMaxPriority: 50 + segmentMemoryStorageLimit: 1024 } } // --------------------------------------------------------------------------- - private getHLSJSOptions (loaderBuilder: () => HLSLoaderClass): HLSPluginOptions { + private getHLSJSOptions (p2pMediaLoaderConfig: { loader: CoreConfig }): HLSPluginOptions { const specificLiveOrVODOptions = this.options.isLive ? this.getHLSLiveOptions() : this.getHLSVODOptions() - const base = { + const base: HLSPluginOptions = { capLevelToPlayerSize: true, autoStartLoad: false, - loaderBuilder, + p2pMediaLoaderOptions: p2pMediaLoaderConfig.loader, + + // p2p-media-loader uses hls.js loader to fetch m3u8 playlists + xhrSetup: (xhr, url) => { + const { requiresUserAuth, requiresPassword } = this.options + + if (isSameOrigin(this.options.serverUrl, url)) { + if (requiresPassword) { + xhr.setRequestHeader('x-peertube-video-password', this.options.videoPassword()) + } else if (requiresUserAuth) { + xhr.setRequestHeader('Authorization', this.options.authorizationHeader()) + } + } + }, ...specificLiveOrVODOptions } diff --git a/client/src/assets/player/shared/player-options-builder/index.ts b/client/src/standalone/player/src/shared/player-options-builder/index.ts similarity index 100% rename from client/src/assets/player/shared/player-options-builder/index.ts rename to client/src/standalone/player/src/shared/player-options-builder/index.ts diff --git a/client/src/assets/player/shared/player-options-builder/web-video-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/web-video-options-builder.ts similarity index 100% rename from client/src/assets/player/shared/player-options-builder/web-video-options-builder.ts rename to client/src/standalone/player/src/shared/player-options-builder/web-video-options-builder.ts diff --git a/client/src/assets/player/shared/playlist/index.ts b/client/src/standalone/player/src/shared/playlist/index.ts similarity index 100% rename from client/src/assets/player/shared/playlist/index.ts rename to client/src/standalone/player/src/shared/playlist/index.ts diff --git a/client/src/assets/player/shared/playlist/playlist-button.ts b/client/src/standalone/player/src/shared/playlist/playlist-button.ts similarity index 100% rename from client/src/assets/player/shared/playlist/playlist-button.ts rename to client/src/standalone/player/src/shared/playlist/playlist-button.ts diff --git a/client/src/assets/player/shared/playlist/playlist-menu-item.ts b/client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts similarity index 100% rename from client/src/assets/player/shared/playlist/playlist-menu-item.ts rename to client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts diff --git a/client/src/assets/player/shared/playlist/playlist-menu.ts b/client/src/standalone/player/src/shared/playlist/playlist-menu.ts similarity index 100% rename from client/src/assets/player/shared/playlist/playlist-menu.ts rename to client/src/standalone/player/src/shared/playlist/playlist-menu.ts diff --git a/client/src/assets/player/shared/playlist/playlist-plugin.ts b/client/src/standalone/player/src/shared/playlist/playlist-plugin.ts similarity index 100% rename from client/src/assets/player/shared/playlist/playlist-plugin.ts rename to client/src/standalone/player/src/shared/playlist/playlist-plugin.ts diff --git a/client/src/assets/player/shared/resolutions/index.ts b/client/src/standalone/player/src/shared/resolutions/index.ts similarity index 100% rename from client/src/assets/player/shared/resolutions/index.ts rename to client/src/standalone/player/src/shared/resolutions/index.ts diff --git a/client/src/assets/player/shared/resolutions/peertube-resolutions-plugin.ts b/client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts similarity index 100% rename from client/src/assets/player/shared/resolutions/peertube-resolutions-plugin.ts rename to client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts diff --git a/client/src/assets/player/shared/settings/index.ts b/client/src/standalone/player/src/shared/settings/index.ts similarity index 100% rename from client/src/assets/player/shared/settings/index.ts rename to client/src/standalone/player/src/shared/settings/index.ts diff --git a/client/src/assets/player/shared/settings/menu-focus-fixed.ts b/client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts similarity index 100% rename from client/src/assets/player/shared/settings/menu-focus-fixed.ts rename to client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts diff --git a/client/src/assets/player/shared/settings/resolution-menu-button.ts b/client/src/standalone/player/src/shared/settings/resolution-menu-button.ts similarity index 100% rename from client/src/assets/player/shared/settings/resolution-menu-button.ts rename to client/src/standalone/player/src/shared/settings/resolution-menu-button.ts diff --git a/client/src/assets/player/shared/settings/resolution-menu-item.ts b/client/src/standalone/player/src/shared/settings/resolution-menu-item.ts similarity index 100% rename from client/src/assets/player/shared/settings/resolution-menu-item.ts rename to client/src/standalone/player/src/shared/settings/resolution-menu-item.ts diff --git a/client/src/assets/player/shared/settings/settings-dialog.ts b/client/src/standalone/player/src/shared/settings/settings-dialog.ts similarity index 100% rename from client/src/assets/player/shared/settings/settings-dialog.ts rename to client/src/standalone/player/src/shared/settings/settings-dialog.ts diff --git a/client/src/assets/player/shared/settings/settings-menu-button.ts b/client/src/standalone/player/src/shared/settings/settings-menu-button.ts similarity index 100% rename from client/src/assets/player/shared/settings/settings-menu-button.ts rename to client/src/standalone/player/src/shared/settings/settings-menu-button.ts diff --git a/client/src/assets/player/shared/settings/settings-menu-item.ts b/client/src/standalone/player/src/shared/settings/settings-menu-item.ts similarity index 100% rename from client/src/assets/player/shared/settings/settings-menu-item.ts rename to client/src/standalone/player/src/shared/settings/settings-menu-item.ts diff --git a/client/src/assets/player/shared/settings/settings-panel-child.ts b/client/src/standalone/player/src/shared/settings/settings-panel-child.ts similarity index 100% rename from client/src/assets/player/shared/settings/settings-panel-child.ts rename to client/src/standalone/player/src/shared/settings/settings-panel-child.ts diff --git a/client/src/assets/player/shared/settings/settings-panel.ts b/client/src/standalone/player/src/shared/settings/settings-panel.ts similarity index 100% rename from client/src/assets/player/shared/settings/settings-panel.ts rename to client/src/standalone/player/src/shared/settings/settings-panel.ts diff --git a/client/src/assets/player/shared/stats/index.ts b/client/src/standalone/player/src/shared/stats/index.ts similarity index 100% rename from client/src/assets/player/shared/stats/index.ts rename to client/src/standalone/player/src/shared/stats/index.ts diff --git a/client/src/assets/player/shared/stats/stats-card.ts b/client/src/standalone/player/src/shared/stats/stats-card.ts similarity index 99% rename from client/src/assets/player/shared/stats/stats-card.ts rename to client/src/standalone/player/src/shared/stats/stats-card.ts index de25cae35cf..01971c7d0f9 100644 --- a/client/src/assets/player/shared/stats/stats-card.ts +++ b/client/src/standalone/player/src/shared/stats/stats-card.ts @@ -138,6 +138,8 @@ class StatsCard extends Component { this.containerEl.style.display = 'block' this.updateInterval = setInterval(async () => { + if (!this.mode) return + try { const options = this.mode === 'p2p-media-loader' ? this.buildHLSOptions() diff --git a/client/src/assets/player/shared/stats/stats-plugin.ts b/client/src/standalone/player/src/shared/stats/stats-plugin.ts similarity index 100% rename from client/src/assets/player/shared/stats/stats-plugin.ts rename to client/src/standalone/player/src/shared/stats/stats-plugin.ts diff --git a/client/src/assets/player/shared/upnext/end-card.ts b/client/src/standalone/player/src/shared/upnext/end-card.ts similarity index 100% rename from client/src/assets/player/shared/upnext/end-card.ts rename to client/src/standalone/player/src/shared/upnext/end-card.ts diff --git a/client/src/assets/player/shared/upnext/index.ts b/client/src/standalone/player/src/shared/upnext/index.ts similarity index 100% rename from client/src/assets/player/shared/upnext/index.ts rename to client/src/standalone/player/src/shared/upnext/index.ts diff --git a/client/src/assets/player/shared/upnext/upnext-plugin.ts b/client/src/standalone/player/src/shared/upnext/upnext-plugin.ts similarity index 100% rename from client/src/assets/player/shared/upnext/upnext-plugin.ts rename to client/src/standalone/player/src/shared/upnext/upnext-plugin.ts diff --git a/client/src/assets/player/shared/web-video/web-video-plugin.ts b/client/src/standalone/player/src/shared/web-video/web-video-plugin.ts similarity index 100% rename from client/src/assets/player/shared/web-video/web-video-plugin.ts rename to client/src/standalone/player/src/shared/web-video/web-video-plugin.ts diff --git a/client/src/assets/player/types/index.ts b/client/src/standalone/player/src/types/index.ts similarity index 100% rename from client/src/assets/player/types/index.ts rename to client/src/standalone/player/src/types/index.ts diff --git a/client/src/assets/player/types/peertube-player-options.ts b/client/src/standalone/player/src/types/peertube-player-options.ts similarity index 100% rename from client/src/assets/player/types/peertube-player-options.ts rename to client/src/standalone/player/src/types/peertube-player-options.ts diff --git a/client/src/assets/player/types/peertube-videojs-typings.ts b/client/src/standalone/player/src/types/peertube-videojs-typings.ts similarity index 96% rename from client/src/assets/player/types/peertube-videojs-typings.ts rename to client/src/standalone/player/src/types/peertube-videojs-typings.ts index 671d2f56951..b78038e271a 100644 --- a/client/src/assets/player/types/peertube-videojs-typings.ts +++ b/client/src/standalone/player/src/types/peertube-videojs-typings.ts @@ -1,6 +1,7 @@ -import { Engine } from '@peertube/p2p-media-loader-hlsjs' import { VideoChapter, VideoFile, VideoPlaylist, VideoPlaylistElement } from '@peertube/peertube-models' import type { HlsConfig, Level, Loader, LoaderContext } from 'hls.js' +import type { CoreConfig } from 'p2p-media-loader-core' +import type { HlsJsP2PEngine } from 'p2p-media-loader-hlsjs' import videojs from 'video.js' import { BezelsPlugin } from '../shared/bezels/bezels-plugin' import { ContextMenuPlugin } from '../shared/context-menu' @@ -215,9 +216,9 @@ export type WebVideoPluginOptions = { export type HLSLoaderClass = { new (confg: HlsConfig): Loader - getEngine(): Engine + getEngine(): HlsJsP2PEngine } -export type HLSPluginOptions = Partial HLSLoaderClass }> +export type HLSPluginOptions = Partial export type P2PMediaLoaderPluginOptions = { redundancyUrlManager: RedundancyUrlManager | null @@ -233,7 +234,7 @@ export type P2PMediaLoaderPluginOptions = { } export type P2PMediaLoader = { - getEngine(): Engine + getEngine(): HlsJsP2PEngine destroy: () => void } diff --git a/client/src/standalone/player/tsconfig.json b/client/src/standalone/player/tsconfig.json new file mode 100644 index 00000000000..c2187c8c04a --- /dev/null +++ b/client/src/standalone/player/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + "./index.ts" + ] +} diff --git a/client/src/standalone/player/vite.config.mjs b/client/src/standalone/player/vite.config.mjs new file mode 100644 index 00000000000..a734e697052 --- /dev/null +++ b/client/src/standalone/player/vite.config.mjs @@ -0,0 +1,56 @@ +import { nodePolyfills } from 'vite-plugin-node-polyfills' +import { dirname, resolve } from 'path' +import { fileURLToPath } from 'url' +import { defineConfig } from 'vite' +import checker from 'vite-plugin-checker' + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const root = resolve(__dirname, '../../../') + +export default defineConfig(() => { + return { + build: { + outDir: resolve(__dirname, 'build'), + emptyOutDir: false, + minify: false, + lib: { + formats: [ 'es' ], + entry: resolve(__dirname, './src/index.ts'), + name: 'PeerTubePlayer', + fileName: 'peertube-player', + cssFilename: 'peertube-player.css' + } + }, + + css: { + preprocessorOptions: { + scss: { + api: 'modern-compiler', + loadPaths: [ resolve(root, './src/sass/include') ], + // FIXME: Wait for bootstrap upgrade that fixes deprecated sass utils + silenceDeprecations: [ 'import', 'mixed-decls', 'color-functions', 'global-builtin' ] + } + } + }, + + resolve: { + alias: [ + { find: /^video.js$/, replacement: resolve(root, './node_modules/video.js/core.js') }, + { find: '@root-helpers', replacement: resolve(root, './src/root-helpers') } + ], + conditions: [ + 'p2pml:core-as-bundle', 'defaultClientConditions' + ] + }, + + plugins: [ + checker({ + typescript: { + tsconfigPath: resolve(__dirname, 'tsconfig.json') + } + }), + + nodePolyfills() + ] + } +}) diff --git a/client/src/standalone/videos/embed.scss b/client/src/standalone/videos/embed.scss index 44082e4a031..8f25b750124 100644 --- a/client/src/standalone/videos/embed.scss +++ b/client/src/standalone/videos/embed.scss @@ -1,11 +1,7 @@ @use '_variables' as *; @use '_mixins' as *; @use '_css-variables' as *; -@use 'video.js/dist/video-js'; - -$assets-path: '../../assets/'; - -@use '../../sass/player/index'; +@use '../player/build/peertube-player'; [hidden] { display: none !important; diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index dbb9478fe5b..4dfd76c6b73 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts @@ -1,8 +1,3 @@ -import './embed.scss' -import '../../assets/player/shared/dock/peertube-dock-component' -import '../../assets/player/shared/dock/peertube-dock-plugin' -import { PeerTubeServerError } from 'src/types' -import videojs from 'video.js' import { HTMLServerConfig, ResultList, @@ -12,10 +7,13 @@ import { VideoPlaylistElement, VideoState } from '@peertube/peertube-models' -import { PeerTubePlayer } from '../../assets/player/peertube-player' -import { TranslationsManager } from '../../assets/player/translations-manager' +import type { PeerTubePlayer } from '@peertube/player' +import { TranslationsManager } from '@root-helpers/translations-manager' +import { PeerTubeServerError } from 'src/types' +import videojs from 'video.js' import { getParamString, logger, videoRequiresFileToken } from '../../root-helpers' import { PeerTubeEmbedApi } from './embed-api' +import './embed.scss' import { AuthHTTP, LiveManager, @@ -94,7 +92,7 @@ export class PeerTubeEmbed { async init () { this.translationsPromise = TranslationsManager.getServerTranslations(getBackendUrl(), navigator.language) - this.PeerTubePlayerManagerModulePromise = import('../../assets/player/peertube-player') + this.PeerTubePlayerManagerModulePromise = import('@peertube/player') // Issue when we parsed config from HTML, fallback to API if (!this.config) { diff --git a/client/src/standalone/videos/shared/player-options-builder.ts b/client/src/standalone/videos/shared/player-options-builder.ts index 94b103f5047..9543df4f740 100644 --- a/client/src/standalone/videos/shared/player-options-builder.ts +++ b/client/src/standalone/videos/shared/player-options-builder.ts @@ -11,7 +11,6 @@ import { VideoState, VideoStreamingPlaylistType } from '@peertube/peertube-models' -import { HLSOptions, PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions, PlayerMode, VideoJSCaption } from '../../../assets/player' import { getBoolOrDefault, getParamString, @@ -22,12 +21,13 @@ import { UserLocalStorageKeys, videoRequiresUserAuth } from '../../../root-helpers' +import { HLSOptions, PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions, PlayerMode, VideoJSCaption } from '../../player' import { PeerTubePlugin } from './peertube-plugin' import { PlayerHTML } from './player-html' import { PlaylistTracker } from './playlist-tracker' import { Translations } from './translations' -import { VideoFetcher } from './video-fetcher' import { getBackendUrl } from './url' +import { VideoFetcher } from './video-fetcher' export class PlayerOptionsBuilder { private autoplay: boolean diff --git a/client/src/standalone/videos/vite.config.mjs b/client/src/standalone/videos/vite.config.mjs index 7c69fd1142e..755be6c9dbe 100644 --- a/client/src/standalone/videos/vite.config.mjs +++ b/client/src/standalone/videos/vite.config.mjs @@ -50,7 +50,9 @@ export default defineConfig(({ mode }) => { css: { preprocessorOptions: { scss: { - includePaths: [resolve(root, './src/sass/include')] + loadPaths: [resolve(root, './src/sass/include')], + // FIXME: Wait for bootstrap upgrade that fixes deprecated sass utils + silenceDeprecations: [ 'import', 'mixed-decls', 'color-functions', 'global-builtin' ] } } }, @@ -60,7 +62,7 @@ export default defineConfig(({ mode }) => { emptyOutDir: true, sourcemap: mode === 'development', - target: [ 'firefox78', 'ios12' ], + target: [ 'firefox78', 'ios14' ], rollupOptions: { input: { diff --git a/client/tsconfig.json b/client/tsconfig.json index 7ee9ab6e456..c9a59b3c92f 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -65,6 +65,11 @@ "strictInjectionParameters": true, "fullTemplateTypeCheck": true, "strictTemplates": true, - "enableI18nLegacyMessageIdFormat": false + "enableI18nLegacyMessageIdFormat": false, + "extendedDiagnostics": { + "checks": { + "unusedStandaloneImports": "suppress" + } + } } } diff --git a/client/yarn.lock b/client/yarn.lock index 0ef35537301..9768ca513fe 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -454,6 +454,11 @@ axios "^1.7.4" uuid "9.0.1" +"@bufbuild/protobuf@^2.0.0": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.2.3.tgz#9cd136f6b687e63e9b517b3a54211ece942897ee" + integrity sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg== + "@colors/colors@1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" @@ -500,171 +505,86 @@ esquery "^1.6.0" jsdoc-type-pratt-parser "~4.0.0" -"@esbuild/aix-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" - integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== - "@esbuild/aix-ppc64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461" integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA== -"@esbuild/android-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" - integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== - "@esbuild/android-arm64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894" integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg== -"@esbuild/android-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" - integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== - "@esbuild/android-arm@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3" integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q== -"@esbuild/android-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" - integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== - "@esbuild/android-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb" integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw== -"@esbuild/darwin-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" - integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== - "@esbuild/darwin-arm64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936" integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA== -"@esbuild/darwin-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" - integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== - "@esbuild/darwin-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9" integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA== -"@esbuild/freebsd-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" - integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== - "@esbuild/freebsd-arm64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00" integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg== -"@esbuild/freebsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" - integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== - "@esbuild/freebsd-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f" integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q== -"@esbuild/linux-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" - integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== - "@esbuild/linux-arm64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43" integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg== -"@esbuild/linux-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" - integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== - "@esbuild/linux-arm@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736" integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA== -"@esbuild/linux-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" - integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== - "@esbuild/linux-ia32@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5" integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw== -"@esbuild/linux-loong64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" - integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== - "@esbuild/linux-loong64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc" integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ== -"@esbuild/linux-mips64el@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" - integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== - "@esbuild/linux-mips64el@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb" integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw== -"@esbuild/linux-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" - integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== - "@esbuild/linux-ppc64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412" integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw== -"@esbuild/linux-riscv64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" - integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== - "@esbuild/linux-riscv64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694" integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q== -"@esbuild/linux-s390x@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" - integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== - "@esbuild/linux-s390x@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577" integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw== -"@esbuild/linux-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" - integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== - "@esbuild/linux-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f" @@ -675,11 +595,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6" integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw== -"@esbuild/netbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" - integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== - "@esbuild/netbsd-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40" @@ -690,51 +605,26 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f" integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A== -"@esbuild/openbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" - integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== - "@esbuild/openbsd-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205" integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA== -"@esbuild/sunos-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" - integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== - "@esbuild/sunos-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6" integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig== -"@esbuild/win32-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" - integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== - "@esbuild/win32-arm64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85" integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ== -"@esbuild/win32-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" - integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== - "@esbuild/win32-ia32@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2" integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA== -"@esbuild/win32-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" - integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== - "@esbuild/win32-x64@0.24.2": version "0.24.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b" @@ -1495,29 +1385,6 @@ smtp-server "^3.9.0" wildstring "1.0.9" -"@peertube/p2p-media-loader-core@^1.0.20": - version "1.0.20" - resolved "https://registry.yarnpkg.com/@peertube/p2p-media-loader-core/-/p2p-media-loader-core-1.0.20.tgz#8e786dd52471a03fc00006d14b150b38fe7c8211" - integrity sha512-t6yYFcBTqDZSp3U0HqOI9fJzxFgb2C4PoiRI4FPGd28baUbsilO1PQBRwQzvu6wt8zwjzOE8FBpzYa+1gv1Sqg== - dependencies: - bittorrent-tracker "^11.1.0" - debug "^4.3.5" - esbuild "^0.21.5" - events "^3.3.0" - sha.js "^2.4.11" - simple-peer "^9.11.1" - -"@peertube/p2p-media-loader-hlsjs@^1.0.20": - version "1.0.20" - resolved "https://registry.yarnpkg.com/@peertube/p2p-media-loader-hlsjs/-/p2p-media-loader-hlsjs-1.0.20.tgz#b6330d5331a70fa3a65ef3c32546b8d88c065749" - integrity sha512-PZS9h+txV+BX3t5lsh5PZ0ZtOogPJv4GmheQ5etceQZHxRAx2UxcAchMBJsa/sQ5c4CSMsN61Megs9iZ3gWauQ== - dependencies: - "@peertube/p2p-media-loader-core" "^1.0.20" - debug "^4.3.5" - esbuild "^0.21.5" - events "^3.3.0" - m3u8-parser "~4.7.1" - "@peertube/xliffmerge@^2.0.3": version "2.0.4" resolved "https://registry.yarnpkg.com/@peertube/xliffmerge/-/xliffmerge-2.0.4.tgz#5a80c263ab6f1b15a8b8c3e54317077f0d98e611" @@ -1609,9 +1476,9 @@ magic-string "^0.30.3" "@rollup/pluginutils@^5.0.1": - version "5.1.4" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.4.tgz#bb94f1f9eaaac944da237767cdfee6c5b2262d4a" - integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ== + version "5.1.3" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf" + integrity sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -1989,7 +1856,7 @@ resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.8.tgz#d5c6ec44f2f3328653dce385ae586bd8261f8e85" integrity sha512-VgnAj6tIAhJhZdJ8/IpxdatM8G4OD3VWGlp6xIxUGENZlpbob9Ty4VVdC1FIEp0aK6DBscDDjyzy5FB60TuNqg== -"@types/debug@^4.1.5": +"@types/debug@^4.1.12", "@types/debug@^4.1.5": version "4.1.12" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== @@ -2997,7 +2864,7 @@ bittorrent-peerid@^1.3.6: resolved "https://registry.yarnpkg.com/bittorrent-peerid/-/bittorrent-peerid-1.3.6.tgz#3688705a64937a8176ac2ded1178fc7bd91b61db" integrity sha512-VyLcUjVMEOdSpHaCG/7odvCdLbAB1y3l9A2V6WIje24uV7FkJPrQrH/RrlFmKxP89pFVDEnE+YlHaFujlFIZsg== -bittorrent-tracker@^11.1.0: +bittorrent-tracker@^11.2.1: version "11.2.1" resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-11.2.1.tgz#b45ff4bd70c2c582bc60d4a8bb6b5bdcb487df9a" integrity sha512-SffBgHzNrhn+HBwdRD2st+TYJOs2LhF3ljJFPCYGv592LpGtPxw41UZHTUeY5muWnQl+wopcU8qXM9UEk2WKrA== @@ -3184,6 +3051,11 @@ browserstack-local@^1.5.1: ps-tree "=1.2.0" temp-fs "^0.9.9" +buffer-builder@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/buffer-builder/-/buffer-builder-0.2.0.tgz#3322cd307d8296dab1f604618593b261a3fade8f" + integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== + buffer-crc32@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-1.0.0.tgz#a10993b9055081d55304bd9feb4a072de179f405" @@ -3544,6 +3416,11 @@ colorette@^2.0.20: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +colorjs.io@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef" + integrity sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3811,7 +3688,7 @@ data-view-byte-offset@^1.0.1: es-errors "^1.3.0" is-data-view "^1.0.1" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.3.7: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== @@ -3832,7 +3709,7 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@~4.3.1, debug@~4.3.2: +debug@^4.3.7, debug@~4.3.1, debug@~4.3.2: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -4022,10 +3899,10 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== -domain-browser@4.22.0: - version "4.22.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.22.0.tgz#6ddd34220ec281f9a65d3386d267ddd35c491f9f" - integrity sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw== +domain-browser@^4.22.0: + version "4.23.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.23.0.tgz#427ebb91efcb070f05cffdfb8a4e9a6c25f8c94b" + integrity sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA== domelementtype@^2.3.0: version "2.3.0" @@ -4129,9 +4006,9 @@ electron-to-chromium@^1.5.73: integrity sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug== elliptic@^6.5.3, elliptic@^6.5.5: - version "6.6.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" - integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== + version "6.6.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.0.tgz#5919ec723286c1edf28685aa89261d4761afa210" + integrity sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -4354,35 +4231,6 @@ esbuild@0.24.2, esbuild@^0.24.2: "@esbuild/win32-ia32" "0.24.2" "@esbuild/win32-x64" "0.24.2" -esbuild@^0.21.3, esbuild@^0.21.5: - version "0.21.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" - integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== - optionalDependencies: - "@esbuild/aix-ppc64" "0.21.5" - "@esbuild/android-arm" "0.21.5" - "@esbuild/android-arm64" "0.21.5" - "@esbuild/android-x64" "0.21.5" - "@esbuild/darwin-arm64" "0.21.5" - "@esbuild/darwin-x64" "0.21.5" - "@esbuild/freebsd-arm64" "0.21.5" - "@esbuild/freebsd-x64" "0.21.5" - "@esbuild/linux-arm" "0.21.5" - "@esbuild/linux-arm64" "0.21.5" - "@esbuild/linux-ia32" "0.21.5" - "@esbuild/linux-loong64" "0.21.5" - "@esbuild/linux-mips64el" "0.21.5" - "@esbuild/linux-ppc64" "0.21.5" - "@esbuild/linux-riscv64" "0.21.5" - "@esbuild/linux-s390x" "0.21.5" - "@esbuild/linux-x64" "0.21.5" - "@esbuild/netbsd-x64" "0.21.5" - "@esbuild/openbsd-x64" "0.21.5" - "@esbuild/sunos-x64" "0.21.5" - "@esbuild/win32-arm64" "0.21.5" - "@esbuild/win32-ia32" "0.21.5" - "@esbuild/win32-x64" "0.21.5" - escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" @@ -5031,11 +4879,6 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-browser-rtc@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" - integrity sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ== - get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -5356,12 +5199,12 @@ hash-base@^3.0.0: safe-buffer "^5.2.0" hash-base@~3.0, hash-base@~3.0.4: - version "3.0.5" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a" - integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg== + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow== dependencies: - inherits "^2.0.4" - safe-buffer "^5.2.1" + inherits "^2.0.1" + safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" @@ -6427,22 +6270,20 @@ m3u8-parser@4.8.0: "@videojs/vhs-utils" "^3.0.5" global "^4.4.0" -m3u8-parser@~4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.7.1.tgz#d6df2c940bb19a01112a04ccc4ff44886a945305" - integrity sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA== - dependencies: - "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "^3.0.5" - global "^4.4.0" - -magic-string@0.30.17, magic-string@^0.30.12, magic-string@^0.30.3: +magic-string@0.30.17, magic-string@^0.30.12: version "0.30.17" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" +magic-string@^0.30.3: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + mailparser-mit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mailparser-mit/-/mailparser-mit-1.0.0.tgz#19df8436c2a02e1d34a03ec518a2eb065e0a94a4" @@ -6855,6 +6696,11 @@ mux.js@6.0.1: "@babel/runtime" "^7.11.2" global "^4.4.0" +nano-md5@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nano-md5/-/nano-md5-1.0.5.tgz#99d155e95ccaadc4096a309292a0df1b5190514e" + integrity sha512-1VAOX0EiuwAdCMGpnglxp9r6ylm+gXwQi+UPAnc/Oj1tLLJ8D1I8rLZeiO4MWsUAqH8tuBAHweT1LYSrDfJlPg== + nanoid@^3.3.8: version "3.3.8" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" @@ -6888,9 +6734,9 @@ ngx-uploadx@^7.0.0: tslib "^2.3.0" node-abi@^3.3.0: - version "3.74.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.74.0.tgz#5bfb4424264eaeb91432d2adb9da23c63a301ed0" - integrity sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w== + version "3.71.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038" + integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw== dependencies: semver "^7.3.5" @@ -6946,9 +6792,9 @@ node-gyp-build-optional-packages@5.2.2: detect-libc "^2.0.1" node-gyp-build@^4.3.0: - version "4.8.4" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" - integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + version "4.8.3" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.3.tgz#9187216d24dbee29e44eb20d2ebf62a296bbea1a" + integrity sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw== node-gyp@^11.0.0: version "11.0.0" @@ -6982,9 +6828,9 @@ node-request-interceptor@^0.6.3: strict-event-emitter "^0.1.0" node-stdlib-browser@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/node-stdlib-browser/-/node-stdlib-browser-1.3.0.tgz#6e04d149f9abfc345a2271b2820a75df0f9cd7de" - integrity sha512-g/koYzOr9Fb1Jc+tHUHlFd5gODjGn48tHexUK8q6iqOVriEgSnd3/1T7myBYc+0KBVze/7F7n65ec9rW6OD7xw== + version "1.2.1" + resolved "https://registry.yarnpkg.com/node-stdlib-browser/-/node-stdlib-browser-1.2.1.tgz#888fa104914af94143ca4d8a8980fe0ed242d2d1" + integrity sha512-dZezG3D88Lg22DwyjsDuUs7cCT/XGr8WwJgg/S3ZnkcWuPet2Tt/W1d2Eytb1Z73JpZv+XVCDI5TWv6UMRq0Gg== dependencies: assert "^2.0.0" browser-resolve "^2.0.0" @@ -6994,7 +6840,7 @@ node-stdlib-browser@^1.2.0: constants-browserify "^1.0.0" create-require "^1.1.1" crypto-browserify "^3.11.0" - domain-browser "4.22.0" + domain-browser "^4.22.0" events "^3.0.0" https-browserify "^1.0.0" isomorphic-timers-promises "^1.0.1" @@ -7321,6 +7167,23 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +p2p-media-loader-core@2.1.1, p2p-media-loader-core@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p2p-media-loader-core/-/p2p-media-loader-core-2.1.1.tgz#0d59b7b2eacf5b1467342eb1a32f94dc1af546f5" + integrity sha512-sqQGeAuZejIC0e0gCj1kDqEuGqIewqhtDC2zIkesmJfBCW3gspg2NW8a5zl3H56vFBf3GleyYwgjAV01N2hBvQ== + dependencies: + "@types/debug" "^4.1.12" + bittorrent-tracker "^11.2.1" + debug "^4.4.0" + nano-md5 "^1.0.5" + +p2p-media-loader-hlsjs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p2p-media-loader-hlsjs/-/p2p-media-loader-hlsjs-2.1.1.tgz#a8b49a08dc0221ef21ed97b12c49eaaebb136af8" + integrity sha512-72/5bchePCaHin7/OB58mseCx598ysdHKOsKJow0yygX0YQ/t3oMTF/Cg1RyxpAgSmDvf32cGIAmYsIXGZRSXQ== + dependencies: + p2p-media-loader-core "2.1.1" + pac-proxy-agent@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz#da7c3b5c4cccc6655aaafb701ae140fb23f15df2" @@ -7620,7 +7483,7 @@ postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.4.32, postcss@^8.4.43, postcss@^8.4.49, postcss@^8.5.1: +postcss@^8.4.32, postcss@^8.4.49, postcss@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214" integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ== @@ -7812,6 +7675,11 @@ queue-microtask@^1.2.2, queue-microtask@^1.2.3: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -8119,7 +7987,7 @@ rollup@4.30.1: "@rollup/rollup-win32-x64-msvc" "4.30.1" fsevents "~2.3.2" -rollup@^4.20.0, rollup@^4.23.0: +rollup@^4.23.0: version "4.34.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.1.tgz#dcc318abee12e23dae4003af733c1987d7baca8e" integrity sha512-iYZ/+PcdLYSGfH3S+dGahlW/RWmsqDhLgj1BT9DH/xXJ0ggZN7xkdP9wipPNjjNLczI+fmMLmTB9pye+d2r4GQ== @@ -8171,7 +8039,7 @@ rust-result@^1.0.0: dependencies: individual "^2.0.0" -rxjs@7.8.1, rxjs@^7.3.0, rxjs@^7.8.1: +rxjs@7.8.1, rxjs@^7.3.0, rxjs@^7.4.0, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -8238,6 +8106,141 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sass-embedded-android-arm64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.83.4.tgz#60af9d787e74276af95e4a1a1507567435bc61d2" + integrity sha512-tgX4FzmbVqnQmD67ZxQDvI+qFNABrboOQgwsG05E5bA/US42zGajW9AxpECJYiMXVOHmg+d81ICbjb0fsVHskw== + +sass-embedded-android-arm@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm/-/sass-embedded-android-arm-1.83.4.tgz#960953d094bf28c3e10a2e0ebd14459d4ec6e2d2" + integrity sha512-9Z4pJAOgEkXa3VDY/o+U6l5XvV0mZTJcSl0l/mSPHihjAHSpLYnOW6+KOWeM8dxqrsqTYcd6COzhanI/a++5Gw== + +sass-embedded-android-ia32@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.83.4.tgz#2293cb9920181094edfa477ba503f1f187d21624" + integrity sha512-RsFOziFqPcfZXdFRULC4Ayzy9aK6R6FwQ411broCjlOBX+b0gurjRadkue3cfUEUR5mmy0KeCbp7zVKPLTK+5Q== + +sass-embedded-android-riscv64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.83.4.tgz#84f86f2e96955a415343a2f24bae1af7bde26e5f" + integrity sha512-EHwh0nmQarBBrMRU928eTZkFGx19k/XW2YwbPR4gBVdWLkbTgCA5aGe8hTE6/1zStyx++3nDGvTZ78+b/VvvLg== + +sass-embedded-android-x64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-android-x64/-/sass-embedded-android-x64-1.83.4.tgz#8db3bb08b941889918f8435a97487cd84e7fd748" + integrity sha512-0PgQNuPWYy1jEOEPDVsV89KfqOsMLIp9CSbjBY7jRcwRhyVAcigqrUG6bDeNtojHUYKA1kU+Eh/85WxOHUOgBw== + +sass-embedded-darwin-arm64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.83.4.tgz#d0f3d82eea999ab0ae7ec8abd7fa364f0defc75e" + integrity sha512-rp2ywymWc3nymnSnAFG5R/8hvxWCsuhK3wOnD10IDlmNB7o4rzKby1c+2ZfpQGowlYGWsWWTgz8FW2qzmZsQRw== + +sass-embedded-darwin-x64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.83.4.tgz#cd2ac7f209fe823a8a5fc1a064cdfe2833680034" + integrity sha512-kLkN2lXz9PCgGfDS8Ev5YVcl/V2173L6379en/CaFuJJi7WiyPgBymW7hOmfCt4uO4R1y7CP2Uc08DRtZsBlAA== + +sass-embedded-linux-arm64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.83.4.tgz#057adf6e337357787331d40714cb8bba4a96dafe" + integrity sha512-E0zjsZX2HgESwyqw31EHtI39DKa7RgK7nvIhIRco1d0QEw227WnoR9pjH3M/ZQy4gQj3GKilOFHM5Krs/omeIA== + +sass-embedded-linux-arm@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.83.4.tgz#aea8b56f3844633f0bfaf13e0694c79511218fc0" + integrity sha512-nL90ryxX2lNmFucr9jYUyHHx21AoAgdCL1O5Ltx2rKg2xTdytAGHYo2MT5S0LIeKLa/yKP/hjuSvrbICYNDvtA== + +sass-embedded-linux-ia32@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.83.4.tgz#2cedba9f41be61ded3cede5abd16f8ec163d7f46" + integrity sha512-ew5HpchSzgAYbQoriRh8QhlWn5Kw2nQ2jHoV9YLwGKe3fwwOWA0KDedssvDv7FWnY/FCqXyymhLd6Bxae4Xquw== + +sass-embedded-linux-musl-arm64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.83.4.tgz#1c5f50c9df93abce7d5ffb4d86eed65b8ffba2f4" + integrity sha512-IzMgalf6MZOxgp4AVCgsaWAFDP/IVWOrgVXxkyhw29fyAEoSWBJH4k87wyPhEtxSuzVHLxKNbc8k3UzdWmlBFg== + +sass-embedded-linux-musl-arm@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.83.4.tgz#00f241dbc750ee73242bfde1ec5d64ef2d5d7956" + integrity sha512-0RrJRwMrmm+gG0VOB5b5Cjs7Sd+lhqpQJa6EJNEaZHljJokEfpE5GejZsGMRMIQLxEvVphZnnxl6sonCGFE/QQ== + +sass-embedded-linux-musl-ia32@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.83.4.tgz#27537a309d39f8e35a7dba34a3edc29a3ee16adf" + integrity sha512-LLb4lYbcxPzX4UaJymYXC+WwokxUlfTJEFUv5VF0OTuSsHAGNRs/rslPtzVBTvMeG9TtlOQDhku1F7G6iaDotA== + +sass-embedded-linux-musl-riscv64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.83.4.tgz#a32edf2ddb7f7d9b526e971e80cadef1e025cce8" + integrity sha512-zoKlPzD5Z13HKin1UGR74QkEy+kZEk2AkGX5RelRG494mi+IWwRuWCppXIovor9+BQb9eDWPYPoMVahwN5F7VA== + +sass-embedded-linux-musl-x64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.83.4.tgz#668b90b80bf35830c2f1ea2a47557d5e60842598" + integrity sha512-hB8+/PYhfEf2zTIcidO5Bpof9trK6WJjZ4T8g2MrxQh8REVtdPcgIkoxczRynqybf9+fbqbUwzXtiUao2GV+vQ== + +sass-embedded-linux-riscv64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.83.4.tgz#b7718df2adf1cbcb4c26609215018dd2e8bab595" + integrity sha512-83fL4n+oeDJ0Y4KjASmZ9jHS1Vl9ESVQYHMhJE0i4xDi/P3BNarm2rsKljq/QtrwGpbqwn8ujzOu7DsNCMDSHA== + +sass-embedded-linux-x64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.83.4.tgz#52e61bd582dfc56b8f638f2b9cfdb8a53db1e57e" + integrity sha512-NlnGdvCmTD5PK+LKXlK3sAuxOgbRIEoZfnHvxd157imCm/s2SYF/R28D0DAAjEViyI8DovIWghgbcqwuertXsA== + +sass-embedded-win32-arm64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.83.4.tgz#b6ca8f65177e24770e87e43ffea5868fea34de27" + integrity sha512-J2BFKrEaeSrVazU2qTjyQdAk+MvbzJeTuCET0uAJEXSKtvQ3AzxvzndS7LqkDPbF32eXAHLw8GVpwcBwKbB3Uw== + +sass-embedded-win32-ia32@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.83.4.tgz#94f8da72e253532f8d857516b99e1caf61e7b08f" + integrity sha512-uPAe9T/5sANFhJS5dcfAOhOJy8/l2TRYG4r+UO3Wp4yhqbN7bggPvY9c7zMYS0OC8tU/bCvfYUDFHYMCl91FgA== + +sass-embedded-win32-x64@1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.83.4.tgz#2179d4e2fc2f9086aecd64209a2d84f7d8e9edbe" + integrity sha512-C9fkDY0jKITdJFij4UbfPFswxoXN9O/Dr79v17fJnstVwtUojzVJWKHUXvF0Zg2LIR7TCc4ju3adejKFxj7ueA== + +sass-embedded@^1.83.4: + version "1.83.4" + resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.83.4.tgz#9b05cdc22ae71a1b27b5996a39054ba59bebc04a" + integrity sha512-Hf2burRA/y5PGxsg6jB9UpoK/xZ6g/pgrkOcdl6j+rRg1Zj8XhGKZ1MTysZGtTPUUmiiErqzkP5+Kzp95yv9GQ== + dependencies: + "@bufbuild/protobuf" "^2.0.0" + buffer-builder "^0.2.0" + colorjs.io "^0.5.0" + immutable "^5.0.2" + rxjs "^7.4.0" + supports-color "^8.1.1" + sync-child-process "^1.0.2" + varint "^6.0.0" + optionalDependencies: + sass-embedded-android-arm "1.83.4" + sass-embedded-android-arm64 "1.83.4" + sass-embedded-android-ia32 "1.83.4" + sass-embedded-android-riscv64 "1.83.4" + sass-embedded-android-x64 "1.83.4" + sass-embedded-darwin-arm64 "1.83.4" + sass-embedded-darwin-x64 "1.83.4" + sass-embedded-linux-arm "1.83.4" + sass-embedded-linux-arm64 "1.83.4" + sass-embedded-linux-ia32 "1.83.4" + sass-embedded-linux-musl-arm "1.83.4" + sass-embedded-linux-musl-arm64 "1.83.4" + sass-embedded-linux-musl-ia32 "1.83.4" + sass-embedded-linux-musl-riscv64 "1.83.4" + sass-embedded-linux-musl-x64 "1.83.4" + sass-embedded-linux-riscv64 "1.83.4" + sass-embedded-linux-x64 "1.83.4" + sass-embedded-win32-arm64 "1.83.4" + sass-embedded-win32-ia32 "1.83.4" + sass-embedded-win32-x64 "1.83.4" + sass@1.83.1: version "1.83.1" resolved "https://registry.yarnpkg.com/sass/-/sass-1.83.1.tgz#dee1ab94b47a6f9993d3195d36f556bcbda64846" @@ -8415,19 +8418,6 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" -simple-peer@^9.11.1: - version "9.11.1" - resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.11.1.tgz#9814d5723f821b778b7fb011bdefcbd1e788e6cc" - integrity sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw== - dependencies: - buffer "^6.0.3" - debug "^4.3.2" - err-code "^3.0.1" - get-browser-rtc "^1.1.0" - queue-microtask "^1.2.3" - randombytes "^2.1.0" - readable-stream "^3.6.0" - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -8628,7 +8618,29 @@ stream-http@^3.2.0: readable-stream "^3.6.0" xtend "^4.0.2" -streamx@^2.15.0, streamx@^2.17.0, streamx@^2.20.1, streamx@^2.21.0: +streamx@^2.15.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.18.0.tgz#5bc1a51eb412a667ebfdcd4e6cf6a6fc65721ac7" + integrity sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ== + dependencies: + fast-fifo "^1.3.2" + queue-tick "^1.0.1" + text-decoder "^1.1.0" + optionalDependencies: + bare-events "^2.2.0" + +streamx@^2.17.0, streamx@^2.20.1: + version "2.20.2" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.20.2.tgz#6a8911959d6f307c19781a1d19ecd94b5f042d78" + integrity sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA== + dependencies: + fast-fifo "^1.3.2" + queue-tick "^1.0.1" + text-decoder "^1.1.0" + optionalDependencies: + bare-events "^2.2.0" + +streamx@^2.21.0: version "2.22.0" resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.22.0.tgz#cd7b5e57c95aaef0ff9b2aef7905afa62ec6e4a7" integrity sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw== @@ -8897,6 +8909,18 @@ symbol-observable@4.0.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== +sync-child-process@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/sync-child-process/-/sync-child-process-1.0.2.tgz#45e7c72e756d1243e80b547ea2e17957ab9e367f" + integrity sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA== + dependencies: + sync-message-port "^1.0.0" + +sync-message-port@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sync-message-port/-/sync-message-port-1.1.3.tgz#6055c565ee8c81d2f9ee5aae7db757e6d9088c0c" + integrity sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg== + synckit@^0.9.1: version "0.9.2" resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" @@ -9406,6 +9430,11 @@ validate-npm-package-name@^6.0.0: resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz#3add966c853cfe36e0e8e6a762edd72ae6f1d6ac" integrity sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg== +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + "video.js@^6 || ^7", video.js@^7.19.2: version "7.21.6" resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.21.6.tgz#a42d817c42d8d91538b72197a0874aeb01c76ce9" @@ -9437,10 +9466,10 @@ videojs-vtt.js@^0.15.5: dependencies: global "^4.3.1" -vite-plugin-checker@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/vite-plugin-checker/-/vite-plugin-checker-0.7.2.tgz#093ffdf9ccf51b2c9eab7101480bd0217ae99536" - integrity sha512-xeYeJbG0gaCaT0QcUC4B2Zo4y5NR8ZhYenc5gPbttrZvraRFwkEADCYwq+BfEHl9zYz7yf85TxsiGoYwyyIjhw== +vite-plugin-checker@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/vite-plugin-checker/-/vite-plugin-checker-0.8.0.tgz#33419857a623b35c9483e4f603d4ca8b6984acde" + integrity sha512-UA5uzOGm97UvZRTdZHiQVYFnd86AVn8EVaD4L3PoVzxH+IZSfaAw14WGFwX9QS23UW3lV/5bVKZn6l0w+q9P0g== dependencies: "@babel/code-frame" "^7.12.13" ansi-escapes "^4.3.0" @@ -9457,15 +9486,15 @@ vite-plugin-checker@^0.7.2: vscode-languageserver-textdocument "^1.0.1" vscode-uri "^3.0.2" -vite-plugin-node-polyfills@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.22.0.tgz#d0afcf82eb985fc02244620d7cec1ddd1c6e0864" - integrity sha512-F+G3LjiGbG8QpbH9bZ//GSBr9i1InSTkaulfUHFa9jkLqVGORFBoqc2A/Yu5Mmh1kNAbiAeKeK+6aaQUf3x0JA== +vite-plugin-node-polyfills@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.23.0.tgz#99d0d1524fa75ce5c7bb1fc8af30283379e9c684" + integrity sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w== dependencies: "@rollup/plugin-inject" "^5.0.5" node-stdlib-browser "^1.2.0" -vite@6.0.11: +vite@6.0.11, vite@^6.0.11: version "6.0.11" resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.11.tgz#224497e93e940b34c3357c9ebf2ec20803091ed8" integrity sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg== @@ -9476,17 +9505,6 @@ vite@6.0.11: optionalDependencies: fsevents "~2.3.3" -vite@^5.3.1: - version "5.4.14" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408" - integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA== - dependencies: - esbuild "^0.21.3" - postcss "^8.4.43" - rollup "^4.20.0" - optionalDependencies: - fsevents "~2.3.3" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" diff --git a/packages/node-utils/src/crypto.ts b/packages/node-utils/src/crypto.ts index 388d7557468..f4199f88416 100644 --- a/packages/node-utils/src/crypto.ts +++ b/packages/node-utils/src/crypto.ts @@ -7,3 +7,7 @@ export function sha256 (str: string | Buffer, encoding: BinaryToTextEncoding = ' export function sha1 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { return createHash('sha1').update(str).digest(encoding) } + +export function md5 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { + return createHash('md5').update(str).digest(encoding) +} diff --git a/scripts/build/client.sh b/scripts/build/client.sh index 357925e7f6a..41ab8b84769 100755 --- a/scripts/build/client.sh +++ b/scripts/build/client.sh @@ -47,9 +47,12 @@ languages=( ["kab"]="kab" ) -cd client -rm -rf ./dist +rm -rf ./client/dist + +npm run build:embed + +cd client # Don't build other languages if --light arg is provided if [ -z ${1+x} ] || ([ "$1" != "--light" ] && [ "$1" != "--analyze-bundle" ]); then @@ -88,7 +91,5 @@ else --configuration production --stats-json $additionalParams fi -cd ../ && npm run build:embed && cd client/ - # Copy runtime locales cp -r "./src/locale" "./dist/locale" diff --git a/scripts/build/embed.sh b/scripts/build/embed.sh index 70c5fc4cfc0..6c88f750515 100755 --- a/scripts/build/embed.sh +++ b/scripts/build/embed.sh @@ -2,4 +2,6 @@ set -eu +(cd client/src/standalone/player && npm run build) + cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs build --mode=production diff --git a/scripts/dev/client.sh b/scripts/dev/client.sh index 2f0b367d4bb..854bedec773 100755 --- a/scripts/dev/client.sh +++ b/scripts/dev/client.sh @@ -2,21 +2,27 @@ set -eu +(cd client/src/standalone/player && npm run build) + clientConfiguration="hmr" if [ ! -z ${2+x} ] && [ "$2" = "--ar-locale" ]; then clientConfiguration="ar-locale" fi +embedCommand="cd client/src/standalone/player && npm run dev" clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --port 3000" serverCommand="NODE_ENV=dev node dist/server" if [ ! -z ${1+x} ] && [ "$1" = "--skip-server" ]; then - eval $clientCommand + node node_modules/.bin/concurrently -k \ + "$embedCommand" \ + "$clientCommand" else npm run build:server node node_modules/.bin/concurrently -k \ + "$embedCommand" \ "$clientCommand" \ "$serverCommand" fi diff --git a/scripts/dev/embed.sh b/scripts/dev/embed.sh index 845036eff7a..b13db57aa75 100755 --- a/scripts/dev/embed.sh +++ b/scripts/dev/embed.sh @@ -3,7 +3,9 @@ set -eu npm run build:server -- --incremental +(cd client/src/standalone/player && npm run build) npm run concurrently -- -k \ + "cd client/src/standalone/player && npm run dev" \ "cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs dev" \ "NODE_ENV=dev npm start" diff --git a/server/core/controllers/tracker.ts b/server/core/controllers/tracker.ts index dbcc884d29a..9f137b67acd 100644 --- a/server/core/controllers/tracker.ts +++ b/server/core/controllers/tracker.ts @@ -25,11 +25,21 @@ const trackerServer = new TrackerServer({ http: false, udp: false, ws: false, - filter: async function (infoHash, params, cb) { + filter: async function (infoHashArg, params, cb) { if (CONFIG.TRACKER.ENABLED === false) { return cb(new Error('Tracker is disabled on this instance.')) } + let infoHash: string + + try { + infoHash = Buffer.from(infoHashArg, 'hex').toString('binary') + } catch (err) { + logger.error('Cannot parse infohash in tracker filter', { err }) + + return cb(new Error('Invalid infoHash.')) + } + let ip: string if (params.type === 'ws') { @@ -126,8 +136,7 @@ function createWebsocketTrackerServer (app: express.Application) { // --------------------------------------------------------------------------- export { - trackerRouter, - createWebsocketTrackerServer + createWebsocketTrackerServer, trackerRouter } // --------------------------------------------------------------------------- diff --git a/server/core/initializers/constants.ts b/server/core/initializers/constants.ts index 7436a74124f..829a9480f7c 100644 --- a/server/core/initializers/constants.ts +++ b/server/core/initializers/constants.ts @@ -423,7 +423,7 @@ export const CONSTRAINTS_FIELDS = { } }, EXTNAME: [] as string[], - INFO_HASH: { min: 40, max: 40 }, // Length, info hash is 20 bytes length but we represent it in hexadecimal so 20 * 2 + INFO_HASH: { min: 10, max: 100 }, DURATION: { min: 0 }, // Number TAGS: { min: 0, max: 5 }, // Number of total tags TAG: { min: 2, max: 30 }, // Length @@ -1112,7 +1112,9 @@ export const TRACKER_RATE_LIMITS = { BLOCK_IP_LIFETIME: parseDurationToMs('3 minutes') } -export const P2P_MEDIA_LOADER_PEER_VERSION = 2 +// We use -2 instead of 2 because of historical reason +// When p2p-media-loader bumps to v3, we'll be able to switch to it +export const P2P_MEDIA_LOADER_PEER_VERSION = -2 // --------------------------------------------------------------------------- diff --git a/server/core/lib/activitypub/videos/shared/object-to-model-attributes.ts b/server/core/lib/activitypub/videos/shared/object-to-model-attributes.ts index 7d6279b81b4..1e23216d07e 100644 --- a/server/core/lib/activitypub/videos/shared/object-to-model-attributes.ts +++ b/server/core/lib/activitypub/videos/shared/object-to-model-attributes.ts @@ -167,7 +167,7 @@ export function getStreamingPlaylistAttributesFromObject (video: MVideoId, video for (const playlistUrlObject of playlistUrls) { const segmentsSha256UrlObject = playlistUrlObject.tag.find(isAPPlaylistSegmentHashesUrlObject) - const files: unknown[] = playlistUrlObject.tag.filter(u => isAPVideoUrlObject(u)) + const files = playlistUrlObject.tag.filter(u => isAPVideoUrlObject(u)) const attribute = { type: VideoStreamingPlaylistType.HLS, diff --git a/server/core/lib/hls.ts b/server/core/lib/hls.ts index 87f503eeadf..7e3cb8b265b 100644 --- a/server/core/lib/hls.ts +++ b/server/core/lib/hls.ts @@ -24,18 +24,23 @@ import { VideoPathManager } from './video-path-manager.js' const lTags = loggerTagsFactory('hls') export async function updateStreamingPlaylistsInfohashesIfNeeded () { - const playlistsToUpdate = await VideoStreamingPlaylistModel.listByIncorrectPeerVersion() + const playlistsToUpdateIds = await VideoStreamingPlaylistModel.listByIncorrectPeerVersion() // Use separate SQL queries, because we could have many videos to update - for (const playlist of playlistsToUpdate) { - await sequelizeTypescript.transaction(async t => { - const videoFiles = await VideoFileModel.listByStreamingPlaylist(playlist.id, t) + for (const playlistId of playlistsToUpdateIds) { + try { + await sequelizeTypescript.transaction(async t => { + const playlist = await VideoStreamingPlaylistModel.loadWithVideo(playlistId, t) + const videoFiles = await VideoFileModel.listByStreamingPlaylist(playlistId, t) - playlist.assignP2PMediaLoaderInfoHashes(playlist.Video, videoFiles) - playlist.p2pMediaLoaderPeerVersion = P2P_MEDIA_LOADER_PEER_VERSION + playlist.assignP2PMediaLoaderInfoHashes(playlist.Video, videoFiles) + playlist.p2pMediaLoaderPeerVersion = P2P_MEDIA_LOADER_PEER_VERSION - await playlist.save({ transaction: t }) - }) + await playlist.save({ transaction: t }) + }) + } catch (err) { + logger.error(`Cannot update streaming playlist infohash of playlist id ${playlistId}`, { err }) + } } } diff --git a/server/core/lib/live/shared/muxing-session.ts b/server/core/lib/live/shared/muxing-session.ts index ca6743103de..45d37cf5f93 100644 --- a/server/core/lib/live/shared/muxing-session.ts +++ b/server/core/lib/live/shared/muxing-session.ts @@ -227,7 +227,7 @@ class MuxingSession extends EventEmitter { this.streamingPlaylist.playlistUrl = url } - this.streamingPlaylist.assignP2PMediaLoaderInfoHashes(this.videoLive.Video, this.allResolutions) + this.streamingPlaylist.assignP2PMediaLoaderInfoHashes(this.videoLive.Video, this.allResolutions.map(r => ({ height: r }))) await this.streamingPlaylist.save() } catch (err) { diff --git a/server/core/models/video/video-file.ts b/server/core/models/video/video-file.ts index 101fa0607de..8291975dce7 100644 --- a/server/core/models/video/video-file.ts +++ b/server/core/models/video/video-file.ts @@ -354,23 +354,17 @@ export class VideoFileModel extends SequelizeModel { const query = { include: [ { - model: VideoModel.unscoped(), + model: VideoStreamingPlaylistModel.unscoped(), required: true, - include: [ - { - model: VideoStreamingPlaylistModel.unscoped(), - required: true, - where: { - id: streamingPlaylistId - } - } - ] + where: { + id: streamingPlaylistId + } } ], transaction } - return VideoFileModel.findAll(query) + return VideoFileModel.findAll(query) } static getStats () { diff --git a/server/core/models/video/video-streaming-playlist.ts b/server/core/models/video/video-streaming-playlist.ts index 0f463969b4c..8742e57900b 100644 --- a/server/core/models/video/video-streaming-playlist.ts +++ b/server/core/models/video/video-streaming-playlist.ts @@ -5,7 +5,7 @@ import { type FileStorageType, type VideoStreamingPlaylistType_Type } from '@peertube/peertube-models' -import { sha1 } from '@peertube/peertube-node-utils' +import { md5 } from '@peertube/peertube-node-utils' import { logger } from '@server/helpers/logger.js' import { CONFIG } from '@server/initializers/config.js' import { getHLSPrivateFileUrl, getObjectStoragePublicFileUrl } from '@server/lib/object-storage/index.js' @@ -141,12 +141,21 @@ export class VideoStreamingPlaylistModel extends SequelizeModel btoa(md5(input, 'binary').slice(1)) + // https://github.com/Novage/p2p-media-loader/blob/master/p2p-media-loader-core/lib/p2p-media-manager.ts#L115 for (let i = 0; i < files.length; i++) { - hashes.push(sha1(`${P2P_MEDIA_LOADER_PEER_VERSION}${playlistUrl}+V${i}`)) + hashes.push(hash(`v${version}-${playlistUrl}-main-${i}`)) + } + + // Audio only stream + if (files.some(f => f.height === 0)) { + hashes.push(hash(`v${version}-${playlistUrl}-secondary-0`)) } logger.debug('Assigned P2P Media Loader info hashes', { playlistUrl, hashes }) @@ -154,22 +163,18 @@ export class VideoStreamingPlaylistModel extends SequelizeModel r.id) } static loadWithVideoAndFiles (id: number) { @@ -188,14 +193,15 @@ export class VideoStreamingPlaylistModel extends SequelizeModel(id, options) } - static loadWithVideo (id: number) { + static loadWithVideo (id: number, transaction?: Transaction) { const options = { include: [ { model: VideoModel.unscoped(), required: true } - ] + ], + transaction } return VideoStreamingPlaylistModel.findByPk(id, options) @@ -242,7 +248,7 @@ export class VideoStreamingPlaylistModel extends SequelizeModel