From 85d30ce2020428b7b64fea211ad3a99fd276e75f Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:21:44 +0100 Subject: [PATCH 01/10] =?UTF-8?q?=E2=AC=86=EF=B8=8F(lib=5Fvideo)=20upgrade?= =?UTF-8?q?=20video.js=20to=208.7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new version of video.js was available, we upgraded to it. --- CHANGELOG.md | 1 + renovate.json | 4 +- src/frontend/packages/lib_video/package.json | 8 +- .../components/common/Player/createPlayer.ts | 2 +- .../common/Player/createVideojsPlayer.ts | 31 ++- .../components/common/Player/videojs/index.ts | 6 + .../lib_video/src/types/VideoPlayer.ts | 4 +- .../src/types/libs/video.js/extend.d.ts | 128 +++++++---- src/frontend/yarn.lock | 214 +++++++++++++++--- 9 files changed, 294 insertions(+), 104 deletions(-) create mode 100644 src/frontend/packages/lib_video/src/components/common/Player/videojs/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f577955d2f..5d7e37f32f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Changed +- Upgrade video.js to version 8 (#25350) - Replace CRA by Vite (#2530) - Replace grommet Image and Grid component (#2518) - Optimized apps bundle (#2528) diff --git a/renovate.json b/renovate.json index 0c10ccbc3e..06f22894c3 100644 --- a/renovate.json +++ b/renovate.json @@ -24,9 +24,7 @@ "rehype-highlight", "rehype-raw", "remark-math", - "styled-components", - "video.js", - "videojs-contrib-quality-levels" + "styled-components" ] }, { diff --git a/src/frontend/packages/lib_video/package.json b/src/frontend/packages/lib_video/package.json index eeb0a8ae0d..4dfc3a59be 100644 --- a/src/frontend/packages/lib_video/package.json +++ b/src/frontend/packages/lib_video/package.json @@ -36,6 +36,7 @@ "@babel/polyfill": "7.12.1", "@babel/preset-env": "7.23.9", "@babel/preset-typescript": "7.23.3", + "@faker-js/faker": "*", "@formatjs/cli": "6.2.7", "@formatjs/intl": "2.10.0", "@openfun/cunningham-react": "*", @@ -59,7 +60,6 @@ "cross-env": "7.0.3", "eslint": "*", "eslint-config-marsha": "*", - "@faker-js/faker": "*", "grommet": "*", "grommet-icons": "4.12.0", "jest": "29.7.0", @@ -84,15 +84,15 @@ "dependencies": { "@streamroot/videojs-hlsjs-plugin": "1.0.16", "altamoon-robust-websocket": "1.0.3", - "m3u8-parser": "7.1.0", "lib-common": "*", "lib-components": "*", "linkifyjs": "4.1.3", + "m3u8-parser": "7.1.0", "p2p-media-loader-hlsjs": "0.6.2", "process": "0.11.10", "react-icalendar-link": "3.0.2", - "video.js": "7.21.1", - "videojs-contrib-quality-levels": "2.2.1", + "video.js": "8.7.0", + "videojs-contrib-quality-levels": "4.0.0", "videojs-http-source-selector": "1.1.6", "vtt.js": "0.13.0" }, diff --git a/src/frontend/packages/lib_video/src/components/common/Player/createPlayer.ts b/src/frontend/packages/lib_video/src/components/common/Player/createPlayer.ts index 5658a2e44c..bd5a8f298f 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/createPlayer.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/createPlayer.ts @@ -23,7 +23,7 @@ export const createPlayer: VideoPlayerCreator = ( ); const trackTextKind: { - [key in timedTextMode]?: videojs.default.TextTrack.Kind; + [key in timedTextMode]?: string; } = { [timedTextMode.CLOSED_CAPTIONING]: 'captions', [timedTextMode.SUBTITLE]: 'subtitles', diff --git a/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts b/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts index c0a5d7c09c..24b29ba192 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts @@ -1,6 +1,5 @@ import 'video.js/dist/video-js.css'; -import 'videojs-contrib-quality-levels'; import 'videojs-http-source-selector'; import './videojs/qualitySelectorPlugin'; import './videojs/p2pHlsPlugin'; @@ -12,13 +11,8 @@ import './videojs/transcriptPlugin'; import { Maybe } from 'lib-common'; import { Video, useP2PConfig, videoSize } from 'lib-components'; -import videojs, { - VideoJsPlayer, - VideoJsPlayerOptions, - VideoJsPlayerPluginOptions, -} from 'video.js'; +import videojs, { Player, Plugins, Source } from 'video.js'; -import { VideoJsExtendedSourceObject } from '@lib-video/types/libs/video.js/extend'; import { isMSESupported } from '@lib-video/utils/isMSESupported'; export const createVideojsPlayer = ( @@ -26,8 +20,8 @@ export const createVideojsPlayer = ( dispatchPlayerTimeUpdate: (time: number) => void, video: Video, locale: Maybe, - onReady: Maybe<(player: VideoJsPlayer) => void> = undefined, -): VideoJsPlayer => { + onReady: Maybe<(player: Player) => void> = undefined, +): Player => { const { isP2PEnabled } = useP2PConfig.getState(); // This property should be deleted once the feature has been // deployed, tested and approved in a production environment @@ -43,8 +37,8 @@ export const createVideojsPlayer = ( // add the video-js class name to the video attribute. videoNode.classList.add('video-js', 'vjs-big-play-centered'); - const sources: VideoJsExtendedSourceObject[] = []; - const plugins: VideoJsPlayerPluginOptions = {}; + const sources: Source[] = []; + const plugins: Partial = {}; if (!isMSESupported()) { plugins.qualitySelector = { @@ -67,7 +61,7 @@ export const createVideojsPlayer = ( }); } - const options: VideoJsPlayerOptions = { + const options = { autoplay: video.is_live, controls: true, controlBar: { @@ -98,12 +92,13 @@ export const createVideojsPlayer = ( sources, }; - const player = videojs(videoNode, options, function () { - if (video.is_live) { - this.play(); - } - onReady?.(this); - }); + const player = videojs(videoNode, options) as Player; + + if (video.is_live) { + player.play(); + } + + onReady?.(player); // plugins initialization if (isMSESupported()) { diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/index.ts new file mode 100644 index 0000000000..8c8fd00c6d --- /dev/null +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/index.ts @@ -0,0 +1,6 @@ +export type * from './downloadVideoPlugin/types'; +export type * from './p2pHlsPlugin/types'; +export type * from './qualitySelectorPlugin/types'; +export type * from './sharedMediaPlugin/types'; +export type * from './transcriptPlugin/types'; +export type * from './xapiPlugin/types'; diff --git a/src/frontend/packages/lib_video/src/types/VideoPlayer.ts b/src/frontend/packages/lib_video/src/types/VideoPlayer.ts index a648d68dd0..e5e0aab0b4 100644 --- a/src/frontend/packages/lib_video/src/types/VideoPlayer.ts +++ b/src/frontend/packages/lib_video/src/types/VideoPlayer.ts @@ -1,6 +1,6 @@ import { Maybe } from 'lib-common'; import { TimedText, Video } from 'lib-components'; -import { VideoJsPlayer } from 'video.js'; +import { Player } from 'video.js'; export interface VideoPlayerInterface { addTrack(track: TimedText, languages: { [key: string]: string }): void; @@ -17,5 +17,5 @@ export type VideoPlayerCreator = ( dispatchPlayerTimeUpdate: (time: number) => void, video: Video, locale?: string, - onReady?: (player: VideoJsPlayer) => void, + onReady?: (player: Player) => void, ) => Maybe; diff --git a/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.ts b/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.ts index aa6f189942..5228a0ebff 100644 --- a/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.ts +++ b/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.ts @@ -1,52 +1,107 @@ -import 'video.js'; import { Engine } from 'p2p-media-loader-hlsjs'; +import 'video.js'; +import PlayerInit from 'video.js/dist/types/player'; +import PluginInit from 'video.js/dist/types/plugin'; +import Tech from 'video.js/dist/types/tech/tech'; -import { DownloadVideoPluginOptions } from '../../../components/common/Player/videojs/downloadVideoPlugin/types'; -import { SharedLiveMediaOptions } from '../../../components/common/Player/videojs/sharedMediaPlugin/types'; -import { TranscriptPluginOptions } from '../../../components/common/Player/videojs/transcriptPlugin/types'; -import { XapiPluginOptions } from '../../../components/common/Player/videojs/xapiPlugin/types'; +import { + DownloadVideoPluginOptions, + SharedLiveMediaOptions, + TranscriptButtonOptions, + XapiPluginOptions, +} from '../../../components/common/Player/videojs/'; declare module 'video.js' { - interface VideoJsPlayerOptions { - debug?: boolean; - responsive?: boolean; - } + export function MiddlewareUse( + type: string, + middleware: (Player) => { + setSource: ( + playerSource: Source, + next: (err: Error | null, source: Source) => void, + ) => void; + }, + ): void; - interface VideoJsPlayerPluginOptions { - httpSourceSelector?: VideoJsHttpSourceSelectorPluginOptions; - qualitySelector?: QualitySelectorOptions; + type PlayerOptionInit = typeof PlayerInit.prototype.options_; + interface PlayerOption extends PlayerOptionInit { + autoplay?: boolean; + controls?: boolean; + debug?: boolean; + fluid?: boolean; + sources: Source[]; + plugins?: Plugins; + html5: { + vhs?: { + limitRenditionByPlayerDimensions?: boolean; + overrideNative?: boolean; + useDevicePixelRatio?: boolean; + }; + nativeAudioTracks?: boolean; + nativeVideoTracks?: boolean; + hlsjsConfig?: { + liveSyncDurationCount?: number; + loader: Engine; + }; + }; } - interface VideoJsPlayer { - // videojs-quality-selector-plugin - videojs_quality_selector_plugin_initialized: boolean; + export class Player extends PlayerInit { + qualityLevels: () => QualityLevels; + currentSources(): Tech & Source[]; + currentSource(): Tech & Source; + videojs_quality_selector_plugin_default?: string; + videojs_quality_selector_plugin_initialized?: boolean; videojs_quality_selector_plugin_is_paused?: boolean; videojs_quality_selector_plugin_currentime?: number; - videojs_quality_selector_plugin_default?: string; - cache_: { - initTime: number; + options_: PlayerOption; + lastSource_: { + player: string; + tech: string; }; - // p2p-media-loader-hlsjs + controlBar: { + el(): Element; + addChild( + name: string, + option?: + | DownloadVideoPluginOptions + | SharedLiveMediaOptions + | TranscriptButtonOptions, + ): { + el(): Element; + }; + getChild(name: string): { + el(): Element; + }; + getDescendant(name: string): { + el(): Element; + }; + }; + p2pHlsPlugin: () => void; config: { loader: { getEngine: () => Engine } }; media: { currentTime: number }; downloadVideoPlugin: (options: DownloadVideoPluginOptions) => void; sharedMediaPlugin: (options: SharedLiveMediaOptions) => void; transcriptPlugin: (option: TranscriptPluginOptions) => void; - p2pHlsPlugin: () => void; + httpSourceSelector: () => void; id3Plugin: () => void; + textTracks: () => TextTrackList; xapiPlugin: (options: XapiPluginOptions) => void; - // videojs-http-source-selector - httpSourceSelector: () => void; - qualitySelector: () => { - on( - type?: string | string[], - listener?: (...args: unknown[]) => void, - ): void; - }; - qualityLevels: () => QualityLevels; - currentSources(): VideoJsExtendedSourceObject[]; - currentSource(): VideoJsExtendedSourceObject; + remoteTextTracks: () => TextTrackList; + seeking: () => boolean; + } + + export interface Source { + src: string; + type?: string; + size?: string; + selected?: boolean; } + + export type Plugins = typeof PluginInit & { + qualitySelector?: { + default: string; + }; + }; } interface QualityLevels { @@ -60,17 +115,6 @@ interface QualityLevels { trigger: (event: string) => void; } -interface VideoJsExtendedSourceObject { - src: string; - type?: string; - size?: string; - selected?: boolean; -} - -interface VideoJsHttpSourceSelectorPluginOptions { - default: 'low' | 'high' | 'auto'; -} - interface VideoJsQualityLevelsPluginRepresentation { id: string; width: number; diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index ff13c43a9a..6d9cc6deb6 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -221,7 +221,7 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.21.0": +"@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz#b04d915ce92ce363666f816a884cdcfc9be04953" integrity sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw== @@ -1117,12 +1117,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-typescript@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.3.tgz#ce806e6cb485d468c48c4f717696719678ab0138" - integrity sha512-ogV0yWnq38CFwH20l2Afz0dfKuZBx9o/Y2Rmh5vuSS0YD1hswgEgTfyTzuSrT2q9btmHRSqYoSfwFUVaC1M1Jw== + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" + integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-create-class-features-plugin" "^7.23.6" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-typescript" "^7.23.3" @@ -1288,27 +1288,34 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.17.8", "@babel/runtime@^7.8.4": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.22.15", "@babel/runtime@^7.9.2": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" - integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.13.9": +"@babel/runtime@^7.11.2", "@babel/runtime@^7.13.9", "@babel/runtime@^7.5.5": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d" integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.12.5": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e" + integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.22.15", "@babel/runtime@^7.9.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" + integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" @@ -4923,10 +4930,10 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@videojs/http-streaming@2.15.1": - version "2.15.1" - resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-2.15.1.tgz#f559f155b2c8400af10d767d4e134971c71b1344" - integrity sha512-/uuN3bVkEeJAdrhu5Hyb19JoUo3CMys7yf2C1vUjeL1wQaZ4Oe8JrZzRrnWZ0rjvPgKfNLPXQomsRtgrMoRMJQ== +"@videojs/http-streaming@2.16.2": + version "2.16.2" + resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-2.16.2.tgz#a9be925b4e368a41dbd67d49c4f566715169b84b" + integrity sha512-etPTUdCFu7gUWc+1XcbiPr+lrhOcBu3rV5OL1M+3PDW89zskScAkkcdqYzP4pFodBPye/ydamQoTDScOnElw5A== dependencies: "@babel/runtime" "^7.12.5" "@videojs/vhs-utils" "3.0.5" @@ -4937,6 +4944,34 @@ mux.js "6.0.1" video.js "^6 || ^7" +"@videojs/http-streaming@3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-3.7.0.tgz#48ece0582602e24a3b403c2410bbcdf320bfcccd" + integrity sha512-5uLFKBL8CvD56dxxJyuxqB5CY0tdoa4SE9KbXakeiAy6iFBUEPvTr2YGLKEWvQ8Lojs1wl+FQndLdv+GO7t9Fw== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "4.0.0" + aes-decrypter "4.0.1" + global "^4.4.0" + m3u8-parser "^7.1.0" + mpd-parser "^1.2.2" + mux.js "7.0.1" + video.js "^7 || ^8" + +"@videojs/http-streaming@3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-3.8.0.tgz#6f6aaa8e7c126371f698fdc1463427439b33050b" + integrity sha512-sZ5xM6XQdAPSxXKm767J28OLCJKY5mMxu7LVAqlyEJommECylm5D/RtzqAyIWM6u4V85qsJR4Zn9k6yzAhEDOw== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "4.0.0" + aes-decrypter "4.0.1" + global "^4.4.0" + m3u8-parser "^7.1.0" + mpd-parser "^1.2.2" + mux.js "7.0.2" + 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" @@ -4946,6 +4981,15 @@ global "^4.4.0" url-toolkit "^2.2.1" +"@videojs/vhs-utils@4.0.0", "@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" @@ -5103,9 +5147,9 @@ integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== "@xmldom/xmldom@^0.8.3": - version "0.8.6" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.6.tgz#8a1524eb5bd5e965c1e3735476f0262469f71440" - integrity sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg== + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -5185,6 +5229,16 @@ aes-decrypter@3.1.3: global "^4.4.0" pkcs7 "^1.0.4" +aes-decrypter@4.0.1, aes-decrypter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-4.0.1.tgz#c1a81d0bde0e96fed0674488d2a31a6d7ab9b7a7" + integrity sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "^3.0.5" + global "^4.4.0" + pkcs7 "^1.0.4" + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -8128,7 +8182,7 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -global@^4.3.0, global@^4.3.1, global@^4.3.2, global@^4.4.0, global@~4.4.0: +global@4.4.0, global@^4.3.0, global@^4.3.1, global@^4.3.2, 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== @@ -9755,6 +9809,11 @@ katex@0.16.9, katex@^0.16.0: dependencies: commander "^8.3.0" +keycode@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" + integrity sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A== + keycode@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.1.tgz#09c23b2be0611d26117ea2501c2c391a01f39eff" @@ -10002,7 +10061,7 @@ m3u8-parser@4.8.0, m3u8-parser@^4.4.0: "@videojs/vhs-utils" "^3.0.5" global "^4.4.0" -m3u8-parser@7.1.0: +m3u8-parser@7.1.0, m3u8-parser@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-7.1.0.tgz#fa92ee22fc798150397c297152c879fe09f066c6" integrity sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ== @@ -10011,6 +10070,15 @@ m3u8-parser@7.1.0: "@videojs/vhs-utils" "^3.0.5" global "^4.4.0" +m3u8-parser@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-6.2.0.tgz#5b2f2fe103b76bd3ffc77c6b1eafc3772b1251dd" + integrity sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "^3.0.5" + global "^4.4.0" + magic-string@^0.30.3: version "0.30.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" @@ -10889,6 +10957,16 @@ mpd-parser@0.22.1, mpd-parser@^0.22.1: "@xmldom/xmldom" "^0.8.3" global "^4.4.0" +mpd-parser@^1.0.1, mpd-parser@^1.2.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-1.3.0.tgz#38c20f4d73542b4ed554158bc1f0fa571dc61388" + integrity sha512-WgeIwxAqkmb9uTn4ClicXpEQYCEduDqRKfmUdp4X8vmghKfBNXZLYpREn9eqrDx/Tf5LhzRcJLSpi4ohfV742Q== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "^4.0.0" + "@xmldom/xmldom" "^0.8.3" + global "^4.4.0" + mri@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -10912,6 +10990,22 @@ mux.js@6.0.1: "@babel/runtime" "^7.11.2" global "^4.4.0" +mux.js@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-7.0.1.tgz#745c77b0fb8aa81dbb47e96651428bfada49b08e" + integrity sha512-Omz79uHqYpMP1V80JlvEdCiOW1hiw4mBvDh9gaZEpxvB+7WYb2soZSzfuSRrK2Kh9Pm6eugQNrIpY/Bnyhk4hw== + dependencies: + "@babel/runtime" "^7.11.2" + global "^4.4.0" + +mux.js@7.0.2, mux.js@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-7.0.2.tgz#410641dc922c5d173d7ce45fbdb2bb9e2a69137c" + integrity sha512-CM6+QuyDbc0qW1OfEjkd2+jVKzTXF+z5VOKH0eZxtZtnrG/ilkW/U7l7IXGtBNLASF9sKZMcK1u669cq50Qq0A== + dependencies: + "@babel/runtime" "^7.11.2" + global "^4.4.0" + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -13375,13 +13469,33 @@ vfile@^6.0.0: unist-util-stringify-position "^4.0.0" vfile-message "^4.0.0" -video.js@7.21.1, "video.js@^6 || ^7", "video.js@^6 || ^7 || ^8", video.js@^7.0.0: - version "7.21.1" - resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.21.1.tgz#c018e1d0f0643661fcebd5ca355e9723cc82312a" - integrity sha512-AvHfr14ePDHCfW5Lx35BvXk7oIonxF6VGhSxocmTyqotkQpxwYdmt4tnQSV7MYzNrYHb0GI8tJMt20NDkCQrxg== +video.js@8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/video.js/-/video.js-8.7.0.tgz#ef8954c4d4489aa403c5116b027b7cb19c13dd0a" + integrity sha512-QAYQKsqyO/jxDed1AYdD4cEYQIuxGuqzMmfyyL3ZTgbCjo+f/XF+1Hw9aC1SZN6Wx3qDVLWKF7oB22uWST0N9w== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/http-streaming" "3.8.0" + "@videojs/vhs-utils" "^4.0.0" + "@videojs/xhr" "2.6.0" + aes-decrypter "^4.0.1" + global "4.4.0" + keycode "2.2.0" + m3u8-parser "^7.1.0" + mpd-parser "^1.2.2" + mux.js "^7.0.1" + safe-json-parse "4.0.0" + videojs-contrib-quality-levels "4.0.0" + videojs-font "4.1.0" + videojs-vtt.js "0.15.5" + +"video.js@^6 || ^7", video.js@^7.0.0: + version "7.21.5" + resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.21.5.tgz#36fcbbdeded757089a10bbb78f49c360a2d0c9d4" + integrity sha512-WRq86tXZKrThA9mK+IR+v4tIQVVvnb5LhvL71fD2AX7TxVOPdaeK1X/wyuUruBqWaOG3w2sZXoMY6HF2Jlo9qA== dependencies: "@babel/runtime" "^7.12.5" - "@videojs/http-streaming" "2.15.1" + "@videojs/http-streaming" "2.16.2" "@videojs/vhs-utils" "^3.0.4" "@videojs/xhr" "2.6.0" aes-decrypter "3.1.3" @@ -13392,9 +13506,36 @@ video.js@7.21.1, "video.js@^6 || ^7", "video.js@^6 || ^7 || ^8", video.js@^7.0.0 mux.js "6.0.1" safe-json-parse "4.0.0" videojs-font "3.2.0" - videojs-vtt.js "^0.15.4" + videojs-vtt.js "^0.15.5" -videojs-contrib-quality-levels@2.2.1, videojs-contrib-quality-levels@^2.0.4: +"video.js@^6 || ^7 || ^8", "video.js@^7 || ^8": + version "8.6.1" + resolved "https://registry.yarnpkg.com/video.js/-/video.js-8.6.1.tgz#d25f59fbf30fb21c0bcf04a1de6a98dfd137997c" + integrity sha512-CNYVJ5WWIZ7bOhbkkfcKqLGoc6WsE3Ft2RfS1lXdQTWk8UiSsPW2Ssk2JzPCA8qnIlUG9os/faCFsYWjyu4JcA== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/http-streaming" "3.7.0" + "@videojs/vhs-utils" "^4.0.0" + "@videojs/xhr" "2.6.0" + aes-decrypter "^4.0.1" + global "4.4.0" + keycode "2.2.0" + m3u8-parser "^6.0.0" + mpd-parser "^1.0.1" + mux.js "^7.0.1" + safe-json-parse "4.0.0" + videojs-contrib-quality-levels "4.0.0" + videojs-font "4.1.0" + videojs-vtt.js "0.15.5" + +videojs-contrib-quality-levels@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.0.0.tgz#faa8096594cdbfc3ccbefe8572fc20531ba23f3d" + integrity sha512-u5rmd8BjLwANp7XwuQ0Q/me34bMe6zg9PQdHfTS7aXgiVRbNTb4djcmfG7aeSrkpZjg+XCLezFNenlJaCjBHKw== + dependencies: + global "^4.4.0" + +videojs-contrib-quality-levels@^2.0.4: version "2.2.1" resolved "https://registry.yarnpkg.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-2.2.1.tgz#46bd7e1db25e6e45824dadf933b08f0c6ec724a1" integrity sha512-cnF6OGGgoC/2nUrbdz54nzPm3BpEZQzMTpyekiX6AXs8imATX2sHbrUz97xXVSHITldk/+d7ZAUrdQYJJTyuug== @@ -13407,6 +13548,11 @@ videojs-font@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.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-4.1.0.tgz#3ae1dbaac60b4f0f1c4e6f7ff9662a89df176015" + integrity sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w== + videojs-http-source-selector@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/videojs-http-source-selector/-/videojs-http-source-selector-1.1.6.tgz#073aadbea0106ba6c98d6b611094dbf8554ffa1f" @@ -13416,10 +13562,10 @@ videojs-http-source-selector@1.1.6: video.js "^7.0.0" videojs-contrib-quality-levels "^2.0.4" -videojs-vtt.js@^0.15.4: - version "0.15.4" - resolved "https://registry.yarnpkg.com/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz#5dc5aabcd82ba40c5595469bd855ea8230ca152c" - integrity sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA== +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== dependencies: global "^4.3.1" From 91451866dc84954dfc92da7682966bd232666164 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:24:57 +0100 Subject: [PATCH 02/10] =?UTF-8?q?=E2=AC=86=EF=B8=8F(lib-video)=20fork=20vi?= =?UTF-8?q?deojs-http-source-selector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The official videojs-http-source-selector on npm is not compatible with video.js version 8, this forked version is compatible. We decided to use this version in waiting the official version to be compatible with video.js version 8. --- src/frontend/packages/lib_video/package.json | 2 +- .../common/Player/createVideojsPlayer.ts | 11 ++ src/frontend/yarn.lock | 128 +++--------------- 3 files changed, 34 insertions(+), 107 deletions(-) diff --git a/src/frontend/packages/lib_video/package.json b/src/frontend/packages/lib_video/package.json index 4dfc3a59be..421a23f7a9 100644 --- a/src/frontend/packages/lib_video/package.json +++ b/src/frontend/packages/lib_video/package.json @@ -93,7 +93,7 @@ "react-icalendar-link": "3.0.2", "video.js": "8.7.0", "videojs-contrib-quality-levels": "4.0.0", - "videojs-http-source-selector": "1.1.6", + "videojs-http-source-selector": "https://github.com/FreeTubeApp/videojs-http-source-selector.git", "vtt.js": "0.13.0" }, "volta": { diff --git a/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts b/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts index 24b29ba192..af96d14aae 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/createVideojsPlayer.ts @@ -115,6 +115,17 @@ export const createVideojsPlayer = ( } player.transcriptPlugin({ video }); player.httpSourceSelector(); + + // The icon of the quality selector is not displayed with the plugin httpSourceSelector, + // so we add the class vjs-icon-cog to the element to display the icon. + player.on('loadeddata', () => { + player + .getChild('controlBar') + ?.el() + ?.getElementsByClassName('vjs-http-source-selector')[0] + ?.getElementsByClassName('vjs-menu-button')[0] + ?.classList.add('vjs-icon-cog'); + }); } player.id3Plugin(); player.xapiPlugin({ video, locale, dispatchPlayerTimeUpdate }); diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index 6d9cc6deb6..adc0711533 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -4930,20 +4930,6 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@videojs/http-streaming@2.16.2": - version "2.16.2" - resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-2.16.2.tgz#a9be925b4e368a41dbd67d49c4f566715169b84b" - integrity sha512-etPTUdCFu7gUWc+1XcbiPr+lrhOcBu3rV5OL1M+3PDW89zskScAkkcdqYzP4pFodBPye/ydamQoTDScOnElw5A== - dependencies: - "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "3.0.5" - aes-decrypter "3.1.3" - global "^4.4.0" - m3u8-parser "4.8.0" - mpd-parser "^0.22.1" - mux.js "6.0.1" - video.js "^6 || ^7" - "@videojs/http-streaming@3.7.0": version "3.7.0" resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-3.7.0.tgz#48ece0582602e24a3b403c2410bbcdf320bfcccd" @@ -4972,19 +4958,19 @@ mux.js "7.0.2" 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", "@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/vhs-utils@4.0.0", "@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== +"@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== dependencies: "@babel/runtime" "^7.12.5" global "^4.4.0" @@ -5219,16 +5205,6 @@ addr-to-ip-port@^1.0.1: resolved "https://registry.yarnpkg.com/addr-to-ip-port/-/addr-to-ip-port-1.5.4.tgz#9542b1c6219fdb8c9ce6cc72c14ee880ab7ddd88" integrity sha512-ByxmJgv8vjmDcl3IDToxL2yrWFrRtFpZAToY0f46XFXl8zS081t7El5MXIodwm7RC6DhHBRoOSMLFSPKCtHukg== -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== - dependencies: - "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "^3.0.5" - global "^4.4.0" - pkcs7 "^1.0.4" - aes-decrypter@4.0.1, aes-decrypter@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-4.0.1.tgz#c1a81d0bde0e96fed0674488d2a31a6d7ab9b7a7" @@ -8182,7 +8158,7 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -global@4.4.0, global@^4.3.0, global@^4.3.1, global@^4.3.2, global@^4.4.0, global@~4.4.0: +global@4.4.0, global@^4.3.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== @@ -9814,11 +9790,6 @@ keycode@2.2.0: resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" integrity sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A== -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.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -10052,19 +10023,19 @@ lz-string@^1.5.0: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== -m3u8-parser@4.8.0, m3u8-parser@^4.4.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.1.0, m3u8-parser@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-7.1.0.tgz#fa92ee22fc798150397c297152c879fe09f066c6" + integrity sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ== dependencies: "@babel/runtime" "^7.12.5" "@videojs/vhs-utils" "^3.0.5" global "^4.4.0" -m3u8-parser@7.1.0, m3u8-parser@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-7.1.0.tgz#fa92ee22fc798150397c297152c879fe09f066c6" - integrity sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ== +m3u8-parser@^4.4.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== dependencies: "@babel/runtime" "^7.12.5" "@videojs/vhs-utils" "^3.0.5" @@ -10947,16 +10918,6 @@ moment-mini@2.24.0: resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18" integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ== -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== - dependencies: - "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "^3.0.5" - "@xmldom/xmldom" "^0.8.3" - global "^4.4.0" - mpd-parser@^1.0.1, mpd-parser@^1.2.2: version "1.3.0" resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-1.3.0.tgz#38c20f4d73542b4ed554158bc1f0fa571dc61388" @@ -10982,14 +10943,6 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -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== - dependencies: - "@babel/runtime" "^7.11.2" - global "^4.4.0" - mux.js@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-7.0.1.tgz#745c77b0fb8aa81dbb47e96651428bfada49b08e" @@ -13489,26 +13442,7 @@ video.js@8.7.0: videojs-font "4.1.0" videojs-vtt.js "0.15.5" -"video.js@^6 || ^7", video.js@^7.0.0: - version "7.21.5" - resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.21.5.tgz#36fcbbdeded757089a10bbb78f49c360a2d0c9d4" - integrity sha512-WRq86tXZKrThA9mK+IR+v4tIQVVvnb5LhvL71fD2AX7TxVOPdaeK1X/wyuUruBqWaOG3w2sZXoMY6HF2Jlo9qA== - dependencies: - "@babel/runtime" "^7.12.5" - "@videojs/http-streaming" "2.16.2" - "@videojs/vhs-utils" "^3.0.4" - "@videojs/xhr" "2.6.0" - aes-decrypter "3.1.3" - 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" - -"video.js@^6 || ^7 || ^8", "video.js@^7 || ^8": +"video.js@^7 || ^8": version "8.6.1" resolved "https://registry.yarnpkg.com/video.js/-/video.js-8.6.1.tgz#d25f59fbf30fb21c0bcf04a1de6a98dfd137997c" integrity sha512-CNYVJ5WWIZ7bOhbkkfcKqLGoc6WsE3Ft2RfS1lXdQTWk8UiSsPW2Ssk2JzPCA8qnIlUG9os/faCFsYWjyu4JcA== @@ -13535,34 +13469,16 @@ videojs-contrib-quality-levels@4.0.0: dependencies: global "^4.4.0" -videojs-contrib-quality-levels@^2.0.4: - version "2.2.1" - resolved "https://registry.yarnpkg.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-2.2.1.tgz#46bd7e1db25e6e45824dadf933b08f0c6ec724a1" - integrity sha512-cnF6OGGgoC/2nUrbdz54nzPm3BpEZQzMTpyekiX6AXs8imATX2sHbrUz97xXVSHITldk/+d7ZAUrdQYJJTyuug== - dependencies: - global "^4.3.2" - video.js "^6 || ^7 || ^8" - -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.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-4.1.0.tgz#3ae1dbaac60b4f0f1c4e6f7ff9662a89df176015" integrity sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w== -videojs-http-source-selector@1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/videojs-http-source-selector/-/videojs-http-source-selector-1.1.6.tgz#073aadbea0106ba6c98d6b611094dbf8554ffa1f" - integrity sha512-6b5MmKTT2cVnrjtdNj4z1VO91udbXkZkTYA6LlD8WN2aHlG2rqFTmtMab4NK4nlkkkbRnm3c2q2IddL3jffLmg== - dependencies: - global "^4.3.2" - video.js "^7.0.0" - videojs-contrib-quality-levels "^2.0.4" +"videojs-http-source-selector@https://github.com/FreeTubeApp/videojs-http-source-selector.git": + version "1.1.7" + resolved "https://github.com/FreeTubeApp/videojs-http-source-selector.git#dfab172b1bd7b1f611434269c0a0bbe07bfdbb8b" -videojs-vtt.js@0.15.5, 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== From 209c63a65681e9c85b483200864a4c5c534d3e81 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:27:38 +0100 Subject: [PATCH 03/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20downloadVideoPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin downloadVideoPlugin to work with video.js version 8. --- .../components/DownloadVideoButton.ts | 22 ++++++++++++++----- .../components/DownloadVideoQualityItem.ts | 22 ++++++++++++------- .../videojs/downloadVideoPlugin/index.ts | 10 +++++---- .../videojs/downloadVideoPlugin/types.ts | 19 +++++++++++++--- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoButton.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoButton.ts index 5b1779df9e..e2c3373e95 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoButton.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoButton.ts @@ -1,13 +1,18 @@ import { videoSize } from '@lib-components/types'; import { getIntl } from 'lib-common'; import { defineMessages } from 'react-intl'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuButton from 'video.js/dist/types/menu/menu-button'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; import { DownloadVideoPluginOptions } from '../types'; import { DownloadVideoQualityItem } from './DownloadVideoQualityItem'; -const MenuButton = videojs.getComponent('MenuButton'); +const MenuButtonClass = videojs.getComponent( + 'MenuButton', +) as unknown as typeof MenuButton; const messages = defineMessages({ downloadVideoButton: { defaultMessage: 'Download Video', @@ -15,8 +20,10 @@ const messages = defineMessages({ id: 'videojs.menu.downloadVideoButton', }, }); -export class DownloadVideoButton extends MenuButton { - constructor(player: videojs.Player, options?: videojs.MenuItemOptions) { +export class DownloadVideoButton extends MenuButtonClass { + declare player: () => Player; + + constructor(player: Player, options?: MenuItemOptions) { super(player, options); this.menuButton_.setAttribute( 'title', @@ -42,7 +49,7 @@ export class DownloadVideoButton extends MenuButton { .sort((a, b) => b - a) .map( (size) => - new DownloadVideoQualityItem(this.player_, { + new DownloadVideoQualityItem(this.player(), { label: `${size}p`, src: urls[size], }), @@ -50,4 +57,7 @@ export class DownloadVideoButton extends MenuButton { } } -videojs.registerComponent('DownloadVideoButton', DownloadVideoButton); +videojs.registerComponent( + 'DownloadVideoButton', + DownloadVideoButton as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoQualityItem.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoQualityItem.ts index 90b6e4b0e7..3eeb6a6704 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoQualityItem.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/components/DownloadVideoQualityItem.ts @@ -1,22 +1,25 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuItem from 'video.js/dist/types/menu/menu-item'; import { DownloadVideoQualityItemOptions } from '../types'; -const Component = videojs.getComponent('Component'); -const MenuItem = videojs.getComponent('MenuItem'); +const MenuItemClass = videojs.getComponent( + 'MenuItem', +) as unknown as typeof MenuItem; -export class DownloadVideoQualityItem extends MenuItem { +export class DownloadVideoQualityItem extends MenuItemClass { source: string | undefined; constructor( - player: videojs.Player, - options: DownloadVideoQualityItemOptions, + player: Player, + options: Partial, ) { options.selectable = false; options.multiSelectable = false; super(player, options); - this.setAttribute('title', options.label); + this.setAttribute('title', options.label || ''); this.source = options.src; } @@ -34,4 +37,7 @@ export class DownloadVideoQualityItem extends MenuItem { } } -Component.registerComponent('DownloadVideoMenuItem', DownloadVideoQualityItem); +videojs.registerComponent( + 'DownloadVideoMenuItem', + DownloadVideoQualityItem as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/index.ts index 7eeec34ee5..4bcc2ba553 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/index.ts @@ -1,13 +1,15 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; import './components/DownloadVideoButton'; import './components/DownloadVideoQualityItem'; -import { DownloadVideoPluginOptions } from './types'; +import { DownloadVideoPluginOptions, DownloadVideoPluginType } from './types'; -const Plugin = videojs.getPlugin('plugin'); +const Plugin = videojs.getPlugin('plugin') as DownloadVideoPluginType; export class DownloadVideoPlugin extends Plugin { - constructor(player: videojs.Player, options: DownloadVideoPluginOptions) { + declare player: Player; + + constructor(player: Player, options: DownloadVideoPluginOptions) { super(player, options); const controlBar = this.player.controlBar; diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/types.ts index 43e3013178..02a720d5cc 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/downloadVideoPlugin/types.ts @@ -1,8 +1,11 @@ import { urls } from 'lib-components'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; +import PluginType from 'video.js/dist/types/plugin'; -export interface DownloadVideoQualityItemOptions - extends videojs.MenuItemOptions { +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; + +export interface DownloadVideoQualityItemOptions extends MenuItemOptions { label: string; src: string | undefined; } @@ -10,3 +13,13 @@ export interface DownloadVideoQualityItemOptions export interface DownloadVideoPluginOptions { urls: Partial; } + +export class DownloadVideoPlugin extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: DownloadVideoPluginOptions) { + super(player); + } +} + +export type DownloadVideoPluginType = typeof DownloadVideoPlugin; From d44554039f84818bd659487f7b77bcd9d177e0f2 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:29:51 +0100 Subject: [PATCH 04/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20id3Plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin id3Plugin to work with video.js version 8. --- .../common/Player/videojs/id3Plugin/index.ts | 20 +++++++++++-------- .../common/Player/videojs/id3Plugin/type.ts | 13 ++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/type.ts diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/index.ts index 35639c2eee..22c36be287 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/index.ts @@ -1,28 +1,32 @@ import { Id3VideoType, useVideo } from 'lib-components'; -import videojs from 'video.js'; -const Plugin = videojs.getPlugin('plugin'); +import videojs, { Player } from 'video.js'; + +import { id3PluginType } from './type'; type Id3MessageType = { video: Id3VideoType; }; -export class id3Plugin extends Plugin { +const PluginClass = videojs.getPlugin('plugin') as id3PluginType; + +export class id3Plugin extends PluginClass { lastReceivedVideo: Id3VideoType | undefined; videoState; + declare player: Player; - constructor(player: videojs.Player, options: unknown) { + constructor(player: Player, options: unknown) { super(player, options); this.videoState = useVideo.getState(); this.videoState.setIsWatchingVideo(true); - player.on('loadedmetadata', this.handleLoadedMetadata.bind(this)); + this.player.on('loadedmetadata', this.handleLoadedMetadata.bind(this)); - player.on('play', this.handleStart.bind(this)); + this.player.on('play', this.handleStart.bind(this)); - player.on('ended', this.handleEnded.bind(this)); + this.player.on('ended', this.handleEnded.bind(this)); - player.on('dispose', this.handleDispose.bind(this)); + this.player.on('dispose', this.handleDispose.bind(this)); } handleLoadedMetadata() { diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/type.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/type.ts new file mode 100644 index 0000000000..0b4e35af80 --- /dev/null +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/id3Plugin/type.ts @@ -0,0 +1,13 @@ +import videojs, { Player } from 'video.js'; +import PluginType from 'video.js/dist/types/plugin'; + +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; +export class id3PluginClass extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: unknown) { + super(player); + } +} + +export type id3PluginType = typeof id3PluginClass; From c6e45164913084ac8d881e473758906e3ba190a2 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:30:22 +0100 Subject: [PATCH 05/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20p2pHlsPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin p2pHlsPlugin to work with video.js version 8. --- .../Player/videojs/p2pHlsPlugin/index.ts | 19 +++++++++---------- .../Player/videojs/p2pHlsPlugin/types.ts | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/index.ts index 30db6de320..d2591eecfb 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/index.ts @@ -1,11 +1,11 @@ import videojsHlsjsSourceHandler from '@streamroot/videojs-hlsjs-plugin'; import { useJwt, useP2PConfig } from 'lib-components'; import { Byterange, Engine } from 'p2p-media-loader-hlsjs'; -import videojs, { VideoJsPlayer } from 'video.js'; +import videojs, { Player } from 'video.js'; -import { ExtendedVideoJs, HlsData } from './types'; +import { ExtendedVideoJs, HlsData, P2pHlsPluginType } from './types'; -const Plugin = videojs.getPlugin('plugin'); +const PluginClass = videojs.getPlugin('plugin') as P2pHlsPluginType; /** * A VideoJS Plugin enabling the P2P for HLS. @@ -22,8 +22,8 @@ const Plugin = videojs.getPlugin('plugin'); * necessary metadata to make `p2p-media-loader-hlsjs` works. * @class P2pPlugin */ -export class P2pHlsPlugin extends Plugin { - constructor(player: videojs.Player, options: unknown) { +export class P2pHlsPlugin extends PluginClass { + constructor(player: Player, options: unknown) { const { stunServersUrls, webTorrentServerTrackerUrls } = useP2PConfig.getState(); @@ -82,10 +82,9 @@ export class P2pHlsPlugin extends Plugin { This options will be passed to the `videojs-hlsjs-plugin` library. Example taken from: https://github.com/Novage/p2p-media-loader/blob/master/p2p-media-loader-hlsjs/demo/videojs-hlsjs-plugin.html */ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access player.options_.html5.hlsjsConfig = { liveSyncDurationCount: 7, // To have at least 7 segments in queue - loader: engine.createLoaderClass() as unknown, + loader: engine.createLoaderClass() as Engine, }; super(player, options); } @@ -96,8 +95,8 @@ export class P2pHlsPlugin extends Plugin { * @param {Engine} engine - The P2P engine * @private */ - private initHlsJsEvents(player: VideoJsPlayer, engine: Engine) { - player.on('hlsFragChanged', (_event, data: HlsData) => { + private initHlsJsEvents(player: Player, engine: Engine) { + player.on('hlsFragChanged', (_event: string, data: HlsData) => { const frag = data.frag; const byterange: Byterange = frag.byteRange?.length !== 2 @@ -114,7 +113,7 @@ export class P2pHlsPlugin extends Plugin { await engine.destroy(); }); - player.on('hlsError', (_event, errorData: { details: string }) => { + player.on('hlsError', (_event: string, errorData: { details: string }) => { if (errorData.details === 'bufferStalledError') { if (player.media === undefined) { return; diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/types.ts index 1e00be4ab9..68fff89b3a 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/p2pHlsPlugin/types.ts @@ -1,4 +1,5 @@ -import { VideoJsPlayer } from 'video.js'; +import videojs, { Player } from 'video.js'; +import PluginType from 'video.js/dist/types/plugin'; export interface HlsData { frag: { @@ -13,7 +14,18 @@ export interface ExtendedVideoJs { Html5Hlsjs: { addHook: ( action: string, - func: (videojsPlayer: VideoJsPlayer, hlsjs: VideoJsPlayer) => void, + func: (videojsPlayer: Player, hlsjs: Player) => void, ) => void; }; } + +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; +export class P2pHlsPlugin extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: unknown) { + super(player); + } +} + +export type P2pHlsPluginType = typeof P2pHlsPlugin; From 2b826358dc71e8f4f3cc31060f55d91be86967eb Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:31:00 +0100 Subject: [PATCH 06/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20qualitySelectorPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin qualitySelectorPlugin to work with video.js version 8. --- .../components/QualitySelectorMenuButton.ts | 34 +++++++++++-------- .../components/QualitySelectorMenuItem.ts | 34 +++++++++++++------ .../videojs/qualitySelectorPlugin/index.ts | 33 +++++++++--------- .../qualitySelectorPlugin/middleware.ts | 8 ++--- .../videojs/qualitySelectorPlugin/types.ts | 20 +++++++++-- 5 files changed, 80 insertions(+), 49 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuButton.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuButton.ts index 502094b8b7..396488f02c 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuButton.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuButton.ts @@ -1,11 +1,17 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import MenuButton from 'video.js/dist/types/menu/menu-button'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; import { QualitySelectorMenuItem } from './QualitySelectorMenuItem'; -const MenuButton = videojs.getComponent('MenuButton'); +const MenuButtonClass = videojs.getComponent( + 'MenuButton', +) as unknown as typeof MenuButton; -export class QualitySelectorMenuButton extends MenuButton { - constructor(player: videojs.Player, options?: videojs.MenuItemOptions) { +export class QualitySelectorMenuButton extends MenuButtonClass { + declare player: () => Player; + + constructor(player: Player, options?: MenuItemOptions) { super(player, options); } @@ -21,16 +27,16 @@ export class QualitySelectorMenuButton extends MenuButton { } createItems() { - return this.player() - .currentSources() - .map((source) => { - return new QualitySelectorMenuItem(this.player_, { - label: `${source.size ?? ''}p`, - size: source.size ?? '', - src: source.src, - type: source.type ?? '', - selected: source.src === this.player().currentSource().src, - }); + const player = this.player(); + + return player.options_.sources.map((source) => { + return new QualitySelectorMenuItem(player, { + label: `${source.size ?? ''}p`, + size: source.size ?? '', + src: source.src, + type: source.type ?? '', + selected: player.currentSrc().includes(source.src), }); + }); } } diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuItem.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuItem.ts index 2f7b4ce8aa..d25e356472 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuItem.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/components/QualitySelectorMenuItem.ts @@ -1,18 +1,26 @@ -import videojs from 'video.js'; +import videojs, { Player, Source } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuItem from 'video.js/dist/types/menu/menu-item'; import { Events, QualitySelectorMenuItemOptions } from '../types'; -const Component = videojs.getComponent('Component'); -const MenuItem = videojs.getComponent('MenuItem'); +const MenuItemClass = videojs.getComponent( + 'MenuItem', +) as unknown as typeof MenuItem; -export class QualitySelectorMenuItem extends MenuItem { - constructor(player: videojs.Player, options: QualitySelectorMenuItemOptions) { - options.selectable = true; - options.multiSelectable = false; +interface MenuItemSources extends Source { + label: string; +} - super(player, options); +export class QualitySelectorMenuItem extends MenuItemClass { + constructor(player: Player, options: MenuItemSources) { + super(player, { + ...options, + selectable: true, + multiSelectable: false, + }); - this.on(player, Events.QUALITY_REQUESTED, this.qualityRequested.bind(this)); + player.on(Events.QUALITY_REQUESTED, this.qualityRequested.bind(this)); } qualityRequested( @@ -23,11 +31,15 @@ export class QualitySelectorMenuItem extends MenuItem { this.selected(selectedItem.src === currentItem.src); } - handleClick(event: videojs.EventTarget.Event) { + handleClick(event: Event) { const selected = this.options_ as QualitySelectorMenuItemOptions; super.handleClick(event); this.player().trigger(Events.QUALITY_REQUESTED, selected); } } -Component.registerComponent('QualitySelectorMenuItem', QualitySelectorMenuItem); + +videojs.registerComponent( + 'QualitySelectorMenuItem', + QualitySelectorMenuItem as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/index.ts index 4e91416dca..8ac285b8b7 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/index.ts @@ -1,36 +1,35 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; import { QualitySelectorMenuButton } from './components/QualitySelectorMenuButton'; -import { QualitySelectorMenuItem } from './components/QualitySelectorMenuItem'; import { Events, QualitySelectorMenuItemOptions, QualitySelectorOptions, + QualitySelectorType, } from './types'; import './middleware'; -const Plugin = videojs.getPlugin('plugin'); +const PluginClass = videojs.getPlugin('plugin') as QualitySelectorType; -export class QualitySelector extends Plugin { - constructor(player: videojs.Player, options?: QualitySelectorOptions) { +export class QualitySelector extends PluginClass { + declare player: Player; + + constructor(player: Player, options?: QualitySelectorOptions) { super(player, options); videojs.registerComponent( 'QualitySelectorMenuButton', - QualitySelectorMenuButton, - ); - videojs.registerComponent( - 'QualitySelectorMenuItem', - QualitySelectorMenuItem, + QualitySelectorMenuButton as unknown as typeof Component, ); + if (options?.default) { - player.videojs_quality_selector_plugin_default = options.default; + this.player.videojs_quality_selector_plugin_default = options.default; } - this.on(player, 'loadedmetadata', this.initPlugin.bind(this)); - this.on(player, Events.QUALITY_REQUESTED, this.changeQuality.bind(this)); - this.on( - player, + this.player.on('loadedmetadata', this.initPlugin.bind(this)); + this.player.on(Events.QUALITY_REQUESTED, this.changeQuality.bind(this)); + this.player.on( Events.PLAYER_SOURCES_CHANGED, this.sourcesChanged.bind(this), ); @@ -40,6 +39,7 @@ export class QualitySelector extends Plugin { if (this.player.videojs_quality_selector_plugin_initialized) { return; } + const controlBar = this.player.controlBar; const fullscreenToggle = controlBar.getChild('fullscreenToggle')?.el(); controlBar @@ -55,12 +55,13 @@ export class QualitySelector extends Plugin { _event: Events, selectedSource: QualitySelectorMenuItemOptions, ) { - const sources = this.player.currentSources(); this.player.videojs_quality_selector_plugin_is_paused = this.player.paused(); + this.player.videojs_quality_selector_plugin_currentime = this.player.currentTime(); + const { sources } = this.player.options_; const newSources = sources.map((source) => { source.selected = source.src === selectedSource.src; diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/middleware.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/middleware.ts index a322b1b869..ea67d5087e 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/middleware.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/middleware.ts @@ -1,15 +1,13 @@ import { Maybe } from 'lib-common'; -import videojs from 'video.js'; - -import { VideoJsExtendedSourceObject } from '@lib-video/types/libs/video.js/extend'; +import videojs, { MiddlewareUse, Player, Source } from 'video.js'; import { Events } from './types'; -videojs.use('video/mp4', (player: videojs.Player) => ({ +(videojs.use as typeof MiddlewareUse)('video/mp4', (player: Player) => ({ setSource: (playerSource, next) => { const sources = player.currentSources(); - let selectedSource: Maybe; + let selectedSource: Maybe; selectedSource = sources.find((source) => source.selected); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/types.ts index de3bb57085..400210c675 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/qualitySelectorPlugin/types.ts @@ -1,12 +1,15 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import MenuItem from 'video.js/dist/types/menu/menu-item'; +import PluginType from 'video.js/dist/types/plugin'; + +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; export enum Events { QUALITY_REQUESTED = 'qualityRequested', PLAYER_SOURCES_CHANGED = 'playerSourcesChanged', } -export interface QualitySelectorMenuItemOptions - extends videojs.MenuItemOptions { +export interface QualitySelectorMenuItemOptions extends MenuItem { label: string; size: string; src: string; @@ -16,3 +19,14 @@ export interface QualitySelectorMenuItemOptions export interface QualitySelectorOptions { default?: string; } + +export class QualitySelector extends Plugin { + qualitySelector?: QualitySelectorOptions; + declare player: Player; + + constructor(player: Player, _options?: QualitySelectorOptions) { + super(player); + } +} + +export type QualitySelectorType = typeof QualitySelector; From 61cd5b15e1e6b98e50be0e0bb8d2ac6460962617 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:31:26 +0100 Subject: [PATCH 07/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20sharedMediaPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin sharedMediaPlugin to work with video.js version 8. --- .../components/SharedMediaButton.ts | 22 ++++++++++++++----- .../components/SharedMediaItem.ts | 20 +++++++++++------ .../Player/videojs/sharedMediaPlugin/index.ts | 10 ++++----- .../Player/videojs/sharedMediaPlugin/types.ts | 17 ++++++++++++-- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaButton.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaButton.ts index 19ccc13ef5..5e7f7bcaf0 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaButton.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaButton.ts @@ -1,12 +1,17 @@ import { getIntl } from 'lib-common'; import { defineMessages } from 'react-intl'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuButton from 'video.js/dist/types/menu/menu-button'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; import { SharedLiveMediaOptions } from '../types'; import { SharedMediaItem } from './SharedMediaItem'; -const MenuButton = videojs.getComponent('MenuButton'); +const MenuButtonClass = videojs.getComponent( + 'MenuButton', +) as unknown as typeof MenuButton; const messages = defineMessages({ sharedMediaButton: { @@ -16,8 +21,10 @@ const messages = defineMessages({ }, }); -export class SharedMediaButton extends MenuButton { - constructor(player: videojs.Player, options?: videojs.MenuItemOptions) { +export class SharedMediaButton extends MenuButtonClass { + declare player: () => Player; + + constructor(player: Player, options?: MenuItemOptions) { super(player, options); this.menuButton_.setAttribute( 'title', @@ -39,7 +46,7 @@ export class SharedMediaButton extends MenuButton { createItems() { const { sharedLiveMedias } = this.options_ as SharedLiveMediaOptions; return sharedLiveMedias.map((item) => { - return new SharedMediaItem(this.player_, { + return new SharedMediaItem(this.player(), { label: item.title || '', src: item.urls ? item.urls.media : undefined, }); @@ -47,4 +54,7 @@ export class SharedMediaButton extends MenuButton { } } -videojs.registerComponent('SharedMediaButton', SharedMediaButton); +videojs.registerComponent( + 'SharedMediaButton', + SharedMediaButton as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaItem.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaItem.ts index f48d2efd5b..48fff3e0bc 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaItem.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/components/SharedMediaItem.ts @@ -1,19 +1,22 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuItem from 'video.js/dist/types/menu/menu-item'; import { SharedLiveMediaItemOptions } from '../types'; -const Component = videojs.getComponent('Component'); -const MenuItem = videojs.getComponent('MenuItem'); +const MenuItemClass = videojs.getComponent( + 'MenuItem', +) as unknown as typeof MenuItem; -export class SharedMediaItem extends MenuItem { +export class SharedMediaItem extends MenuItemClass { source: string | undefined; - constructor(player: videojs.Player, options: SharedLiveMediaItemOptions) { + constructor(player: Player, options: Partial) { options.selectable = false; options.multiSelectable = false; super(player, options); - this.setAttribute('title', options.label); + this.setAttribute('title', options.label || ''); this.source = options.src; } @@ -30,4 +33,7 @@ export class SharedMediaItem extends MenuItem { } } -Component.registerComponent('SharedMediaItem', SharedMediaItem); +videojs.registerComponent( + 'SharedMediaItem', + SharedMediaItem as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/index.ts index 3690432300..674c0af372 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/index.ts @@ -1,13 +1,13 @@ -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; import './components/SharedMediaButton'; import './components/SharedMediaItem'; -import { SharedLiveMediaOptions } from './types'; +import { SharedLiveMediaOptions, SharedLiveMediaType } from './types'; -const Plugin = videojs.getPlugin('plugin'); +const PluginClass = videojs.getPlugin('plugin') as SharedLiveMediaType; -export class SharedMediaPlugin extends Plugin { - constructor(player: videojs.Player, options: SharedLiveMediaOptions) { +export class SharedMediaPlugin extends PluginClass { + constructor(player: Player, options: SharedLiveMediaOptions) { super(player, options); const controlBar = this.player.controlBar; diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/types.ts index ec60dcb1fe..4bff9ad79a 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/sharedMediaPlugin/types.ts @@ -1,7 +1,9 @@ import { SharedLiveMedia } from '@lib-components/types/tracks'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; +import PluginType from 'video.js/dist/types/plugin'; -export interface SharedLiveMediaItemOptions extends videojs.MenuItemOptions { +export interface SharedLiveMediaItemOptions extends MenuItemOptions { label: string; src: string | undefined; } @@ -9,3 +11,14 @@ export interface SharedLiveMediaItemOptions extends videojs.MenuItemOptions { export interface SharedLiveMediaOptions { sharedLiveMedias: SharedLiveMedia[]; } + +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; +export class SharedLiveMediaClass extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: SharedLiveMediaOptions) { + super(player); + } +} + +export type SharedLiveMediaType = typeof SharedLiveMediaClass; From 82b83bd5a6709a57573e404c5ebc9c9c6a6ce187 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:31:51 +0100 Subject: [PATCH 08/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20transcriptPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin transcriptPlugin to work with video.js version 8. --- .../components/TranscriptButton.ts | 24 ++++++++++---- .../components/TranscriptItem.ts | 32 ++++++++++++------- .../Player/videojs/transcriptPlugin/index.ts | 10 +++--- .../Player/videojs/transcriptPlugin/types.ts | 18 +++++++++-- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptButton.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptButton.ts index 307751fa48..0936d51996 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptButton.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptButton.ts @@ -1,12 +1,17 @@ import { getIntl } from 'lib-common'; import { defineMessages } from 'react-intl'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuButton from 'video.js/dist/types/menu/menu-button'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; import { TranscriptButtonOptions } from '../types'; import { TranscriptItem } from './TranscriptItem'; -const MenuButton = videojs.getComponent('MenuButton'); +const MenuButtonClass = videojs.getComponent( + 'MenuButton', +) as unknown as typeof MenuButton; const messages = defineMessages({ transcriptButton: { @@ -16,8 +21,10 @@ const messages = defineMessages({ }, }); -export class TranscriptButton extends MenuButton { - constructor(player: videojs.Player, options: videojs.MenuButtonOptions) { +export class TranscriptButton extends MenuButtonClass { + declare player: () => Player; + + constructor(player: Player, options: MenuItemOptions) { super(player, options); this.menuButton_.setAttribute( 'title', @@ -35,12 +42,12 @@ export class TranscriptButton extends MenuButton { return []; } return [ - new TranscriptItem(this.player_, { + new TranscriptItem(this.player(), { label: 'transcript off', transcript: null, }), ...transcripts.map((item) => { - return new TranscriptItem(this.player_, { + return new TranscriptItem(this.player(), { label: item.language, transcript: item, }); @@ -49,4 +56,7 @@ export class TranscriptButton extends MenuButton { } } -videojs.registerComponent('TranscriptButton', TranscriptButton); +videojs.registerComponent( + 'TranscriptButton', + TranscriptButton as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptItem.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptItem.ts index 3612514734..167724bb7a 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptItem.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/components/TranscriptItem.ts @@ -1,21 +1,25 @@ -import { TimedTextTranscript, useTimedTextTrack } from 'lib-components'; -import videojs from 'video.js'; +import { useTimedTextTrack } from 'lib-components'; +import videojs, { Player } from 'video.js'; +import Component from 'video.js/dist/types/component'; +import MenuItem from 'video.js/dist/types/menu/menu-item'; -import { SharedLiveMediaItemOptions } from '../types'; +import { TranscriptItemOptions } from '../types'; import { TranscriptButton } from './TranscriptButton'; -const Component = videojs.getComponent('Component'); -const MenuItem = videojs.getComponent('MenuItem'); +const MenuItemClass = videojs.getComponent( + 'MenuItem', +) as unknown as typeof MenuItem; -export class TranscriptItem extends MenuItem { - transcript: TimedTextTranscript | null; +export class TranscriptItem extends MenuItemClass { + declare player: () => Player; + transcript?: TranscriptItemOptions['transcript']; - constructor(player: videojs.Player, options: SharedLiveMediaItemOptions) { + constructor(player: Player, options: Partial) { options.selectable = true; options.multiSelectable = false; super(player, options); - this.setAttribute('title', options.label); + this.setAttribute('title', options.label || ''); this.transcript = options.transcript; this.selected( useTimedTextTrack.getState().selectedTranscript === this.transcript, @@ -36,8 +40,14 @@ export class TranscriptItem extends MenuItem { } this.selected(true); - useTimedTextTrack.getState().setSelectedTranscript(this.transcript); + + if (this.transcript) { + useTimedTextTrack.getState().setSelectedTranscript(this.transcript); + } } } -Component.registerComponent('TranscriptItem', TranscriptItem); +videojs.registerComponent( + 'TranscriptItem', + TranscriptItem as unknown as typeof Component, +); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/index.ts index 180a990971..cc9495c20b 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/index.ts @@ -3,20 +3,20 @@ import { timedTextMode, useTimedTextTrack, } from 'lib-components'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; import './components/TranscriptButton'; import './components/TranscriptItem'; import { useTranscriptTimeSelector } from '@lib-video/hooks/useTranscriptTimeSelector'; -import { TranscriptPluginOptions } from './types'; +import { TranscriptPluginOptions, TranscriptPluginType } from './types'; -const Plugin = videojs.getPlugin('plugin'); +const PluginClass = videojs.getPlugin('plugin') as TranscriptPluginType; -export class TranscriptPlugin extends Plugin { +export class TranscriptPlugin extends PluginClass { unsubscribeTranscriptTimeSelector: () => void; - constructor(player: videojs.Player, options: TranscriptPluginOptions) { + constructor(player: Player, options: TranscriptPluginOptions) { super(player); const { video } = options; const timedTextTracks = useTimedTextTrack.getState().getTimedTextTracks(); diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/types.ts index 96f60d010e..a45af1c615 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/transcriptPlugin/types.ts @@ -1,8 +1,12 @@ import { Nullable } from 'lib-common'; import { TimedTextTranscript, Video } from 'lib-components'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; +import MenuItemOptions from 'video.js/dist/types/menu/menu-item'; +import PluginType from 'video.js/dist/types/plugin'; -export interface SharedLiveMediaItemOptions extends videojs.MenuItemOptions { +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; + +export interface TranscriptItemOptions extends MenuItemOptions { label: string; transcript: Nullable; } @@ -14,3 +18,13 @@ export interface TranscriptPluginOptions { export interface TranscriptButtonOptions { transcripts: TimedTextTranscript[]; } + +export class TranscriptPlugin extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: TranscriptPluginOptions) { + super(player); + } +} + +export type TranscriptPluginType = typeof TranscriptPlugin; From cee17f30804a666b5a23734522e54d21ae6a7238 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:32:14 +0100 Subject: [PATCH 09/10] =?UTF-8?q?=E2=99=BB=EF=B8=8F(lib-video)=20adapt=20p?= =?UTF-8?q?lugin=20video.js=20xapiPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We adapt the plugin xapiPlugin to work with video.js version 8. --- .../common/Player/videojs/xapiPlugin/index.ts | 27 ++++++++++--------- .../common/Player/videojs/xapiPlugin/types.ts | 13 +++++++++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/index.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/index.ts index d2d70ef83e..eeb26426cb 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/index.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/index.ts @@ -9,7 +9,7 @@ import { useCurrentSession, useJwt, } from 'lib-components'; -import videojs from 'video.js'; +import videojs, { Player } from 'video.js'; import { pushAttendance } from '@lib-video/api/pushAttendance'; import { useAttendance } from '@lib-video/hooks/useAttendance'; @@ -19,11 +19,11 @@ import { isMSESupported } from '@lib-video/utils/isMSESupported'; import { Events } from '../qualitySelectorPlugin/types'; -import { XapiPluginOptions } from './types'; +import { XapiPluginOptions, XapiPluginType } from './types'; -const Plugin = videojs.getPlugin('plugin'); +const PluginClass = videojs.getPlugin('plugin') as XapiPluginType; -export class xapiPlugin extends Plugin { +export class xapiPlugin extends PluginClass { private xapiStatement: VideoXAPIStatementInterface; video: Video; currentTime: number; @@ -34,8 +34,9 @@ export class xapiPlugin extends Plugin { hasAttendance: boolean; currentTrack: Nullable; locale: Maybe; + declare player: Player; - constructor(player: videojs.Player, options: XapiPluginOptions) { + constructor(player: Player, options: XapiPluginOptions) { super(player, options); this.video = options.video; @@ -74,20 +75,20 @@ export class xapiPlugin extends Plugin { player.on('canplaythrough', this.initialize.bind(this)); player.on('play', () => { this.xapiStatement.played({ - time: player.currentTime(), + time: player.currentTime() || 0, }); }); player.on('pause', () => { this.xapiStatement.paused({ - time: player.currentTime(), + time: player.currentTime() || 0, }); }); player.on('timeupdate', () => { if (this.isInitialized && !player.seeking()) { - this.currentTime = player.currentTime(); + this.currentTime = player.currentTime() || 0; } - options.dispatchPlayerTimeUpdate(player.currentTime()); + options.dispatchPlayerTimeUpdate(player.currentTime() || 0); }); player.on('seeking', () => { @@ -102,7 +103,7 @@ export class xapiPlugin extends Plugin { this.hasSeeked = false; this.xapiStatement.seeked({ timeFrom: this.seekingAt, - timeTo: player.currentTime(), + timeTo: player.currentTime() || 0, }); }); player.on('fullscreenchange', this.interacted.bind(this)); @@ -122,7 +123,7 @@ export class xapiPlugin extends Plugin { return; } - this.xapiStatement.terminated({ time: player.currentTime() }); + this.xapiStatement.terminated({ time: player.currentTime() || 0 }); if (this.interval) { player.clearInterval(this.interval); @@ -165,7 +166,7 @@ export class xapiPlugin extends Plugin { const contextExtensions = { ccSubtitleEnabled: this.currentTrack !== null, fullScreen: this.player.isFullscreen(), - length: this.player.duration(), + length: this.player.duration() || 0, speed: `${this.player.playbackRate()}x`, volume: this.player.volume(), }; @@ -215,7 +216,7 @@ export class xapiPlugin extends Plugin { } this.xapiStatement.interacted( - { time: this.player.currentTime() }, + { time: this.player.currentTime() || 0 }, contextExtensions, ); } diff --git a/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/types.ts b/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/types.ts index c28e433897..c92e3006fc 100644 --- a/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/types.ts +++ b/src/frontend/packages/lib_video/src/components/common/Player/videojs/xapiPlugin/types.ts @@ -1,8 +1,21 @@ import { Maybe } from 'lib-common'; import { Video } from 'lib-components'; +import videojs, { Player } from 'video.js'; +import PluginType from 'video.js/dist/types/plugin'; export interface XapiPluginOptions { video: Video; locale: Maybe; dispatchPlayerTimeUpdate: (time: number) => void; } + +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; +export class XapiPlugin extends Plugin { + declare player: Player; + + constructor(player: Player, _options?: XapiPluginOptions) { + super(player); + } +} + +export type XapiPluginType = typeof XapiPlugin; From 0ac7324c44ec177af6dd8433f34ab4ad95521747 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Fri, 22 Dec 2023 12:32:58 +0100 Subject: [PATCH 10/10] =?UTF-8?q?=E2=9C=85(frontend)=20adapt=20babel=20to?= =?UTF-8?q?=20interpret=20declare=20keyword=20in=20typescript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we adapted the class in the plugin video.js, we use the keyword "declare", which is not interpreted by babel. We need to add a plugin to babel to interpret this keyword correctly. --- src/frontend/apps/lti_site/babel.config.js | 6 ++++++ src/frontend/apps/lti_site/package.json | 1 + src/frontend/apps/standalone_site/babel.config.js | 6 ++++++ src/frontend/apps/standalone_site/package.json | 1 + src/frontend/package.json | 1 + src/frontend/packages/lib_video/babel.config.js | 6 ++++++ src/frontend/packages/lib_video/package.json | 1 + src/frontend/yarn.lock | 2 +- 8 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/frontend/apps/lti_site/babel.config.js b/src/frontend/apps/lti_site/babel.config.js index f2000080a6..f04423b09b 100644 --- a/src/frontend/apps/lti_site/babel.config.js +++ b/src/frontend/apps/lti_site/babel.config.js @@ -1,5 +1,11 @@ module.exports = { plugins: [ + [ + '@babel/plugin-transform-typescript', + { + allowDeclareFields: true, + }, + ], [ 'react-intl', { diff --git a/src/frontend/apps/lti_site/package.json b/src/frontend/apps/lti_site/package.json index 2ffb14e735..9c983eb1c8 100644 --- a/src/frontend/apps/lti_site/package.json +++ b/src/frontend/apps/lti_site/package.json @@ -25,6 +25,7 @@ "@babel/core": "7.23.9", "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/plugin-transform-typescript": "*", "@babel/polyfill": "7.12.1", "@babel/preset-env": "7.23.9", "@babel/preset-react": "7.23.3", diff --git a/src/frontend/apps/standalone_site/babel.config.js b/src/frontend/apps/standalone_site/babel.config.js index 7d64c7ff5f..340c2acdd4 100644 --- a/src/frontend/apps/standalone_site/babel.config.js +++ b/src/frontend/apps/standalone_site/babel.config.js @@ -12,6 +12,12 @@ module.exports = babelJest.createTransformer({ ast: true, }, ], + [ + '@babel/plugin-transform-typescript', + { + allowDeclareFields: true, + }, + ], 'babel-plugin-import-remove-resource-query', '@babel/plugin-syntax-dynamic-import', 'babel-plugin-transform-vite-meta-env', diff --git a/src/frontend/apps/standalone_site/package.json b/src/frontend/apps/standalone_site/package.json index ccf5d5689f..b6e9577798 100644 --- a/src/frontend/apps/standalone_site/package.json +++ b/src/frontend/apps/standalone_site/package.json @@ -39,6 +39,7 @@ "devDependencies": { "@babel/core": "7.23.9", "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/plugin-transform-typescript": "*", "@babel/preset-env": "7.23.9", "@babel/preset-typescript": "7.23.3", "@testing-library/jest-dom": "*", diff --git a/src/frontend/package.json b/src/frontend/package.json index fc7eeba0fb..822793b93d 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -40,6 +40,7 @@ }, "resolutions": { "@babel/plugin-proposal-private-property-in-object": "7.21.11", + "@babel/plugin-transform-typescript": "7.23.6", "@codemirror/lang-markdown": "6.2.4", "@codemirror/language": "6.10.1", "@codemirror/language-data": "6.4.1", diff --git a/src/frontend/packages/lib_video/babel.config.js b/src/frontend/packages/lib_video/babel.config.js index 4bfd2bff38..6419139179 100644 --- a/src/frontend/packages/lib_video/babel.config.js +++ b/src/frontend/packages/lib_video/babel.config.js @@ -8,6 +8,12 @@ module.exports = { ast: true, }, ], + [ + '@babel/plugin-transform-typescript', + { + allowDeclareFields: true, + }, + ], '@babel/proposal-class-properties', '@babel/plugin-syntax-dynamic-import', '@babel/plugin-transform-runtime', diff --git a/src/frontend/packages/lib_video/package.json b/src/frontend/packages/lib_video/package.json index 421a23f7a9..fdb283aea8 100644 --- a/src/frontend/packages/lib_video/package.json +++ b/src/frontend/packages/lib_video/package.json @@ -33,6 +33,7 @@ "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/plugin-syntax-dynamic-import": "7.8.3", "@babel/plugin-transform-runtime": "7.23.9", + "@babel/plugin-transform-typescript": "*", "@babel/polyfill": "7.12.1", "@babel/preset-env": "7.23.9", "@babel/preset-typescript": "7.23.3", diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock index adc0711533..a9af785795 100644 --- a/src/frontend/yarn.lock +++ b/src/frontend/yarn.lock @@ -1116,7 +1116,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typescript@^7.23.3": +"@babel/plugin-transform-typescript@*", "@babel/plugin-transform-typescript@7.23.6", "@babel/plugin-transform-typescript@^7.23.3": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==