diff --git a/client/package.json b/client/package.json
index 04990d473..ca7236d66 100644
--- a/client/package.json
+++ b/client/package.json
@@ -67,7 +67,6 @@
"@types/qrcode": "^1.5.5",
"@types/sanitize-html": "2.11.0",
"@types/sha.js": "^2.4.0",
- "@types/video.js": "^7.3.40",
"@wdio/browserstack-service": "^9.12.7",
"@wdio/cli": "^9.12.7",
"@wdio/local-runner": "^9.12.7",
@@ -109,7 +108,7 @@
"type-fest": "^4.37.0",
"typescript": "~5.7.3",
"ua-parser-js": "^2.0.3",
- "video.js": "^7.19.2",
+ "video.js": "^8.23.4",
"vite": "^6.0.11",
"vite-plugin-checker": "^0.9.3",
"vite-plugin-node-polyfills": "^0.23.0",
diff --git a/client/src/app/+video-watch/video-watch.component.ts b/client/src/app/+video-watch/video-watch.component.ts
index b6ba33443..e5b34857d 100644
--- a/client/src/app/+video-watch/video-watch.component.ts
+++ b/client/src/app/+video-watch/video-watch.component.ts
@@ -52,7 +52,8 @@ import {
PeerTubePlayerConstructorOptions,
PeerTubePlayerLoadOptions,
PlayerMode,
- videojs
+ videojs,
+ VideojsPlayer
} from '@peertube/player'
import { logger } from '@root-helpers/logger'
import { isP2PEnabled, videoRequiresFileToken, videoRequiresUserAuth } from '@root-helpers/video'
@@ -885,7 +886,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
return loggedInOrAnonymousUser?.autoPlayNextVideo
},
- isSuspended: (player: videojs.Player) => {
+ isSuspended: (player: VideojsPlayer) => {
return !isXPercentInViewport(player.el() as HTMLElement, 80)
},
diff --git a/client/src/standalone/player/src/peertube-player.ts b/client/src/standalone/player/src/peertube-player.ts
index f3d38ab39..f43426513 100644
--- a/client/src/standalone/player/src/peertube-player.ts
+++ b/client/src/standalone/player/src/peertube-player.ts
@@ -5,7 +5,7 @@ import { TranslationsManager } from '@root-helpers/translations-manager'
import { copyToClipboard } from '@root-helpers/utils'
import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
import { isMobile } from '@root-helpers/web-browser'
-import videojs, { VideoJsPlayer } from 'video.js'
+import videojs from 'video.js'
import { saveAverageBandwidth } from './peertube-player-local-storage'
import './shared/bezels/bezels-plugin'
import './shared/context-menu'
@@ -20,12 +20,12 @@ import './shared/control-bar/theater-button'
import './shared/control-bar/time-tooltip'
import './shared/dock/peertube-dock-component'
import './shared/dock/peertube-dock-plugin'
-import './shared/nsfw/peertube-nsfw-info-component'
-import './shared/nsfw/peertube-nsfw-plugin'
import './shared/hotkeys/peertube-hotkeys-plugin'
import './shared/metrics/metrics-plugin'
import './shared/mobile/peertube-mobile-buttons'
import './shared/mobile/peertube-mobile-plugin'
+import './shared/nsfw/peertube-nsfw-info-component'
+import './shared/nsfw/peertube-nsfw-plugin'
import './shared/p2p-media-loader/hls-plugin'
import './shared/p2p-media-loader/p2p-media-loader-plugin'
import './shared/peertube/peertube-plugin'
@@ -45,7 +45,15 @@ import './shared/stats/stats-plugin'
import './shared/upnext/end-card'
import './shared/upnext/upnext-plugin'
import './shared/web-video/web-video-plugin'
-import { PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions, PlayerNetworkInfo, VideoJSPluginOptions } from './types'
+import {
+ PeerTubePlayerConstructorOptions,
+ PeerTubePlayerLoadOptions,
+ PlayerNetworkInfo,
+ VideojsAutoplay,
+ VideojsPlayer,
+ VideojsPlayerOptions,
+ VideoJSPluginOptions
+} from './types'
const CaptionsButton = videojs.getComponent('CaptionsButton') as any
// Change Captions to Subtitles/CC
@@ -70,7 +78,7 @@ export class PeerTubePlayer {
private videojsDecodeErrors = 0
- private player: VideoJsPlayer
+ private player: VideojsPlayer
private currentLoadOptions: PeerTubePlayerLoadOptions
@@ -210,7 +218,7 @@ export class PeerTubePlayer {
this.getVideojsOptions()
)
- this.player = videojs(this.options.playerElement(), videojsOptions)
+ this.player = videojs(this.options.playerElement(), videojsOptions) as VideojsPlayer
this.player.ready(() => {
if (!isNaN(+this.options.playbackRate)) {
@@ -233,7 +241,7 @@ export class PeerTubePlayer {
this.player.on('video-change', () => alreadyFallback = false)
this.player.on('error', () => handleError())
- this.player.on('network-info', (_, data: PlayerNetworkInfo) => {
+ this.player.on('network-info', (_: any, data: PlayerNetworkInfo) => {
if (data.source !== 'p2p-media-loader' || isNaN(data.bandwidthEstimate)) return
saveAverageBandwidth(data.bandwidthEstimate)
@@ -366,7 +374,7 @@ export class PeerTubePlayer {
})
}
- getVideojsOptions (): videojs.PlayerOptions {
+ getVideojsOptions (): VideojsPlayerOptions {
const html5 = {
preloadTextTracks: false,
// Prevent a bug on iOS where the text tracks added by peertube plugin are removed on play
@@ -422,7 +430,7 @@ export class PeerTubePlayer {
html5,
// We don't use text track settings for now
- textTrackSettings: false as any, // FIXME: typings
+ textTrackSettings: false,
controls: this.options.controls !== undefined ? this.options.controls : true,
loop: this.options.loop !== undefined ? this.options.loop : false,
@@ -441,18 +449,20 @@ export class PeerTubePlayer {
plugins,
controlBar: {
- children: controlBarOptionsBuilder.getChildrenOptions() as any // FIXME: typings
+ children: controlBarOptionsBuilder.getChildrenOptions()
},
language: this.options.language && !isDefaultLocale(this.options.language)
? this.options.language
- : undefined
- }
+ : undefined,
+
+ enableSmoothSeeking: true
+ } satisfies VideojsPlayerOptions
return videojsOptions
}
- private getAutoPlayValue (autoplay: boolean): videojs.Autoplay {
+ private getAutoPlayValue (autoplay: boolean): VideojsAutoplay {
if (autoplay !== true) return false
return this.currentLoadOptions.forceAutoplay
@@ -500,14 +510,14 @@ export class PeerTubePlayer {
const player = this.player
const shortUUID = self.currentLoadOptions.videoShortUUID
- const isLoopEnabled = player.options_['loop']
+ const isLoopEnabled = player.options_.loop
const items = [
{
icon: 'repeat',
label: player.localize('Play in loop') + (isLoopEnabled ? '' : ''),
listener: function () {
- player.options_['loop'] = !isLoopEnabled
+ player.options_.loop = !isLoopEnabled
}
},
{
diff --git a/client/src/standalone/player/src/sass/shared/context-menu.scss b/client/src/standalone/player/src/sass/shared/context-menu.scss
index 21dd487df..d65568ac8 100644
--- a/client/src/standalone/player/src/sass/shared/context-menu.scss
+++ b/client/src/standalone/player/src/sass/shared/context-menu.scss
@@ -25,8 +25,8 @@ $context-menu-width: 350px;
cursor: pointer;
font-size: 1em;
padding: 8px 16px;
- text-align: start;
text-transform: none;
+ justify-content: flex-start;
&:hover {
background-color: rgba(255, 255, 255, 0.2);
diff --git a/client/src/standalone/player/src/sass/shared/settings-menu.scss b/client/src/standalone/player/src/sass/shared/settings-menu.scss
index a808cce16..9beeb66d6 100644
--- a/client/src/standalone/player/src/sass/shared/settings-menu.scss
+++ b/client/src/standalone/player/src/sass/shared/settings-menu.scss
@@ -40,7 +40,6 @@ $setting-transition-easing: ease-out;
}
.vjs-settings-sub-menu-title {
- text-align: start;
font-weight: $font-semibold;
}
@@ -118,16 +117,19 @@ $setting-transition-easing: ease-out;
.vjs-menu-item {
outline: 0;
font-weight: $font-semibold;
- text-align: end;
+ justify-content: flex-end;
padding: 8px 15px;
&.vjs-back-button {
padding: 12px 15px;
margin-bottom: 5px;
border-bottom: 1px solid #808080;
- text-align: start;
+ justify-content: flex-start;
+ align-items: center;
&::before {
+ top: -1px;
+
@include chevron-left(9px, 2px);
@include margin-right(10px);
}
diff --git a/client/src/standalone/player/src/shared/bezels/bezels-plugin.ts b/client/src/standalone/player/src/shared/bezels/bezels-plugin.ts
index cf07dbd2c..0de47c53c 100644
--- a/client/src/standalone/player/src/shared/bezels/bezels-plugin.ts
+++ b/client/src/standalone/player/src/shared/bezels/bezels-plugin.ts
@@ -1,11 +1,11 @@
import videojs from 'video.js'
+import type { VideojsComponentOptions, VideojsPlayer, VideojsPlugin } from '../../types/peertube-videojs-typings'
import { PauseBezel } from './pause-bezel'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class BezelsPlugin extends Plugin {
-
- constructor (player: videojs.Player, options?: videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: VideojsComponentOptions) {
super(player)
this.player.ready(() => {
diff --git a/client/src/standalone/player/src/shared/bezels/pause-bezel.ts b/client/src/standalone/player/src/shared/bezels/pause-bezel.ts
index d7515e3cc..c921ead4d 100644
--- a/client/src/standalone/player/src/shared/bezels/pause-bezel.ts
+++ b/client/src/standalone/player/src/shared/bezels/pause-bezel.ts
@@ -1,5 +1,6 @@
-import videojs from 'video.js'
import { isMobile } from '@root-helpers/web-browser'
+import videojs from 'video.js'
+import { VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
function getPauseBezel () {
return `
@@ -31,7 +32,8 @@ function getPlayBezel () {
`
}
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
+
export class PauseBezel extends Component {
declare container: HTMLDivElement
@@ -42,7 +44,7 @@ export class PauseBezel extends Component {
declare private playerPlayHandler: () => void
declare private videoChangeHandler: () => void
- constructor (player: videojs.Player, options?: videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: VideojsComponentOptions) {
super(player, options)
// Hide bezels on mobile since we already have our mobile overlay
diff --git a/client/src/standalone/player/src/shared/context-menu/context-menu-item.ts b/client/src/standalone/player/src/shared/context-menu/context-menu-item.ts
index 65f728c46..8d6949419 100644
--- a/client/src/standalone/player/src/shared/context-menu/context-menu-item.ts
+++ b/client/src/standalone/player/src/shared/context-menu/context-menu-item.ts
@@ -1,17 +1,17 @@
import videojs from 'video.js'
-import { ContextMenuItemOptions } from '../../types'
+import { ContextMenuItemOptions, VideojsComponentOptions, VideojsMenuItem, VideojsPlayer } from '../../types'
-const MenuItem = videojs.getComponent('MenuItem')
+const MenuItem = videojs.getComponent('MenuItem') as typeof VideojsMenuItem
class ContextMenuItem extends MenuItem {
declare options_: ContextMenuItemOptions
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
- constructor (player: videojs.Player, options: ContextMenuItemOptions) {
+ constructor (player: VideojsPlayer, options: VideojsComponentOptions & ContextMenuItemOptions) {
super(player, options)
}
- handleClick (e: videojs.EventTarget.Event) {
+ handleClick (e: Event) {
super.handleClick(e)
this.options_.listener(e)
diff --git a/client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts b/client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts
index ee0732072..379a48c67 100644
--- a/client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts
+++ b/client/src/standalone/player/src/shared/context-menu/context-menu-plugin.ts
@@ -1,18 +1,18 @@
-import videojs, { VideoJsPlayer } from 'video.js'
-import { ContextMenuPluginOptions } from '../../types'
+import videojs from 'video.js'
+import { ContextMenuPluginOptions, VideojsMenuItemOptions, VideojsPlayer, VideojsPlugin } from '../../types'
import { ContextMenu } from './context-menu'
import { getPointerPosition } from './util'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class ContextMenuPlugin extends Plugin {
- declare options_: ContextMenuPluginOptions & videojs.MenuOptions
+ declare options_: ContextMenuPluginOptions & VideojsMenuItemOptions
declare menu: ContextMenu
declare private onContextMenuBind: (e: TouchEvent & MouseEvent) => void
- constructor (player: videojs.Player, options: ContextMenuPluginOptions & videojs.MenuOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: ContextMenuPluginOptions & VideojsMenuItemOptions) {
+ super(player)
this.options_ = options
@@ -96,7 +96,7 @@ export { ContextMenuPlugin }
// Private
// ---------------------------------------------------------------------------
-function hasMenu (player: VideoJsPlayer) {
+function hasMenu (player: VideojsPlayer) {
if (!player.usingPlugin('contextMenu')) return false
return !!player.contextMenu().menu?.el()
diff --git a/client/src/standalone/player/src/shared/context-menu/context-menu.ts b/client/src/standalone/player/src/shared/context-menu/context-menu.ts
index 908ebbfd1..4446fa00c 100644
--- a/client/src/standalone/player/src/shared/context-menu/context-menu.ts
+++ b/client/src/standalone/player/src/shared/context-menu/context-menu.ts
@@ -1,33 +1,32 @@
import videojs from 'video.js'
+import { ContextMenuPluginOptions, VideojsMenu, VideojsMenuOptions, VideojsPlayer } from '../../types'
import { ContextMenuItem } from './context-menu-item'
-import { ContextMenuPluginOptions } from '../../types'
-const Menu = videojs.getComponent('Menu')
+const Menu = videojs.getComponent('Menu') as typeof VideojsMenu
type ContextMenuOptions = ContextMenuPluginOptions & { position: { left: number, top: number } }
class ContextMenu extends Menu {
- declare options_: ContextMenuOptions & videojs.MenuOptions
+ declare options_: ContextMenuOptions & VideojsMenuOptions
- constructor (player: videojs.Player, options: ContextMenuOptions) {
+ constructor (player: VideojsPlayer, options: ContextMenuOptions) {
super(player, { ...options, menuButton: undefined })
- // Each menu component has its own `dispose` method that can be
- // safely bound and unbound to events while maintaining its context.
- this.dispose = videojs.bind(this, this.dispose)
+ // TODO: explain why we need this (I don't understand it)
+ this.dispose = this.dispose.bind(this)
for (const c of options.content()) {
this.addItem(
new ContextMenuItem(player, {
label: c.label,
- listener: videojs.bind(player, c.listener)
+ listener: c.listener.bind(player)
})
)
}
}
createEl () {
- const el = super.createEl()
+ const el = super.createEl() as HTMLElement
videojs.dom.addClass(el, 'vjs-contextmenu-ui-menu')
el.style.left = this.options_.position.left + 'px'
diff --git a/client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts b/client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts
index 0dbe5c610..58ba07986 100644
--- a/client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts
+++ b/client/src/standalone/player/src/shared/control-bar/caption-toggle-button.ts
@@ -1,11 +1,11 @@
import videojs from 'video.js'
-import { TheaterButtonOptions } from '../../types'
import { getStoredPreferredSubtitle } from '../../peertube-player-local-storage'
+import { TheaterButtonOptions, VideojsButton, VideojsButtonOptions, VideojsPlayer } from '../../types'
+
+const Button = videojs.getComponent('Button') as typeof VideojsButton
-const Button = videojs.getComponent('Button')
class CaptionToggleButton extends Button {
-
- constructor (player: videojs.Player, options: TheaterButtonOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options: TheaterButtonOptions & VideojsButtonOptions) {
super(player, options)
player.on('texttrackchange', () => this.update())
diff --git a/client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts b/client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts
index d25e60264..1768bedd1 100644
--- a/client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts
+++ b/client/src/standalone/player/src/shared/control-bar/chapters-plugin.ts
@@ -1,9 +1,9 @@
import { VideoChapter } from '@peertube/peertube-models'
import videojs from 'video.js'
-import { ChaptersOptions } from '../../types'
+import { ChaptersOptions, VideojsPlayer, VideojsPlugin } from '../../types'
import { ProgressBarMarkerComponent } from './progress-bar-marker-component'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class ChaptersPlugin extends Plugin {
declare private chapters: VideoChapter[]
@@ -11,8 +11,8 @@ class ChaptersPlugin extends Plugin {
private activeChapter: VideoChapter
- constructor (player: videojs.Player, options: videojs.ComponentOptions & ChaptersOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: ChaptersOptions) {
+ super(player)
this.markers = []
this.chapters = options.chapters
@@ -25,8 +25,13 @@ class ChaptersPlugin extends Plugin {
const marker = new ProgressBarMarkerComponent(player, { timecode: chapter.timecode })
- marker.on('mouseenter', () => this.activeChapter = chapter)
- marker.on('mouseleave', () => this.activeChapter = undefined)
+ marker.on('mouseenter', () => {
+ this.activeChapter = chapter
+ })
+
+ marker.on('mouseleave', () => {
+ this.activeChapter = undefined
+ })
this.markers.push(marker)
this.getSeekBar().addChild(marker)
diff --git a/client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts b/client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts
index f2ff962fd..61eafaef5 100644
--- a/client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts
+++ b/client/src/standalone/player/src/shared/control-bar/next-previous-video-button.ts
@@ -1,12 +1,12 @@
import videojs from 'video.js'
-import { NextPreviousVideoButtonOptions } from '../../types'
+import { NextPreviousVideoButtonOptions, VideojsButton, VideojsButtonOptions, VideojsPlayer } from '../../types'
-const Button = videojs.getComponent('Button')
+const Button = videojs.getComponent('Button') as typeof VideojsButton
class NextPreviousVideoButton extends Button {
- declare options_: NextPreviousVideoButtonOptions & videojs.ComponentOptions
+ declare options_: NextPreviousVideoButtonOptions & VideojsButtonOptions
- constructor (player: videojs.Player, options?: NextPreviousVideoButtonOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: NextPreviousVideoButtonOptions & VideojsButtonOptions) {
super(player, options)
this.player().on('video-change', () => {
diff --git a/client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts b/client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts
index e521b8fea..3ddab6fbd 100644
--- a/client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts
+++ b/client/src/standalone/player/src/shared/control-bar/p2p-info-button.ts
@@ -1,8 +1,9 @@
import videojs from 'video.js'
-import { PlayerNetworkInfo } from '../../types'
+import { PlayerNetworkInfo, VideojsButton } from '../../types'
import { bytes } from '../common'
-const Button = videojs.getComponent('Button')
+const Button = videojs.getComponent('Button') as typeof VideojsButton
+
class P2PInfoButton extends Button {
createEl () {
const div = videojs.dom.createEl('div', { className: 'vjs-peertube' })
@@ -87,7 +88,7 @@ class P2PInfoButton extends Button {
subDivP2P.className = 'vjs-peertube-displayed'
})
- this.player_.on('network-info', (_event, data: PlayerNetworkInfo) => {
+ this.player_.on('network-info', (_event: any, data: PlayerNetworkInfo) => {
if (data.p2p) return
if (data.source === 'web-video') subDivHttpText.textContent = 'HTTP'
diff --git a/client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts b/client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts
index f61945981..7e4079af9 100644
--- a/client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts
+++ b/client/src/standalone/player/src/shared/control-bar/peertube-link-button.ts
@@ -1,16 +1,16 @@
-import videojs from 'video.js'
import { buildVideoLink, decorateVideoLink } from '@peertube/peertube-core-utils'
-import { PeerTubeLinkButtonOptions } from '../../types'
+import videojs from 'video.js'
+import { PeerTubeLinkButtonOptions, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class PeerTubeLinkButton extends Component {
declare private mouseEnterHandler: () => void
declare private clickHandler: () => void
- declare options_: PeerTubeLinkButtonOptions & videojs.ComponentOptions
+ declare options_: PeerTubeLinkButtonOptions & VideojsComponentOptions
- constructor (player: videojs.Player, options?: PeerTubeLinkButtonOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: PeerTubeLinkButtonOptions & VideojsComponentOptions) {
super(player, options)
this.updateShowing()
diff --git a/client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts b/client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts
index ed77528e1..adb15dd26 100644
--- a/client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts
+++ b/client/src/standalone/player/src/shared/control-bar/peertube-live-display.ts
@@ -1,15 +1,15 @@
import videojs from 'video.js'
-import { PeerTubeLinkButtonOptions } from '../../types'
+import { PeerTubeLinkButtonOptions, VideojsClickableComponent, VideojsClickableComponentOptions, VideojsPlayer } from '../../types'
-const ClickableComponent = videojs.getComponent('ClickableComponent')
+const ClickableComponent = videojs.getComponent('ClickableComponent') as typeof VideojsClickableComponent
class PeerTubeLiveDisplay extends ClickableComponent {
declare private interval: any
- declare private contentEl_: any
+ declare private contentEl_: HTMLElement
- constructor (player: videojs.Player, options?: PeerTubeLinkButtonOptions) {
- super(player, options as any)
+ constructor (player: VideojsPlayer, options?: VideojsClickableComponentOptions & PeerTubeLinkButtonOptions) {
+ super(player, options)
this.interval = this.setInterval(() => this.updateClass(), 1000)
@@ -36,7 +36,7 @@ class PeerTubeLiveDisplay extends ClickableComponent {
className: 'vjs-live-display'
}, {
'aria-live': 'off'
- })
+ }) as HTMLElement
this.contentEl_.appendChild(videojs.dom.createEl('span', {
className: 'vjs-control-text',
diff --git a/client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts b/client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts
index 6476f087a..54dfd96cf 100644
--- a/client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts
+++ b/client/src/standalone/player/src/shared/control-bar/progress-bar-marker-component.ts
@@ -1,12 +1,12 @@
import videojs from 'video.js'
-import { ProgressBarMarkerComponentOptions } from '../../types'
+import { ProgressBarMarkerComponentOptions, VideojsClickableComponent, VideojsClickableComponentOptions, VideojsPlayer } from '../../types'
-const ClickableComponent = videojs.getComponent('ClickableComponent')
+const ClickableComponent = videojs.getComponent('ClickableComponent') as typeof VideojsClickableComponent
export class ProgressBarMarkerComponent extends ClickableComponent {
- declare options_: ProgressBarMarkerComponentOptions & videojs.ComponentOptions
+ declare options_: ProgressBarMarkerComponentOptions & VideojsClickableComponentOptions
- constructor (player: videojs.Player, options?: ProgressBarMarkerComponentOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: ProgressBarMarkerComponentOptions & VideojsClickableComponentOptions) {
super(player, options)
const updateMarker = () => {
diff --git a/client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts b/client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts
index 914e5c164..d5e652751 100644
--- a/client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts
+++ b/client/src/standalone/player/src/shared/control-bar/storyboard-plugin.ts
@@ -1,10 +1,11 @@
import videojs from 'video.js'
-import { StoryboardOptions } from '../../types'
+import { StoryboardOptions, VideojsPlayer, VideojsPlugin } from '../../types'
+import Tech from 'video.js/dist/types/tech/tech'
// Big thanks to this beautiful plugin: https://github.com/phloxic/videojs-sprite-thumbnails
// Adapted to respect peertube player style
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class StoryboardPlugin extends Plugin {
declare private url: string
@@ -14,9 +15,9 @@ class StoryboardPlugin extends Plugin {
declare private cached: boolean
- declare private mouseTimeTooltip: videojs.MouseTimeDisplay
- declare private seekBar: { el(): HTMLElement, mouseTimeDisplay: any, playProgressBar: any }
- declare private progress: any
+ declare private mouseTimeTooltip: VideojsPlayer['controlBar']['progressControl']['seekBar']['mouseTimeDisplay']['timeTooltip']
+ declare private seekBar: VideojsPlayer['controlBar']['progressControl']['seekBar']
+ declare private progress: VideojsPlayer['controlBar']['progressControl']
declare private spritePlaceholder: HTMLElement
@@ -26,8 +27,8 @@ class StoryboardPlugin extends Plugin {
declare private onReadyOrLoadstartHandler: (event: { type: 'ready' }) => void
- constructor (player: videojs.Player, options: videojs.ComponentOptions & StoryboardOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: StoryboardOptions) {
+ super(player)
this.url = options.url
this.height = options.height
@@ -46,7 +47,7 @@ class StoryboardPlugin extends Plugin {
}
init () {
- const controls = this.player.controlBar as any
+ const controls = this.player.controlBar
// default control bar component tree is expected
// https://docs.videojs.com/tutorial-components.html#default-component-tree
@@ -60,7 +61,8 @@ class StoryboardPlugin extends Plugin {
this.onReadyOrLoadstartHandler = event => {
if (event.type !== 'ready') {
- const spriteSource = this.player.currentSources().find(source => {
+ // FIXME: typings
+ const spriteSource = (this.player.currentSources() as unknown as Tech[]).find(source => {
return Object.prototype.hasOwnProperty.call(source, 'storyboard')
}) as any
const spriteOpts = spriteSource?.['storyboard'] as StoryboardOptions
@@ -97,7 +99,7 @@ class StoryboardPlugin extends Plugin {
if (!this.cached) {
this.sprites[this.url] = videojs.dom.createEl('img', {
src: this.url
- })
+ }) as HTMLImageElement
}
this.progress.on(spriteEvents, this.boundedHijackMouseTooltip)
} else {
diff --git a/client/src/standalone/player/src/shared/control-bar/theater-button.ts b/client/src/standalone/player/src/shared/control-bar/theater-button.ts
index d721605dc..78ea1d744 100644
--- a/client/src/standalone/player/src/shared/control-bar/theater-button.ts
+++ b/client/src/standalone/player/src/shared/control-bar/theater-button.ts
@@ -1,15 +1,15 @@
import videojs from 'video.js'
import { getStoredTheater, saveTheaterInStore } from '../../peertube-player-local-storage'
-import { TheaterButtonOptions } from '../../types'
+import { TheaterButtonOptions, VideojsButton, VideojsButtonOptions, VideojsPlayer } from '../../types'
+
+const Button = videojs.getComponent('Button') as typeof VideojsButton
-const Button = videojs.getComponent('Button')
class TheaterButton extends Button {
-
private static readonly THEATER_MODE_CLASS = 'vjs-theater-enabled'
declare private theaterButtonOptions: TheaterButtonOptions
- constructor (player: videojs.Player, options: TheaterButtonOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options: TheaterButtonOptions & VideojsButtonOptions) {
super(player, options)
this.theaterButtonOptions = options
diff --git a/client/src/standalone/player/src/shared/control-bar/time-tooltip.ts b/client/src/standalone/player/src/shared/control-bar/time-tooltip.ts
index 4c0dd0e99..8a11d1db6 100644
--- a/client/src/standalone/player/src/shared/control-bar/time-tooltip.ts
+++ b/client/src/standalone/player/src/shared/control-bar/time-tooltip.ts
@@ -1,13 +1,14 @@
import { timeToInt } from '@peertube/peertube-core-utils'
-import videojs, { VideoJsPlayer } from 'video.js'
+import videojs from 'video.js'
+import { VideojsTimeTooltip } from '../../types'
-const TimeToolTip = videojs.getComponent('TimeTooltip') as any // FIXME: typings don't have write method
+const TimeToolTip = videojs.getComponent('TimeTooltip') as typeof VideojsTimeTooltip
class TimeTooltip extends TimeToolTip {
declare private currentTimecode: string
write (timecode: string) {
- const player: VideoJsPlayer = this.player()
+ const player = this.player()
if (player.usingPlugin('chapters')) {
if (timecode === this.currentTimecode) return
diff --git a/client/src/standalone/player/src/shared/dock/peertube-dock-component.ts b/client/src/standalone/player/src/shared/dock/peertube-dock-component.ts
index ad5a62bb1..bd2ed0477 100644
--- a/client/src/standalone/player/src/shared/dock/peertube-dock-component.ts
+++ b/client/src/standalone/player/src/shared/dock/peertube-dock-component.ts
@@ -1,6 +1,7 @@
import videojs from 'video.js'
+import { VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
export type PeerTubeDockComponentOptions = {
title?: string
@@ -9,10 +10,10 @@ export type PeerTubeDockComponentOptions = {
}
class PeerTubeDockComponent extends Component {
- declare options_: videojs.ComponentOptions & PeerTubeDockComponentOptions
+ declare options_: VideojsComponentOptions & PeerTubeDockComponentOptions
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
- constructor (player: videojs.Player, options: videojs.ComponentOptions & PeerTubeDockComponentOptions) {
+ constructor (player: VideojsPlayer, options: VideojsComponentOptions & PeerTubeDockComponentOptions) {
super(player, options)
}
diff --git a/client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts b/client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts
index 4ff9873fa..4abd2a7a9 100644
--- a/client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts
+++ b/client/src/standalone/player/src/shared/dock/peertube-dock-plugin.ts
@@ -1,7 +1,8 @@
import videojs from 'video.js'
+import { VideojsPlayer, VideojsPlugin } from '../../types'
import { PeerTubeDockComponent } from './peertube-dock-component'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
export type PeerTubeDockPluginOptions = {
title?: string
@@ -12,8 +13,8 @@ export type PeerTubeDockPluginOptions = {
class PeerTubeDockPlugin extends Plugin {
declare private dockComponent: PeerTubeDockComponent
- constructor (player: videojs.Player, options: videojs.PlayerOptions & PeerTubeDockPluginOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: PeerTubeDockPluginOptions) {
+ super(player)
player.ready(() => {
player.addClass('peertube-dock')
diff --git a/client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts b/client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts
index d1bcf2810..3d91efcb6 100644
--- a/client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts
+++ b/client/src/standalone/player/src/shared/hotkeys/peertube-hotkeys-plugin.ts
@@ -1,8 +1,9 @@
import videojs from 'video.js'
+import { VideojsPlayer, VideojsPlugin } from '../../types'
type KeyHandler = { accept: (event: KeyboardEvent) => boolean, cb: (e: KeyboardEvent) => void }
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
export type HotkeysOptions = {
isLive: boolean
@@ -18,8 +19,8 @@ class PeerTubeHotkeysPlugin extends Plugin {
declare private readonly isLive: boolean
- constructor (player: videojs.Player, options: videojs.PlayerOptions & HotkeysOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: HotkeysOptions) {
+ super(player)
this.isLive = options.isLive
diff --git a/client/src/standalone/player/src/shared/metrics/metrics-plugin.ts b/client/src/standalone/player/src/shared/metrics/metrics-plugin.ts
index b90db9097..b60bf780c 100644
--- a/client/src/standalone/player/src/shared/metrics/metrics-plugin.ts
+++ b/client/src/standalone/player/src/shared/metrics/metrics-plugin.ts
@@ -1,12 +1,12 @@
-import debug from 'debug'
-import videojs from 'video.js'
import { PlaybackMetricCreate, VideoResolutionType } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
-import { MetricsPluginOptions, PlayerNetworkInfo } from '../../types'
+import debug from 'debug'
+import videojs from 'video.js'
+import { MetricsPluginOptions, PlayerNetworkInfo, VideojsPlayer, VideojsPlugin } from '../../types'
const debugLogger = debug('peertube:player:metrics')
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class MetricsPlugin extends Plugin {
declare options_: MetricsPluginOptions
@@ -27,7 +27,7 @@ class MetricsPlugin extends Plugin {
declare private metricsInterval: any
- constructor (player: videojs.Player, options: MetricsPluginOptions) {
+ constructor (player: VideojsPlayer, options: MetricsPluginOptions) {
super(player)
this.options_ = options
@@ -154,7 +154,7 @@ class MetricsPlugin extends Plugin {
}
private trackBytes () {
- this.player.on('network-info', (_event, data: PlayerNetworkInfo) => {
+ this.player.on('network-info', (_event: any, data: PlayerNetworkInfo) => {
this.downloadedBytesHTTP += Math.max(Math.round(data.http.downloaded - (this.lastPlayerNetworkInfo?.http.downloaded || 0)), 0)
this.downloadedBytesP2P += Math.max(Math.round((data.p2p?.downloaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.downloaded || 0)), 0)
diff --git a/client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts b/client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts
index 43316b9ad..0801967d3 100644
--- a/client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts
+++ b/client/src/standalone/player/src/shared/mobile/peertube-mobile-buttons.ts
@@ -1,6 +1,8 @@
import videojs from 'video.js'
+import { VideojsComponent } from '../../types'
+
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
-const Component = videojs.getComponent('Component')
class PeerTubeMobileButtons extends Component {
declare private mainButton: HTMLDivElement
diff --git a/client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts b/client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts
index 008eab112..770cf55ef 100644
--- a/client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts
+++ b/client/src/standalone/player/src/shared/mobile/peertube-mobile-plugin.ts
@@ -1,11 +1,14 @@
+import { logger } from '@root-helpers/logger'
import debug from 'debug'
import videojs from 'video.js'
-import { logger } from '@root-helpers/logger'
+import { VideojsPlayer, VideojsPlugin } from '../../types'
import { PeerTubeMobileButtons } from './peertube-mobile-buttons'
const debugLogger = debug('peertube:player:mobile')
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
+
+type SeekBar = VideojsPlayer['controlBar']['progressControl']['seekBar']
class PeerTubeMobilePlugin extends Plugin {
private static readonly DOUBLE_TAP_DELAY_MS = 250
@@ -29,10 +32,10 @@ class PeerTubeMobilePlugin extends Plugin {
declare private sliderActiveHandler: () => void
declare private sliderInactiveHandler: () => void
- declare private seekBar: videojs.Component
+ declare private seekBar: SeekBar
- constructor (player: videojs.Player, options: videojs.PlayerOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer) {
+ super(player)
this.seekAmount = 0
@@ -45,16 +48,14 @@ class PeerTubeMobilePlugin extends Plugin {
this.peerTubeMobileButtons = player.addChild('PeerTubeMobileButtons', { reportTouchActivity: false }) as PeerTubeMobileButtons
- if (!this.player.options_.userActions) this.player.options_.userActions = {};
-
- // FIXME: typings
- (this.player.options_.userActions as any).click = false
+ if (!this.player.options_.userActions) this.player.options_.userActions = {}
+ this.player.options_.userActions.click = false
this.player.options_.userActions.doubleClick = false
this.onPlayHandler = () => this.initTouchStartEvents()
this.player.one('play', this.onPlayHandler)
- this.seekBar = this.player.getDescendant([ 'controlBar', 'progressControl', 'seekBar' ])
+ this.seekBar = this.player.getDescendant([ 'controlBar', 'progressControl', 'seekBar' ]) as SeekBar
this.sliderActiveHandler = () => this.player.addClass('vjs-mobile-sliding')
this.sliderInactiveHandler = () => this.player.removeClass('vjs-mobile-sliding')
@@ -76,10 +77,9 @@ class PeerTubeMobilePlugin extends Plugin {
private handleFullscreenRotation () {
this.onFullScreenChangeHandler = () => {
- if (!this.player.isFullscreen() || this.isPortraitVideo()) return;
-
// https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1615
- (screen.orientation as any).lock('landscape')
+ if (!this.player.isFullscreen() || this.isPortraitVideo()) return
+ ;(screen.orientation as any).lock('landscape')
.catch((err: Error) => logger.error('Cannot lock screen to landscape.', err))
}
@@ -151,7 +151,7 @@ class PeerTubeMobilePlugin extends Plugin {
private onDoubleTap (event: TouchEvent) {
const playerWidth = this.player.currentWidth()
- const rect = this.findPlayerTarget((event.target as HTMLElement)).getBoundingClientRect()
+ const rect = this.findPlayerTarget(event.target as HTMLElement).getBoundingClientRect()
const offsetX = event.targetTouches[0].pageX - rect.left
debugLogger('Calculating double tap zone (player width: %d, offset X: %d)', playerWidth, offsetX)
diff --git a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-details-component.ts b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-details-component.ts
index 03dbc4bf0..6dd79a74a 100644
--- a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-details-component.ts
+++ b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-details-component.ts
@@ -1,14 +1,15 @@
import { NSFWFlag } from '@peertube/peertube-models'
import videojs from 'video.js'
+import { VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
import { type PeerTubeNSFWPluginOptions } from './peertube-nsfw-plugin'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class PeerTubeNSFWDetailsComponent extends Component {
- declare options_: videojs.ComponentOptions & PeerTubeNSFWPluginOptions
+ declare options_: VideojsComponentOptions & PeerTubeNSFWPluginOptions
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
- constructor (player: videojs.Player, options: videojs.ComponentOptions & PeerTubeNSFWPluginOptions) {
+ constructor (player: VideojsPlayer, options: VideojsComponentOptions & PeerTubeNSFWPluginOptions) {
super(player, options)
}
diff --git a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-info-component.ts b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-info-component.ts
index d5a134eca..55f32992b 100644
--- a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-info-component.ts
+++ b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-info-component.ts
@@ -1,13 +1,14 @@
import videojs from 'video.js'
+import { VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
import { type PeerTubeNSFWPluginOptions } from './peertube-nsfw-plugin'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class PeerTubeNSFWInfoComponent extends Component {
- declare options_: videojs.ComponentOptions & PeerTubeNSFWPluginOptions
+ declare options_: VideojsComponentOptions & PeerTubeNSFWPluginOptions
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
- constructor (player: videojs.Player, options: videojs.ComponentOptions & PeerTubeNSFWPluginOptions) {
+ constructor (player: VideojsPlayer, options: VideojsComponentOptions & PeerTubeNSFWPluginOptions) {
super(player, options)
}
diff --git a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-plugin.ts b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-plugin.ts
index d4d97e405..5102bc333 100644
--- a/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-plugin.ts
+++ b/client/src/standalone/player/src/shared/nsfw/peertube-nsfw-plugin.ts
@@ -1,8 +1,9 @@
import videojs from 'video.js'
-import { PeerTubeNSFWInfoComponent } from './peertube-nsfw-info-component'
+import { VideojsPlayer, VideojsPlugin } from '../../types'
import { PeerTubeNSFWDetailsComponent } from './peertube-nsfw-details-component'
+import { PeerTubeNSFWInfoComponent } from './peertube-nsfw-info-component'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
export type PeerTubeNSFWPluginOptions = {
summary: string
@@ -13,8 +14,8 @@ class PeerTubeNSFWPlugin extends Plugin {
declare private nsfwInfoComponent: PeerTubeNSFWInfoComponent
declare private nsfwDetailsComponent: PeerTubeNSFWDetailsComponent
- constructor (player: videojs.Player, options: videojs.PlayerOptions & PeerTubeNSFWPluginOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: PeerTubeNSFWPluginOptions) {
+ super(player)
player.ready(() => {
player.addClass('peertube-nsfw')
diff --git a/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts b/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts
index 2bd094db4..f6ac83105 100644
--- a/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts
+++ b/client/src/standalone/player/src/shared/p2p-media-loader/hls-plugin.ts
@@ -1,12 +1,13 @@
// Thanks https://github.com/streamroot/videojs-hlsjs-plugin
// We duplicated this plugin to choose the hls.js version we want, because streamroot only provide a bundled file
+import { omit } from '@peertube/peertube-core-utils'
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'
+import videojs from 'video.js'
+import Tech, { SourceObject } from 'video.js/dist/types/tech/tech'
+import { HLSPluginOptions, HlsjsConfigHandlerOptions, PeerTubeResolution, VideoJSTechHLS, VideojsPlayer, VideojsPlugin } from '../../types'
const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hlsjs)
@@ -37,7 +38,7 @@ const registerSourceHandler = function (vjs: typeof videojs) {
alreadyRegistered = true // FIXME: typings
;(html5 as any).registerSourceHandler({
- canHandleSource: function (source: videojs.Tech.SourceObject) {
+ canHandleSource: function (source: SourceObject) {
const hlsTypeRE = /^application\/x-mpegURL|application\/vnd\.apple\.mpegurl$/i
const hlsExtRE = /\.m3u8/i
@@ -47,7 +48,7 @@ const registerSourceHandler = function (vjs: typeof videojs) {
return ''
},
- handleSource: function (source: videojs.Tech.SourceObject, tech: VideoJSTechHLS) {
+ handleSource: function (source: SourceObject, tech: VideoJSTechHLS) {
if (tech.hlsProvider) {
tech.hlsProvider.dispose()
}
@@ -64,11 +65,11 @@ const registerSourceHandler = function (vjs: typeof videojs) {
// HLS options plugin
// ---------------------------------------------------------------------------
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class HLSJSConfigHandler extends Plugin {
- constructor (player: videojs.Player, options: HlsjsConfigHandlerOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options: HlsjsConfigHandlerOptions) {
+ super(player)
if (!options) return
@@ -109,9 +110,9 @@ videojs.registerPlugin('hlsjs', HLSJSConfigHandler)
export class Html5Hlsjs {
private readonly videoElement: HTMLVideoElement
private readonly errorCounts: ErrorCounts = {}
- private readonly player: videojs.Player
- private readonly tech: videojs.Tech
- private readonly source: videojs.Tech.SourceObject
+ private readonly player: VideojsPlayer
+ private readonly tech: Tech
+ private readonly source: SourceObject
private readonly vjs: typeof videojs
private maxNetworkErrorRecovery = 5
@@ -134,7 +135,7 @@ export class Html5Hlsjs {
private audioMode = false
- constructor (vjs: typeof videojs, source: videojs.Tech.SourceObject, tech: videojs.Tech) {
+ constructor (vjs: typeof videojs, source: SourceObject, tech: Tech) {
this.vjs = vjs
this.source = source
@@ -142,7 +143,7 @@ export class Html5Hlsjs {
;(this.tech as any).name_ = 'Hlsjs'
this.videoElement = tech.el() as HTMLVideoElement
- this.player = vjs((tech.options_ as any).playerId)
+ this.player = vjs(tech.options_.playerId) as VideojsPlayer
this.handlers.error = event => {
let errorTxt: string
diff --git a/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts
index 07a038722..b17ce60ca 100644
--- a/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts
+++ b/client/src/standalone/player/src/shared/p2p-media-loader/p2p-media-loader-plugin.ts
@@ -5,12 +5,13 @@ import { FragLoadedData, 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 { P2PMediaLoaderPluginOptions, PlayerNetworkInfo, VideojsPlayer, VideojsPlugin } from '../../types'
import { SettingsButton } from '../settings/settings-menu-button'
const debugLogger = debug('peertube:player:p2p-media-loader')
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
+
class P2pMediaLoaderPlugin extends Plugin {
declare private readonly options: P2PMediaLoaderPluginOptions
@@ -35,7 +36,7 @@ class P2pMediaLoaderPlugin extends Plugin {
declare private connectedPeers: Set
declare private totalHTTPPeers: number
- constructor (player: videojs.Player, options?: P2PMediaLoaderPluginOptions) {
+ constructor (player: VideojsPlayer, options?: P2PMediaLoaderPluginOptions) {
super(player)
this.options = options
diff --git a/client/src/standalone/player/src/shared/peertube/peertube-plugin.ts b/client/src/standalone/player/src/shared/peertube/peertube-plugin.ts
index 7d731ca7f..6ae35ff35 100644
--- a/client/src/standalone/player/src/shared/peertube/peertube-plugin.ts
+++ b/client/src/standalone/player/src/shared/peertube/peertube-plugin.ts
@@ -5,6 +5,8 @@ import { isIOS, isMobile, isSafari } from '@root-helpers/web-browser'
import debug from 'debug'
import { UAParser } from 'ua-parser-js'
import videojs from 'video.js'
+import type MediaError from 'video.js/dist/types/media-error'
+import type ModalDialog from 'video.js/dist/types/modal-dialog'
import {
getPlayerSessionId,
getStoredLastSubtitle,
@@ -16,19 +18,26 @@ import {
saveVideoWatchHistory,
saveVolumeInStore
} from '../../peertube-player-local-storage'
-import { PeerTubePluginOptions } from '../../types'
+import type {
+ PeerTubePluginOptions,
+ VideojsAutoplay,
+ VideojsCaptionsButton,
+ VideojsPlayer,
+ VideojsPlayerOptions,
+ VideojsPlugin
+} from '../../types'
import { SettingsButton } from '../settings/settings-menu-button'
const debugLogger = debug('peertube:player:peertube')
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class PeerTubePlugin extends Plugin {
declare private readonly videoViewUrl: () => string
declare private readonly authorizationHeader: () => string
declare private readonly initialInactivityTimeout: number
- declare private readonly hasAutoplay: () => videojs.Autoplay
+ declare private readonly hasAutoplay: () => VideojsAutoplay
declare private currentSubtitle: string
declare private currentPlaybackRate: number
@@ -39,7 +48,7 @@ class PeerTubePlugin extends Plugin {
declare private mouseInControlBar: boolean
declare private mouseInSettings: boolean
- declare private errorModal: videojs.ModalDialog
+ declare private errorModal: ModalDialog
declare private hasInitialSeek: boolean
@@ -56,7 +65,7 @@ class PeerTubePlugin extends Plugin {
os: string
}
- constructor (player: videojs.Player, private readonly options: PeerTubePluginOptions) {
+ constructor (player: VideojsPlayer, private readonly options: PeerTubePluginOptions) {
super(player)
this.setUserAgentInfo()
@@ -99,7 +108,7 @@ class PeerTubePlugin extends Plugin {
})
this.player.one('canplay', () => {
- const playerOptions = this.player.options_
+ const playerOptions = this.player.options_ as VideojsPlayerOptions
const volume = getStoredVolume()
if (volume !== undefined) this.player.volume(volume)
@@ -298,7 +307,7 @@ class PeerTubePlugin extends Plugin {
this.player.on('video-change', () => tryToUpdateRatioFromOptions())
- this.player.on('video-ratio-changed', (_event, data: { ratio: number }) => {
+ this.player.on('video-ratio-changed', (_event: any, data: { ratio: number }) => {
if (this.options.videoRatio()) return
this.adaptPlayerFromRatio({ ratio: data.ratio, defaultRatio })
@@ -497,7 +506,7 @@ class PeerTubePlugin extends Plugin {
private listenControlBarMouse () {
const controlBar = this.player.controlBar
- const settingsButton: SettingsButton = (controlBar as any).settingsButton
+ const settingsButton = controlBar.settingsButton
controlBar.on('mouseenter', () => {
this.mouseInControlBar = true
@@ -635,24 +644,6 @@ class PeerTubePlugin extends Plugin {
// Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657
private initSmoothProgressBar () {
- const SeekBar = videojs.getComponent('SeekBar') as any
- SeekBar.prototype.getPercent = function getPercent () {
- // Allows for smooth scrubbing, when player can't keep up.
- // const time = (this.player_.scrubbing()) ?
- // this.player_.getCache().currentTime :
- // this.player_.currentTime()
- const time = this.player_.currentTime()
- const percent = time / this.player_.duration()
- return percent >= 1 ? 1 : percent
- }
- SeekBar.prototype.handleMouseMove = function handleMouseMove (event: any) {
- let newTime = this.calculateDistance(event) * this.player_.duration()
- if (newTime === this.player_.duration()) {
- newTime = newTime - 0.1
- }
- this.player_.currentTime(newTime)
- this.update()
- }
}
private patchMenuEscapeKey () {
@@ -688,7 +679,7 @@ class PeerTubePlugin extends Plugin {
private getCaptionsButton () {
const settingsButton = this.player.controlBar.getDescendant([ 'settingsButton' ]) as SettingsButton
- return settingsButton.menu.getChild('captionsButton') as videojs.CaptionsButton
+ return settingsButton.menu.getChild('captionsButton') as unknown as VideojsCaptionsButton
}
private getPlaybackRateButton () {
diff --git a/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts
index 42f472df4..55f89c50f 100644
--- a/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts
+++ b/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts
@@ -7,8 +7,8 @@ import {
} from '../../types'
type ControlBarOptionsBuilderConstructorOptions =
- Pick &
- {
+ & Pick
+ & {
videoShortUUID: () => string
p2pEnabled: () => boolean
@@ -17,7 +17,6 @@ type ControlBarOptionsBuilderConstructorOptions =
}
export class ControlBarOptionsBuilder {
-
constructor (private options: ControlBarOptionsBuilderConstructorOptions) {
}
@@ -84,11 +83,7 @@ export class ControlBarOptionsBuilder {
progressControl: {
children: {
seekBar: {
- children: {
- loadProgressBar: {},
- mouseTimeDisplay: {},
- playProgressBar: {}
- }
+ children: [ 'loadProgressBar', 'mouseTimeDisplay', 'playProgressBar' ]
}
}
}
diff --git a/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts
index a0ee03723..01fdba427 100644
--- a/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts
+++ b/client/src/standalone/player/src/shared/player-options-builder/hls-options-builder.ts
@@ -7,7 +7,13 @@ 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 { HLSPluginOptions, P2PMediaLoaderPluginOptions, PeerTubePlayerConstructorOptions, PeerTubePlayerLoadOptions } from '../../types'
+import {
+ HLSPluginOptions,
+ P2PMediaLoaderPluginOptions,
+ PeerTubePlayerConstructorOptions,
+ PeerTubePlayerLoadOptions,
+ VideojsPlayer
+} from '../../types'
import { getRtcConfig } from '../common'
import { RedundancyUrlManager } from '../p2p-media-loader/redundancy-url-manager'
import { SegmentValidator } from '../p2p-media-loader/segment-validator'
@@ -67,7 +73,7 @@ export class HLSOptionsBuilder {
const hlsjs = {
hlsjsConfig: this.getHLSJSOptions(p2pMediaLoaderConfig),
- levelLabelHandler: (level: Level, player: videojs.VideoJsPlayer) => {
+ levelLabelHandler: (level: Level, player: VideojsPlayer) => {
const resolution = Math.min(level.height || 0, level.width || 0)
const file = this.options.hls.videoFiles.find(f => f.resolution.id === resolution)
diff --git a/client/src/standalone/player/src/shared/playlist/playlist-button.ts b/client/src/standalone/player/src/shared/playlist/playlist-button.ts
index b5bb63c7f..d788e3858 100644
--- a/client/src/standalone/player/src/shared/playlist/playlist-button.ts
+++ b/client/src/standalone/player/src/shared/playlist/playlist-button.ts
@@ -1,20 +1,20 @@
import videojs from 'video.js'
-import { PlaylistPluginOptions } from '../../types'
+import { PlaylistPluginOptions, VideojsClickableComponent, VideojsClickableComponentOptions, VideojsPlayer } from '../../types'
import { PlaylistMenu } from './playlist-menu'
-const ClickableComponent = videojs.getComponent('ClickableComponent')
+const ClickableComponent = videojs.getComponent('ClickableComponent') as typeof VideojsClickableComponent
class PlaylistButton extends ClickableComponent {
declare private playlistInfoElement: HTMLElement
declare private wrapper: HTMLElement
- declare options_: PlaylistPluginOptions & { playlistMenu: PlaylistMenu } & videojs.ClickableComponentOptions
+ declare options_: PlaylistPluginOptions & { playlistMenu: PlaylistMenu } & VideojsClickableComponentOptions
// FIXME: eslint -> it's not a useless constructor, we need to extend constructor options typings
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor (
- player: videojs.Player,
- options?: PlaylistPluginOptions & { playlistMenu: PlaylistMenu } & videojs.ClickableComponentOptions
+ player: VideojsPlayer,
+ options?: PlaylistPluginOptions & { playlistMenu: PlaylistMenu } & VideojsClickableComponentOptions
) {
super(player, options)
}
diff --git a/client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts b/client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts
index 578950161..b159dae7c 100644
--- a/client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts
+++ b/client/src/standalone/player/src/shared/playlist/playlist-menu-item.ts
@@ -1,9 +1,9 @@
-import videojs from 'video.js'
import { secondsToTime } from '@peertube/peertube-core-utils'
import { VideoPlaylistElement } from '@peertube/peertube-models'
-import { PlaylistItemOptions } from '../../types'
+import videojs from 'video.js'
+import { PlaylistItemOptions, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class PlaylistMenuItem extends Component {
declare private element: VideoPlaylistElement
@@ -11,10 +11,10 @@ class PlaylistMenuItem extends Component {
declare private clickHandler: () => void
declare private keyDownHandler: (event: KeyboardEvent) => void
- declare options_: videojs.ComponentOptions & PlaylistItemOptions
+ declare options_: VideojsComponentOptions & PlaylistItemOptions
- constructor (player: videojs.Player, options?: PlaylistItemOptions) {
- super(player, options as any)
+ constructor (player: VideojsPlayer, options?: VideojsComponentOptions & PlaylistItemOptions) {
+ super(player, options)
this.emitTapEvents()
@@ -130,7 +130,8 @@ class PlaylistMenuItem extends Component {
li.appendChild(block)
}
- private handleKeyDown (event: KeyboardEvent) {
+ // Can't put it private because it's public in parent component
+ handleKeyDown (event: KeyboardEvent) {
if (event.code === 'Space' || event.code === 'Enter') {
this.switchPlaylistItem()
}
@@ -141,6 +142,6 @@ class PlaylistMenuItem extends Component {
}
}
-Component.registerComponent('PlaylistMenuItem', PlaylistMenuItem)
+videojs.registerComponent('PlaylistMenuItem', PlaylistMenuItem)
export { PlaylistMenuItem }
diff --git a/client/src/standalone/player/src/shared/playlist/playlist-menu.ts b/client/src/standalone/player/src/shared/playlist/playlist-menu.ts
index b9c991e2a..f759611c7 100644
--- a/client/src/standalone/player/src/shared/playlist/playlist-menu.ts
+++ b/client/src/standalone/player/src/shared/playlist/playlist-menu.ts
@@ -1,9 +1,9 @@
-import videojs from 'video.js'
import { VideoPlaylistElement } from '@peertube/peertube-models'
-import { PlaylistPluginOptions } from '../../types'
+import videojs from 'video.js'
+import { PlaylistPluginOptions, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
import { PlaylistMenuItem } from './playlist-menu-item'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class PlaylistMenu extends Component {
declare private menuItems: PlaylistMenuItem[]
@@ -14,9 +14,9 @@ class PlaylistMenu extends Component {
declare private readonly onPlayerCick: (event: Event) => void
- declare options_: PlaylistPluginOptions & videojs.ComponentOptions
+ declare options_: PlaylistPluginOptions & VideojsComponentOptions
- constructor (player: videojs.Player, options?: PlaylistPluginOptions & videojs.ComponentOptions) {
+ constructor (player: VideojsPlayer, options?: PlaylistPluginOptions & VideojsComponentOptions) {
super(player, options)
this.menuItems = []
@@ -152,6 +152,6 @@ class PlaylistMenu extends Component {
}
}
-Component.registerComponent('PlaylistMenu', PlaylistMenu)
+videojs.registerComponent('PlaylistMenu', PlaylistMenu)
export { PlaylistMenu }
diff --git a/client/src/standalone/player/src/shared/playlist/playlist-plugin.ts b/client/src/standalone/player/src/shared/playlist/playlist-plugin.ts
index 4cb208032..9ea839fac 100644
--- a/client/src/standalone/player/src/shared/playlist/playlist-plugin.ts
+++ b/client/src/standalone/player/src/shared/playlist/playlist-plugin.ts
@@ -1,16 +1,16 @@
import videojs from 'video.js'
-import { PlaylistPluginOptions } from '../../types'
+import { PlaylistPluginOptions, VideojsPlayer, VideojsPlugin } from '../../types'
import { PlaylistButton } from './playlist-button'
import { PlaylistMenu } from './playlist-menu'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class PlaylistPlugin extends Plugin {
declare private playlistMenu: PlaylistMenu
declare private playlistButton: PlaylistButton
- constructor (player: videojs.Player, options?: PlaylistPluginOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options?: PlaylistPluginOptions) {
+ super(player)
this.player.addClass('vjs-playlist')
diff --git a/client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts b/client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts
index d5fb98d02..088470df7 100644
--- a/client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts
+++ b/client/src/standalone/player/src/shared/resolutions/peertube-resolutions-plugin.ts
@@ -1,7 +1,7 @@
import videojs from 'video.js'
-import { PeerTubeResolution } from '../../types'
+import { PeerTubeResolution, VideojsPlayer, VideojsPlugin } from '../../types'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class PeerTubeResolutionsPlugin extends Plugin {
declare private currentSelection: PeerTubeResolution
@@ -9,7 +9,7 @@ class PeerTubeResolutionsPlugin extends Plugin {
declare private autoResolutionChosenId: number
- constructor (player: videojs.Player) {
+ constructor (player: VideojsPlayer) {
super(player)
this.resolutions = []
@@ -85,7 +85,6 @@ class PeerTubeResolutionsPlugin extends Plugin {
return 1
})
}
-
}
videojs.registerPlugin('peertubeResolutions', PeerTubeResolutionsPlugin)
diff --git a/client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts b/client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts
index ad148e823..0bda7c5be 100644
--- a/client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts
+++ b/client/src/standalone/player/src/shared/settings/menu-focus-fixed.ts
@@ -1,12 +1,12 @@
import videojs from 'video.js'
+import { VideojsMenu } from '../../types'
-const Menu = videojs.getComponent('Menu')
-const Component = videojs.getComponent('Component')
+const Menu = videojs.getComponent('Menu') as typeof VideojsMenu
// Default menu doesn't check if the child is disabled/hidden
class MenuFocusFixed extends Menu {
- declare private focusedChild_: number
+ declare focusedChild_: number
stepForward () {
let stepChild = 0
@@ -72,5 +72,5 @@ class MenuFocusFixed extends Menu {
}
}
-Component.registerComponent('MenuFocusFixed', MenuFocusFixed)
+videojs.registerComponent('MenuFocusFixed', MenuFocusFixed)
export { MenuFocusFixed }
diff --git a/client/src/standalone/player/src/shared/settings/resolution-menu-button.ts b/client/src/standalone/player/src/shared/settings/resolution-menu-button.ts
index b0f6dbc14..c48641581 100644
--- a/client/src/standalone/player/src/shared/settings/resolution-menu-button.ts
+++ b/client/src/standalone/player/src/shared/settings/resolution-menu-button.ts
@@ -1,12 +1,14 @@
import videojs from 'video.js'
+import { VideojsMenu, VideojsMenuButton, VideojsMenuButtonOptions, VideojsPlayer } from '../../types'
import { ResolutionMenuItem } from './resolution-menu-item'
-const Menu = videojs.getComponent('Menu')
-const MenuButton = videojs.getComponent('MenuButton')
+const Menu = videojs.getComponent('Menu') as typeof VideojsMenu
+const MenuButton = videojs.getComponent('MenuButton') as typeof VideojsMenuButton
+
class ResolutionMenuButton extends MenuButton {
declare labelEl_: HTMLElement
- constructor (player: videojs.Player, options?: videojs.MenuButtonOptions) {
+ constructor (player: VideojsPlayer, options?: VideojsMenuButtonOptions) {
super(player, options)
this.controlText('Quality')
@@ -37,7 +39,7 @@ class ResolutionMenuButton extends MenuButton {
}
createMenu () {
- const menu: videojs.Menu = new Menu(this.player_, { menuButton: this })
+ const menu = new Menu(this.player_, { menuButton: this })
const resolutions = this.player().peertubeResolutions().getResolutions()
for (const r of resolutions) {
diff --git a/client/src/standalone/player/src/shared/settings/resolution-menu-item.ts b/client/src/standalone/player/src/shared/settings/resolution-menu-item.ts
index 46999161e..f5990ad0a 100644
--- a/client/src/standalone/player/src/shared/settings/resolution-menu-item.ts
+++ b/client/src/standalone/player/src/shared/settings/resolution-menu-item.ts
@@ -1,9 +1,10 @@
import videojs from 'video.js'
+import { VideojsMenuItem, VideojsMenuItemOptions, VideojsPlayer } from '../../types'
-const MenuItem = videojs.getComponent('MenuItem')
+const MenuItem = videojs.getComponent('MenuItem') as typeof VideojsMenuItem
-export interface ResolutionMenuItemOptions extends videojs.MenuItemOptions {
- resolutionId: number
+export interface ResolutionMenuItemOptions extends VideojsMenuItemOptions {
+ resolutionId?: number
}
class ResolutionMenuItem extends MenuItem {
@@ -14,7 +15,7 @@ class ResolutionMenuItem extends MenuItem {
declare private updateSelectionHandler: () => void
- constructor (player: videojs.Player, options?: ResolutionMenuItemOptions) {
+ constructor (player: VideojsPlayer, options?: ResolutionMenuItemOptions) {
super(player, { ...options, selectable: true })
this.autoResolutionChosen = ''
diff --git a/client/src/standalone/player/src/shared/settings/settings-dialog.ts b/client/src/standalone/player/src/shared/settings/settings-dialog.ts
index 7c2fbd8c3..12d57a650 100644
--- a/client/src/standalone/player/src/shared/settings/settings-dialog.ts
+++ b/client/src/standalone/player/src/shared/settings/settings-dialog.ts
@@ -1,9 +1,10 @@
import videojs from 'video.js'
+import { VideojsComponent, VideojsPlayer } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class SettingsDialog extends Component {
- constructor (player: videojs.Player) {
+ constructor (player: VideojsPlayer) {
super(player)
this.hide()
@@ -41,6 +42,6 @@ class SettingsDialog extends Component {
}
}
-Component.registerComponent('SettingsDialog', SettingsDialog)
+videojs.registerComponent('SettingsDialog', SettingsDialog)
export { SettingsDialog }
diff --git a/client/src/standalone/player/src/shared/settings/settings-menu-button.ts b/client/src/standalone/player/src/shared/settings/settings-menu-button.ts
index d7731709a..d7970da9f 100644
--- a/client/src/standalone/player/src/shared/settings/settings-menu-button.ts
+++ b/client/src/standalone/player/src/shared/settings/settings-menu-button.ts
@@ -1,5 +1,6 @@
import debug from 'debug'
import videojs from 'video.js'
+import { VideojsButton, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
import { toTitleCase } from '../common'
import { MenuFocusFixed } from './menu-focus-fixed'
import { SettingsDialog } from './settings-dialog'
@@ -9,10 +10,10 @@ import { SettingsPanelChild } from './settings-panel-child'
const debugLogger = debug('peertube:player:settings')
-const Button = videojs.getComponent('Button')
-const Component = videojs.getComponent('Component')
+const Button = videojs.getComponent('Button') as typeof VideojsButton
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
-export interface SettingsButtonOptions extends videojs.ComponentOptions {
+export interface SettingsButtonOptions extends VideojsComponentOptions {
entries: any[]
setup?: {
maxHeightOffset: number
@@ -33,18 +34,18 @@ class SettingsButton extends Button {
declare private settingsButtonOptions: SettingsButtonOptions
- constructor (player: videojs.Player, options?: SettingsButtonOptions) {
+ constructor (player: VideojsPlayer, options?: SettingsButtonOptions) {
super(player, options)
this.settingsButtonOptions = options
this.controlText('Settings')
- this.dialog = this.player().addChild('settingsDialog')
+ this.dialog = this.player().addChild('settingsDialog') as SettingsDialog
this.dialogEl = this.dialog.el() as HTMLElement
this.menu = null
- this.panel = this.dialog.addChild('settingsPanel')
- this.panelChild = this.panel.addChild('settingsPanelChild')
+ this.panel = this.dialog.addChild('settingsPanel') as SettingsPanel
+ this.panelChild = this.panel.addChild('settingsPanelChild') as SettingsPanelChild
this.addClass('vjs-settings')
this.setAttribute('aria-controls', 'vjs-settings-dialog-' + this.player().id())
@@ -170,7 +171,7 @@ class SettingsButton extends Button {
this.resetChildren()
}
- getComponentSize (element: videojs.Component | HTMLElement) {
+ getComponentSize (element: VideojsComponent | HTMLElement) {
let width: number = null
let height: number = null
@@ -217,7 +218,7 @@ class SettingsButton extends Button {
this.focus()
})
- this.menu.on('arrow-right', (_, el) => {
+ this.menu.on('arrow-right', (_: any, el: HTMLElement) => {
debugLogger('Detected arrow right on menu item', el)
el.click()
@@ -257,7 +258,7 @@ class SettingsButton extends Button {
// Hide children to avoid sub menus stacking on top of each other
// or having multiple menus open
- settingsMenuItem.on('click', videojs.bind(this, this.hideChildren))
+ settingsMenuItem.on('click', () => this.hideChildren())
// Whether to add or remove selected class on the settings sub menu element
settingsMenuItem.on('click', openSubMenu)
@@ -288,6 +289,6 @@ class SettingsButton extends Button {
}
}
-Component.registerComponent('SettingsButton', SettingsButton)
+videojs.registerComponent('SettingsButton', SettingsButton)
export { SettingsButton }
diff --git a/client/src/standalone/player/src/shared/settings/settings-menu-item.ts b/client/src/standalone/player/src/shared/settings/settings-menu-item.ts
index 91ab0c794..989cc2fe8 100644
--- a/client/src/standalone/player/src/shared/settings/settings-menu-item.ts
+++ b/client/src/standalone/player/src/shared/settings/settings-menu-item.ts
@@ -1,37 +1,40 @@
import debug from 'debug'
import videojs from 'video.js'
+import { VideojsComponent, VideojsMenu, VideojsMenuItem, VideojsMenuItemOptions, VideojsPlayer } from '../../types'
import { toTitleCase } from '../common'
import { SettingsDialog } from './settings-dialog'
import { SettingsButton } from './settings-menu-button'
import { SettingsPanel } from './settings-panel'
import { SettingsPanelChild } from './settings-panel-child'
+import Button from 'video.js/dist/types/button'
+import MenuButton from 'video.js/dist/types/menu/menu-button'
const debugLogger = debug('peertube:player:settings')
-const MenuItem = videojs.getComponent('MenuItem')
-const Component = videojs.getComponent('Component')
+const MenuItem = videojs.getComponent('MenuItem') as typeof VideojsMenuItem
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
-interface MenuItemExtended extends videojs.MenuItem {
+interface MenuItemExtended extends VideojsMenuItem {
isSelected_: boolean
getLabel?: () => string
}
-export interface SettingsMenuItemOptions extends videojs.MenuItemOptions {
- entry: string
- menuButton: SettingsButton
+export interface SettingsMenuItemOptions extends VideojsMenuItemOptions {
+ entry?: string
+ menuButton?: SettingsButton
}
class SettingsMenuItem extends MenuItem {
declare settingsButton: SettingsButton
declare dialog: SettingsDialog
- declare mainMenu: videojs.Menu
+ declare mainMenu: VideojsMenu
declare panel: SettingsPanel
declare panelChild: SettingsPanelChild
declare panelChildEl: HTMLElement
declare size: number[]
declare menuToLoad: string
- declare subMenu: SettingsButton
+ declare subMenu: MenuButton
declare submenuClickHandler: typeof SettingsMenuItem.prototype.onSubmenuClick
declare transitionEndHandler: typeof SettingsMenuItem.prototype.onTransitionEnd
@@ -40,14 +43,14 @@ class SettingsMenuItem extends MenuItem {
declare settingsSubMenuValueEl_: HTMLElement
declare settingsSubMenuEl_: HTMLElement
- constructor (player: videojs.Player, options?: SettingsMenuItemOptions) {
+ constructor (player: VideojsPlayer, options?: SettingsMenuItemOptions) {
super(player, options)
this.settingsButton = options.menuButton
this.dialog = this.settingsButton.dialog
this.mainMenu = this.settingsButton.menu
- this.panel = this.dialog.getChild('settingsPanel')
- this.panelChild = this.panel.getChild('settingsPanelChild')
+ this.panel = this.dialog.getChild('settingsPanel') as SettingsPanel
+ this.panelChild = this.panel.getChild('settingsPanelChild') as SettingsPanelChild
this.panelChildEl = this.panelChild.el() as HTMLElement
this.size = null
@@ -56,15 +59,15 @@ class SettingsMenuItem extends MenuItem {
this.menuToLoad = 'mainmenu'
const subMenuName = toTitleCase(options.entry)
- const SubMenuComponent = videojs.getComponent(subMenuName)
+ const SubMenuComponent = videojs.getComponent(subMenuName) as typeof MenuButton
+
+ console.log(options.entry)
if (!SubMenuComponent) {
throw new Error(`Component ${subMenuName} does not exist`)
}
- const newOptions = Object.assign({}, options, { entry: options.menuButton, menuButton: this })
-
- this.subMenu = new SubMenuComponent(this.player(), newOptions) as SettingsButton
+ this.subMenu = new SubMenuComponent(this.player(), { ...options })
const subMenuClass = this.subMenu.buildCSSClass().split(' ')[0]
this.settingsSubMenuEl_.className += ' ' + subMenuClass
@@ -174,7 +177,7 @@ class SettingsMenuItem extends MenuItem {
*
* @method handleClick
*/
- handleClick (event: videojs.EventTarget.Event) {
+ handleClick (event: Event) {
this.menuToLoad = 'submenu'
// Remove open class to ensure only the open submenu gets this class
videojs.dom.removeClass(this.el(), 'open')
@@ -239,8 +242,7 @@ class SettingsMenuItem extends MenuItem {
mainMenuEl.style.opacity = '0'
// back button will always take you to main menu, so set dialog sizes
- const mainMenuAny = this.mainMenu
- this.settingsButton.setDialogSize([ mainMenuAny.width() as number, mainMenuAny.height() as number ])
+ this.settingsButton.setDialogSize([ this.mainMenu.width(), this.mainMenu.height() ])
// animation not triggered without timeout (some async stuff ?!?)
setTimeout(() => {
@@ -376,7 +378,6 @@ class SettingsMenuItem extends MenuItem {
}
}
-;(SettingsMenuItem as any).prototype.contentElType = 'button'
videojs.registerComponent('SettingsMenuItem', SettingsMenuItem)
export { SettingsMenuItem }
diff --git a/client/src/standalone/player/src/shared/settings/settings-panel-child.ts b/client/src/standalone/player/src/shared/settings/settings-panel-child.ts
index d4ce5ce3f..41bad40c3 100644
--- a/client/src/standalone/player/src/shared/settings/settings-panel-child.ts
+++ b/client/src/standalone/player/src/shared/settings/settings-panel-child.ts
@@ -1,9 +1,9 @@
import videojs from 'video.js'
+import { VideojsComponent } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class SettingsPanelChild extends Component {
-
createEl () {
return super.createEl('div', {
className: 'vjs-settings-panel-child',
@@ -12,6 +12,6 @@ class SettingsPanelChild extends Component {
}
}
-Component.registerComponent('SettingsPanelChild', SettingsPanelChild)
+videojs.registerComponent('SettingsPanelChild', SettingsPanelChild)
export { SettingsPanelChild }
diff --git a/client/src/standalone/player/src/shared/settings/settings-panel.ts b/client/src/standalone/player/src/shared/settings/settings-panel.ts
index d7c198bbf..1fe35372d 100644
--- a/client/src/standalone/player/src/shared/settings/settings-panel.ts
+++ b/client/src/standalone/player/src/shared/settings/settings-panel.ts
@@ -1,9 +1,9 @@
import videojs from 'video.js'
+import { VideojsComponent } from '../../types'
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
class SettingsPanel extends Component {
-
createEl () {
return super.createEl('div', {
className: 'vjs-settings-panel',
@@ -12,6 +12,6 @@ class SettingsPanel extends Component {
}
}
-Component.registerComponent('SettingsPanel', SettingsPanel)
+videojs.registerComponent('SettingsPanel', SettingsPanel)
export { SettingsPanel }
diff --git a/client/src/standalone/player/src/shared/stats/stats-card.ts b/client/src/standalone/player/src/shared/stats/stats-card.ts
index a40bc37de..f75d4a3d8 100644
--- a/client/src/standalone/player/src/shared/stats/stats-card.ts
+++ b/client/src/standalone/player/src/shared/stats/stats-card.ts
@@ -1,10 +1,11 @@
-import videojs from 'video.js'
-import { logger } from '@root-helpers/logger'
import { secondsToTime } from '@peertube/peertube-core-utils'
-import { PlayerNetworkInfo as EventPlayerNetworkInfo } from '../../types'
+import { logger } from '@root-helpers/logger'
+import videojs from 'video.js'
+import { TimeRange } from 'video.js/dist/types/utils/time'
+import { PlayerNetworkInfo as EventPlayerNetworkInfo, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
import { bytes } from '../common'
-interface StatsCardOptions extends videojs.ComponentOptions {
+interface StatsCardOptions extends VideojsComponentOptions {
videoUUID: string
videoIsLive: boolean
mode: 'web-video' | 'p2p-media-loader'
@@ -28,7 +29,8 @@ interface InfoElement {
value: HTMLElement
}
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
+
class StatsCard extends Component {
declare options_: StatsCardOptions
@@ -65,7 +67,7 @@ class StatsCard extends Component {
declare private onNetworkInfoHandler: (_event: any, data: EventPlayerNetworkInfo) => void
- constructor (player: videojs.Player, options?: StatsCardOptions) {
+ constructor (player: VideojsPlayer, options?: StatsCardOptions) {
super(player, options)
this.metadataStore = {}
@@ -365,7 +367,7 @@ class StatsCard extends Component {
return { root, value }
}
- private timeRangesToString (r: videojs.TimeRange) {
+ private timeRangesToString (r: TimeRange) {
let result = ''
for (let i = 0; i < r.length; i++) {
diff --git a/client/src/standalone/player/src/shared/stats/stats-plugin.ts b/client/src/standalone/player/src/shared/stats/stats-plugin.ts
index c680b2659..9dd64e365 100644
--- a/client/src/standalone/player/src/shared/stats/stats-plugin.ts
+++ b/client/src/standalone/player/src/shared/stats/stats-plugin.ts
@@ -1,12 +1,13 @@
import videojs from 'video.js'
+import { VideojsPlayer, VideojsPlugin } from '../../types'
import { StatsCard, StatsCardOptions } from './stats-card'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class StatsForNerdsPlugin extends Plugin {
declare private statsCard: StatsCard
- constructor (player: videojs.Player, options: StatsCardOptions) {
+ constructor (player: VideojsPlayer, options: StatsCardOptions) {
super(player)
this.player.ready(() => {
diff --git a/client/src/standalone/player/src/shared/upnext/end-card.ts b/client/src/standalone/player/src/shared/upnext/end-card.ts
index b056f4b9b..03db2d303 100644
--- a/client/src/standalone/player/src/shared/upnext/end-card.ts
+++ b/client/src/standalone/player/src/shared/upnext/end-card.ts
@@ -1,5 +1,5 @@
import videojs from 'video.js'
-import { UpNextPluginOptions } from '../../types'
+import { UpNextPluginOptions, VideojsComponent, VideojsComponentOptions, VideojsPlayer } from '../../types'
function getMainTemplate (options: EndCardOptions) {
return `
@@ -24,13 +24,14 @@ function getMainTemplate (options: EndCardOptions) {
`
}
-export interface EndCardOptions extends videojs.ComponentOptions, UpNextPluginOptions {
+export interface EndCardOptions extends VideojsComponentOptions, UpNextPluginOptions {
cancelText: string
headText: string
suspendedText: string
}
-const Component = videojs.getComponent('Component')
+const Component = videojs.getComponent('Component') as typeof VideojsComponent
+
export class EndCard extends Component {
declare options_: EndCardOptions
@@ -53,7 +54,7 @@ export class EndCard extends Component {
declare private onEndedHandler: () => void
declare private onPlayingHandler: () => void
- constructor (player: videojs.Player, options: EndCardOptions) {
+ constructor (player: VideojsPlayer, options: EndCardOptions) {
super(player, options)
this.dashOffsetTotal = 586
diff --git a/client/src/standalone/player/src/shared/upnext/upnext-plugin.ts b/client/src/standalone/player/src/shared/upnext/upnext-plugin.ts
index 45688978c..24571b4a2 100644
--- a/client/src/standalone/player/src/shared/upnext/upnext-plugin.ts
+++ b/client/src/standalone/player/src/shared/upnext/upnext-plugin.ts
@@ -1,12 +1,11 @@
import videojs from 'video.js'
-import { UpNextPluginOptions } from '../../types'
+import { UpNextPluginOptions, VideojsPlayer, VideojsPlugin } from '../../types'
import { EndCard, EndCardOptions } from './end-card'
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class UpNextPlugin extends Plugin {
-
- constructor (player: videojs.Player, options: UpNextPluginOptions) {
+ constructor (player: VideojsPlayer, options: UpNextPluginOptions) {
super(player)
const settings: EndCardOptions = {
diff --git a/client/src/standalone/player/src/shared/web-video/web-video-plugin.ts b/client/src/standalone/player/src/shared/web-video/web-video-plugin.ts
index 0d4ae7146..2f2a84e98 100644
--- a/client/src/standalone/player/src/shared/web-video/web-video-plugin.ts
+++ b/client/src/standalone/player/src/shared/web-video/web-video-plugin.ts
@@ -3,11 +3,11 @@ import { VideoFile } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
import debug from 'debug'
import videojs from 'video.js'
-import { PeerTubeResolution, PlayerNetworkInfo, WebVideoPluginOptions } from '../../types'
+import { PeerTubeResolution, PlayerNetworkInfo, VideojsPlayer, VideojsPlugin, WebVideoPluginOptions } from '../../types'
const debugLogger = debug('peertube:player:web-video-plugin')
-const Plugin = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin') as typeof VideojsPlugin
class WebVideoPlugin extends Plugin {
declare private readonly videoFiles: VideoFile[]
@@ -21,8 +21,8 @@ class WebVideoPlugin extends Plugin {
declare private onPlayHandler: () => void
declare private onLoadedMetadata: () => void
- constructor (player: videojs.Player, options?: WebVideoPluginOptions) {
- super(player, options)
+ constructor (player: VideojsPlayer, options?: WebVideoPluginOptions) {
+ super(player)
this.videoFiles = options.videoFiles
this.videoFileToken = options.videoFileToken
@@ -109,7 +109,8 @@ class WebVideoPlugin extends Plugin {
.then(() => {
if (paused) this.player.pause()
- this.player.autoplay(oldAutoplayValue)
+ // FIXME: typings
+ this.player.autoplay(oldAutoplayValue as any)
})
}
}
diff --git a/client/src/standalone/player/src/types/peertube-player-options.ts b/client/src/standalone/player/src/types/peertube-player-options.ts
index f26dc05ab..b908f0e96 100644
--- a/client/src/standalone/player/src/types/peertube-player-options.ts
+++ b/client/src/standalone/player/src/types/peertube-player-options.ts
@@ -1,7 +1,7 @@
import { LiveVideoLatencyModeType, VideoChapter, VideoFile } from '@peertube/peertube-models'
import { PluginsManager } from '@root-helpers/plugins-manager'
import { PeerTubeDockPluginOptions } from '../shared/dock/peertube-dock-plugin'
-import { PlaylistPluginOptions, VideoJSCaption, VideoJSStoryboard } from './peertube-videojs-typings'
+import { PlaylistPluginOptions, VideoJSCaption, VideojsPlayer, VideoJSStoryboard } from './peertube-videojs-typings'
export type PlayerMode = 'web-video' | 'p2p-media-loader'
@@ -106,7 +106,7 @@ export type PeerTubePlayerLoadOptions = {
upnext?: {
isEnabled: () => boolean
- isSuspended: (player: videojs.VideoJsPlayer) => boolean
+ isSuspended: (player: VideojsPlayer) => boolean
timeout: number
}
diff --git a/client/src/standalone/player/src/types/peertube-videojs-typings.ts b/client/src/standalone/player/src/types/peertube-videojs-typings.ts
index b0607a14c..34e08fc64 100644
--- a/client/src/standalone/player/src/types/peertube-videojs-typings.ts
+++ b/client/src/standalone/player/src/types/peertube-videojs-typings.ts
@@ -3,6 +3,22 @@ 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 BigPlayButton from 'video.js/dist/types/big-play-button'
+import Button from 'video.js/dist/types/button'
+import ClickableComponent from 'video.js/dist/types/clickable-component'
+import Component from 'video.js/dist/types/component'
+import ControlBar from 'video.js/dist/types/control-bar/control-bar'
+import MouseTimeDisplay from 'video.js/dist/types/control-bar/progress-control/mouse-time-display'
+import ProgressControl from 'video.js/dist/types/control-bar/progress-control/progress-control'
+import SeekBar from 'video.js/dist/types/control-bar/progress-control/seek-bar'
+import TimeTooltip from 'video.js/dist/types/control-bar/progress-control/time-tooltip'
+import type CaptionButton from 'video.js/dist/types/control-bar/text-track-controls/captions-button'
+import LoadingSpinner from 'video.js/dist/types/loading-spinner'
+import Menu from 'video.js/dist/types/menu/menu'
+import MenuButton from 'video.js/dist/types/menu/menu-button'
+import MenuItem from 'video.js/dist/types/menu/menu-item'
+import type Plugin from 'video.js/dist/types/plugin'
+import Tech from 'video.js/dist/types/tech/tech'
import { BezelsPlugin } from '../shared/bezels/bezels-plugin'
import { ContextMenuPlugin } from '../shared/context-menu'
import { ChaptersPlugin } from '../shared/control-bar/chapters-plugin'
@@ -23,65 +39,28 @@ import { StatsForNerdsPlugin } from '../shared/stats/stats-plugin'
import { UpNextPlugin } from '../shared/upnext/upnext-plugin'
import { WebVideoPlugin } from '../shared/web-video/web-video-plugin'
import { PlayerMode } from './peertube-player-options'
+import { SettingsButton } from '../shared/settings/settings-menu-button'
declare module 'video.js' {
export interface VideoJsPlayer {
- srOptions_: HlsjsConfigHandlerOptions
-
- theaterEnabled: boolean
-
// FIXME: add it to upstream typings
- posterImage: {
- show(): void
- hide(): void
- }
handleTechSeeked_(): void
textTracks(): TextTrackList & {
tracks_: (TextTrack & { id: string, label: string, src: string })[]
}
-
- // Plugins
-
- peertube(): PeerTubePlugin
-
- webVideo(options?: any): WebVideoPlugin
-
- p2pMediaLoader(options?: any): P2pMediaLoaderPlugin
- hlsjs(options?: any): any
-
- peertubeResolutions(): PeerTubeResolutionsPlugin
-
- contextMenu(options?: ContextMenuPluginOptions): ContextMenuPlugin
-
- bezels(): BezelsPlugin
- peertubeMobile(): PeerTubeMobilePlugin
- peerTubeHotkeysPlugin(options?: HotkeysOptions): PeerTubeHotkeysPlugin
-
- stats(options?: StatsCardOptions): StatsForNerdsPlugin
-
- storyboard(options?: StoryboardOptions): StoryboardPlugin
-
- peertubeDock(options?: PeerTubeDockPluginOptions): PeerTubeDockPlugin
- peertubeNSFW(options?: PeerTubeNSFWPluginOptions): PeerTubeNSFWPlugin
-
- chapters(options?: ChaptersOptions): ChaptersPlugin
-
- upnext(options?: UpNextPluginOptions): UpNextPlugin
-
- playlist(options?: PlaylistPluginOptions): PlaylistPlugin
}
}
-export interface VideoJSTechHLS extends videojs.Tech {
+export interface VideoJSTechHLS extends Tech {
hlsProvider: Html5Hlsjs
}
export interface HlsjsConfigHandlerOptions {
hlsjsConfig?: HlsConfig
- levelLabelHandler?: (level: Level, player: videojs.Player) => string
+ levelLabelHandler?: (level: Level, player: VideojsPlayer) => string
}
export type PeerTubeResolution = {
@@ -116,7 +95,7 @@ export type PeerTubePluginOptions = {
cssPlayerPortraitModeVariable: string
}
- hasAutoplay: () => videojs.Autoplay
+ hasAutoplay: () => VideojsAutoplay
videoViewUrl: () => string
videoViewIntervalMs: number
@@ -154,7 +133,7 @@ export type ContextMenuPluginOptions = {
}
export type ContextMenuItemOptions = {
- listener: (e: videojs.EventTarget.Event) => void
+ listener: (e?: Event) => void
label: string
}
@@ -215,7 +194,7 @@ export type WebVideoPluginOptions = {
}
export type HLSLoaderClass = {
- new(confg: HlsConfig): Loader
+ new(config: HlsConfig): Loader
getEngine(): HlsJsP2PEngine
}
@@ -300,3 +279,150 @@ export type PlaylistItemOptions = {
onClicked: () => void
}
+
+type EventHandler = (event: any, data: any) => void
+
+export declare class VideojsPlugin extends Plugin {
+ player: VideojsPlayer
+
+ on (event: string, handler: EventHandler): this
+ one (event: string, handler: EventHandler): void
+ off (event: string, handler: EventHandler): void
+}
+
+export type VideojsPlayer = ReturnType & {
+ options_: ReturnType['options_'] & {
+ loop: boolean
+
+ userActions: {
+ click?: boolean
+ doubleClick?: boolean
+ }
+ }
+
+ posterImage: {
+ show(): void
+ hide(): void
+ }
+
+ error: (err?: MediaError | string | number) => MediaError
+
+ on(event: string, handler: EventHandler): void
+
+ loadingSpinner: LoadingSpinner
+ controlBar: ControlBar & {
+ settingsButton: SettingsButton
+
+ progressControl: ProgressControl & {
+ seekBar: SeekBar & {
+ mouseTimeDisplay: {
+ timeTooltip: MouseTimeDisplay
+ }
+ }
+ }
+ }
+ bigPlayButton: BigPlayButton
+
+ srOptions_: HlsjsConfigHandlerOptions
+
+ // ---------------------------------------------------------------------------
+
+ peertube(): PeerTubePlugin
+
+ webVideo(options?: any): WebVideoPlugin
+
+ p2pMediaLoader(options?: any): P2pMediaLoaderPlugin
+ hlsjs(options?: any): any
+
+ peertubeResolutions(): PeerTubeResolutionsPlugin
+
+ contextMenu(options?: ContextMenuPluginOptions): ContextMenuPlugin
+
+ bezels(): BezelsPlugin
+ peertubeMobile(): PeerTubeMobilePlugin
+ peerTubeHotkeysPlugin(options?: HotkeysOptions): PeerTubeHotkeysPlugin
+
+ stats(options?: StatsCardOptions): StatsForNerdsPlugin
+
+ storyboard(options?: StoryboardOptions): StoryboardPlugin
+
+ peertubeDock(options?: PeerTubeDockPluginOptions): PeerTubeDockPlugin
+ peertubeNSFW(options?: PeerTubeNSFWPluginOptions): PeerTubeNSFWPlugin
+
+ chapters(options?: ChaptersOptions): ChaptersPlugin
+
+ upnext(options?: UpNextPluginOptions): UpNextPlugin
+
+ playlist(options?: PlaylistPluginOptions): PlaylistPlugin
+
+ // ---------------------------------------------------------------------------
+
+ theaterEnabled: boolean
+}
+
+export declare class VideojsComponent extends Component {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export declare class VideojsMenuItem extends MenuItem {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export declare class VideojsMenu extends Menu {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export declare class VideojsMenuButton extends MenuButton {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+
+ // FIXME: typings
+ setIcon: Component['setIcon']
+}
+
+export declare class VideojsButton extends Button {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export declare class VideojsClickableComponent extends ClickableComponent {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export declare class VideojsTimeTooltip extends TimeTooltip {
+ player: () => VideojsPlayer
+ player_: VideojsPlayer
+}
+
+export type VideojsComponentOptions = ConstructorParameters[1]
+export type VideojsMenuItemOptions = ConstructorParameters[1]
+export type VideojsMenuOptions = ConstructorParameters[1]
+export type VideojsButtonOptions = ConstructorParameters[1]
+export type VideojsClickableComponentOptions = ConstructorParameters[1]
+export type VideojsMenuButtonOptions = ConstructorParameters[1]
+
+export type VideojsAutoplay = boolean | 'muted' | 'play' | 'any'
+
+export type VideojsPlayerOptions = Partial & {
+ muted?: boolean
+ controls?: boolean
+
+ autoplay?: VideojsAutoplay
+
+ poster?: string
+ preload?: 'none'
+
+ plugins?: VideoJSPluginOptions
+
+ controlBar?: {
+ children: Record
+ }
+
+ textTrackSettings?: boolean
+}
+
+export type VideojsCaptionsButton = CaptionButton & Component
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts
index 3bcf034bf..28d453aa4 100644
--- a/client/src/standalone/videos/embed.ts
+++ b/client/src/standalone/videos/embed.ts
@@ -7,7 +7,7 @@ import {
VideoPlaylistElement,
VideoState
} from '@peertube/peertube-models'
-import type { PeerTubePlayer } from '@peertube/player'
+import type { PeerTubePlayer, VideojsPlayer } from '@peertube/player'
import { TranslationsManager } from '@root-helpers/translations-manager'
import { PeerTubeServerError } from 'src/types'
import type videojs from 'video.js'
@@ -29,7 +29,7 @@ import {
import { PlayerHTML } from './shared/player-html'
export class PeerTubeEmbed {
- player: videojs.Player
+ player: VideojsPlayer
api: PeerTubeEmbedApi = null
config: HTMLServerConfig
diff --git a/client/yarn.lock b/client/yarn.lock
index 23374c599..f83b8c636 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -2265,11 +2265,6 @@
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
-"@types/video.js@^7.3.40":
- version "7.3.58"
- resolved "https://registry.yarnpkg.com/@types/video.js/-/video.js-7.3.58.tgz#7e8cdafee25c75d6eb18f530b93ac52edff53c03"
- integrity sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ==
-
"@types/which@^2.0.1":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/which/-/which-2.0.2.tgz#54541d02d6b1daee5ec01ac0d1b37cecf37db1ae"
@@ -2387,33 +2382,41 @@
"@typescript-eslint/types" "8.32.0"
eslint-visitor-keys "^4.2.0"
-"@videojs/http-streaming@2.16.3":
- version "2.16.3"
- resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-2.16.3.tgz#d9b460c3716436327dbab4b1faeb2a767f05dcef"
- integrity sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==
+"@videojs/http-streaming@^3.17.2":
+ version "3.17.2"
+ resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-3.17.2.tgz#264eaf23980f4f0e3ad918a665ac60f178f01ff8"
+ integrity sha512-VBQ3W4wnKnVKb/limLdtSD2rAd5cmHN70xoMf4OmuDd0t2kfJX04G+sfw6u2j8oOm2BXYM9E1f4acHruqKnM1g==
dependencies:
"@babel/runtime" "^7.12.5"
- "@videojs/vhs-utils" "3.0.5"
- aes-decrypter "3.1.3"
+ "@videojs/vhs-utils" "^4.1.1"
+ aes-decrypter "^4.0.2"
global "^4.4.0"
- m3u8-parser "4.8.0"
- mpd-parser "^0.22.1"
- mux.js "6.0.1"
- video.js "^6 || ^7"
+ m3u8-parser "^7.2.0"
+ mpd-parser "^1.3.1"
+ mux.js "7.1.0"
+ video.js "^7 || ^8"
-"@videojs/vhs-utils@3.0.5", "@videojs/vhs-utils@^3.0.4", "@videojs/vhs-utils@^3.0.5":
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz#665ba70d78258ba1ab977364e2fe9f4d4799c46c"
- integrity sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==
+"@videojs/vhs-utils@^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz#4d4dbf5d61a9fbd2da114b84ec747c3a483bc60d"
+ integrity sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==
dependencies:
"@babel/runtime" "^7.12.5"
global "^4.4.0"
url-toolkit "^2.2.1"
-"@videojs/xhr@2.6.0":
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/@videojs/xhr/-/xhr-2.6.0.tgz#cd897e0ad54faf497961bcce3fa16dc15a26bb80"
- integrity sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==
+"@videojs/vhs-utils@^4.1.1":
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz#44226fc5993f577490b5e08951ddc083714405cc"
+ integrity sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ global "^4.4.0"
+
+"@videojs/xhr@2.7.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@videojs/xhr/-/xhr-2.7.0.tgz#e272af6e2b5448aeb400905a5c6f4818f6b6ad47"
+ integrity sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==
dependencies:
"@babel/runtime" "^7.5.5"
global "~4.4.0"
@@ -2709,13 +2712,13 @@ addressparser@^1.0.1:
resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746"
integrity sha512-aQX7AISOMM7HFE0iZ3+YnD07oIeJqWGVnJ+ZIKaBZAk03ftmVYVqsGas/rbXKR21n4D/hKCSHypvcyOkds/xzg==
-aes-decrypter@3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-3.1.3.tgz#65ff5f2175324d80c41083b0e135d1464b12ac35"
- integrity sha512-VkG9g4BbhMBy+N5/XodDeV6F02chEk9IpgRTq/0bS80y4dzy79VH2Gtms02VXomf3HmyRe3yyJYkJ990ns+d6A==
+aes-decrypter@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-4.0.2.tgz#90648181c68878f54093920a3b44776ec2dc4914"
+ integrity sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==
dependencies:
"@babel/runtime" "^7.12.5"
- "@videojs/vhs-utils" "^3.0.5"
+ "@videojs/vhs-utils" "^4.1.1"
global "^4.4.0"
pkcs7 "^1.0.4"
@@ -5402,7 +5405,7 @@ global-prefix@^3.0.0:
kind-of "^6.0.2"
which "^1.3.1"
-global@^4.3.1, global@^4.4.0, global@~4.4.0:
+global@4.4.0, global@^4.3.1, global@^4.4.0, global@~4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
@@ -5745,11 +5748,6 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
-individual@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/individual/-/individual-2.0.0.tgz#833b097dad23294e76117a98fb38e0d9ad61bb97"
- integrity sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==
-
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -6322,11 +6320,6 @@ jszip@^3.10.1:
readable-stream "~2.3.6"
setimmediate "^1.0.5"
-keycode@^2.2.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.1.tgz#09c23b2be0611d26117ea2501c2c391a01f39eff"
- integrity sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==
-
keyv@^4.5.4:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
@@ -6575,13 +6568,13 @@ lru@^3.1.0:
dependencies:
inherits "^2.0.1"
-m3u8-parser@4.8.0:
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.8.0.tgz#4a2d591fdf6f2579d12a327081198df8af83083d"
- integrity sha512-UqA2a/Pw3liR6Df3gwxrqghCP17OpPlQj6RBPLYygf/ZSQ4MoSgvdvhvt35qV+3NaaA0FSZx93Ix+2brT1U7cA==
+m3u8-parser@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-7.2.0.tgz#9e2eb50abb8349d248cd58842367da4acabdf297"
+ integrity sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==
dependencies:
"@babel/runtime" "^7.12.5"
- "@videojs/vhs-utils" "^3.0.5"
+ "@videojs/vhs-utils" "^4.1.1"
global "^4.4.0"
magic-string@0.30.17, magic-string@^0.30.12, magic-string@^0.30.3:
@@ -6921,13 +6914,13 @@ mocha@^10.3.0:
yargs-parser "^20.2.9"
yargs-unparser "^2.0.0"
-mpd-parser@0.22.1, mpd-parser@^0.22.1:
- version "0.22.1"
- resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-0.22.1.tgz#bc2bf7d3e56368e4b0121035b055675401871521"
- integrity sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==
+mpd-parser@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-1.3.1.tgz#557b6ac27411c2c177bb01e46e14440703a414a3"
+ integrity sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==
dependencies:
"@babel/runtime" "^7.12.5"
- "@videojs/vhs-utils" "^3.0.5"
+ "@videojs/vhs-utils" "^4.0.0"
"@xmldom/xmldom" "^0.8.3"
global "^4.4.0"
@@ -6972,10 +6965,10 @@ mute-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==
-mux.js@6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-6.0.1.tgz#65ce0f7a961d56c006829d024d772902d28c7755"
- integrity sha512-22CHb59rH8pWGcPGW5Og7JngJ9s+z4XuSlYvnxhLuc58cA1WqGDQPzuG8I+sPm1/p0CdgpzVTaKW408k5DNn8w==
+mux.js@7.1.0, mux.js@^7.0.1:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-7.1.0.tgz#aba5ed55a39cb790ef4b30b2c3ea0d2630b0264e"
+ integrity sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==
dependencies:
"@babel/runtime" "^7.11.2"
global "^4.4.0"
@@ -8311,13 +8304,6 @@ run-series@^1.1.9:
resolved "https://registry.yarnpkg.com/run-series/-/run-series-1.1.9.tgz#15ba9cb90e6a6c054e67c98e1dc063df0ecc113a"
integrity sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==
-rust-result@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/rust-result/-/rust-result-1.0.0.tgz#34c75b2e6dc39fe5875e5bdec85b5e0f91536f72"
- integrity sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==
- dependencies:
- individual "^2.0.0"
-
rxjs@7.8.1:
version "7.8.1"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
@@ -8358,13 +8344,6 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-safe-json-parse@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-4.0.0.tgz#7c0f578cfccd12d33a71c0e05413e2eca171eaac"
- integrity sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==
- dependencies:
- rust-result "^1.0.0"
-
safe-push-apply@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5"
@@ -8946,16 +8925,7 @@ strict-event-emitter@^0.1.0:
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.1.0.tgz#fd742c1fb7e3852f0b964ecdae2d7666a6fb7ef8"
integrity sha512-8hSYfU+WKLdNcHVXJ0VxRXiPESalzRe7w1l8dg9+/22Ry+iZQUoQuoJ27R30GMD1TiyYINWsIEGY05WrskhSKw==
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -9036,14 +9006,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -9747,31 +9710,37 @@ vary@^1, vary@^1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
-"video.js@^6 || ^7", video.js@^7.19.2:
- version "7.21.7"
- resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.21.7.tgz#8feccac174c5f202144b2f84138352a81f263dcd"
- integrity sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==
+"video.js@^7 || ^8", video.js@^8.23.4:
+ version "8.23.4"
+ resolved "https://registry.yarnpkg.com/video.js/-/video.js-8.23.4.tgz#65876174dfcee1057102a03a847fdaa8cf346c66"
+ integrity sha512-qI0VTlYmKzEqRsz1Nppdfcaww4RSxZAq77z2oNSl3cNg2h6do5C8Ffl0KqWQ1OpD8desWXsCrde7tKJ9gGTEyQ==
dependencies:
"@babel/runtime" "^7.12.5"
- "@videojs/http-streaming" "2.16.3"
- "@videojs/vhs-utils" "^3.0.4"
- "@videojs/xhr" "2.6.0"
- aes-decrypter "3.1.3"
+ "@videojs/http-streaming" "^3.17.2"
+ "@videojs/vhs-utils" "^4.1.1"
+ "@videojs/xhr" "2.7.0"
+ aes-decrypter "^4.0.2"
+ global "4.4.0"
+ m3u8-parser "^7.2.0"
+ mpd-parser "^1.3.1"
+ mux.js "^7.0.1"
+ videojs-contrib-quality-levels "4.1.0"
+ videojs-font "4.2.0"
+ videojs-vtt.js "0.15.5"
+
+videojs-contrib-quality-levels@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz#44c2d2167114a5c8418548b10a25cb409d6cba51"
+ integrity sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==
+ dependencies:
global "^4.4.0"
- keycode "^2.2.0"
- m3u8-parser "4.8.0"
- mpd-parser "0.22.1"
- mux.js "6.0.1"
- safe-json-parse "4.0.0"
- videojs-font "3.2.0"
- videojs-vtt.js "^0.15.5"
-videojs-font@3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-3.2.0.tgz#212c9d3f4e4ec3fa7345167d64316add35e92232"
- integrity sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==
+videojs-font@4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-4.2.0.tgz#fbce803d347c565816e296f527e208dc65c9f235"
+ integrity sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==
-videojs-vtt.js@^0.15.5:
+videojs-vtt.js@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz#567776eaf2a7a928d88b148a8b401ade2406f2ca"
integrity sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==
@@ -10058,7 +10027,7 @@ workerpool@^6.5.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544"
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -10076,15 +10045,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
diff --git a/locales/fr-FR/translation.json b/locales/fr-FR/translation.json
new file mode 100644
index 000000000..e69de29bb