From 5e41fbebe70188cc1a04b40a6e21d1535115f696 Mon Sep 17 00:00:00 2001 From: Anthony Le Courric Date: Thu, 21 Dec 2023 17:11:39 +0100 Subject: [PATCH] xapiPlugin --- .../components/common/Player/createPlayer.ts | 2 +- .../common/Player/createVideojsPlayer.ts | 18 +-- .../common/Player/videojs/id3Plugin/index.ts | 2 - .../Player/videojs/p2pHlsPlugin/types.ts | 3 +- .../common/Player/videojs/xapiPlugin/index.ts | 27 ++-- .../common/Player/videojs/xapiPlugin/types.ts | 13 ++ .../lib_video/src/types/VideoPlayer.ts | 4 +- .../src/types/libs/video.js/extend.d.ts | 137 ++---------------- .../src/types/libs/video.js/extend.d.tsToto | 83 ----------- 9 files changed, 43 insertions(+), 246 deletions(-) delete mode 100644 src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.tsToto 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 d9ae48279d..8224a9449f 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'; @@ -13,14 +12,7 @@ import './videojs/transcriptPlugin'; import { Maybe } from 'lib-common'; import { Video, useP2PConfig, videoSize } from 'lib-components'; import videojs, { Player, Plugins, Source } from 'video.js'; -// import from 'video.js/dist/types/plugin'; -// import videojs, { -// VideoJsPlayer, -// VideoJsPlayerOptions, -// VideoJsPlayerPluginOptions, -// } from 'video.js'; -//import { VideoJsExtendedSourceObject } from '@lib-video/types/libs/video.js/extend'; import { isMSESupported } from '@lib-video/utils/isMSESupported'; export const createVideojsPlayer = ( @@ -48,9 +40,7 @@ export const createVideojsPlayer = ( const sources: Source[] = []; const plugins: Partial = {}; - console.log('urls.mp4', urls.mp4); - - if (isMSESupported()) { + if (!isMSESupported()) { plugins.qualitySelector = { default: '480', }; @@ -103,8 +93,6 @@ export const createVideojsPlayer = ( sources, }; - console.log('options', { options, isMSESupported: isMSESupported() }); - const player = videojs(videoNode, options) as Player; if (video.is_live) { @@ -113,8 +101,6 @@ export const createVideojsPlayer = ( onReady?.(player); - console.log('player', { player }); - // plugins initialization if (isMSESupported()) { if (isP2pQueryEnabled && isP2PEnabled) { @@ -132,7 +118,7 @@ export const createVideojsPlayer = ( //player.httpSourceSelector(); } player.id3Plugin(); - // player.xapiPlugin({ video, locale, dispatchPlayerTimeUpdate }); + player.xapiPlugin({ video, locale, dispatchPlayerTimeUpdate }); return player; }; 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 8a2d6a8a4c..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 @@ -30,8 +30,6 @@ export class id3Plugin extends PluginClass { } handleLoadedMetadata() { - console.log('handleLoadedMetadata', this.player); - const tracks = this.player.textTracks(); for (let index = 0; index < tracks.length; index++) { const track = tracks[index]; 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 9326aa14b6..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,8 +1,6 @@ import videojs, { Player } from 'video.js'; import PluginType from 'video.js/dist/types/plugin'; -const Plugin = videojs.getPlugin('plugin') as typeof PluginType; - export interface HlsData { frag: { url: string; @@ -21,6 +19,7 @@ export interface ExtendedVideoJs { }; } +const Plugin = videojs.getPlugin('plugin') as typeof PluginType; export class P2pHlsPlugin extends Plugin { declare player: Player; 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; 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 d5cedae013..c31c5ff048 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 @@ -2,9 +2,7 @@ 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 TechInit from 'video.js/dist/types/tech/tech'; - -//const PlayerC = videojsInit.getComponent('Player') as PlayerInit; +import Tech from 'video.js/dist/types/tech/tech'; import { DownloadVideoPluginOptions, @@ -12,7 +10,6 @@ import { TranscriptButtonOptions, XapiPluginOptions, } from '../../../components/common/Player/videojs/'; -// import { TranscriptPluginOptions } from '../../../components/common/Player/videojs/transcriptPlugin/types'; declare module 'video.js' { export function MiddlewareUse( @@ -25,74 +22,14 @@ declare module 'video.js' { }, ): void; - // interface VideoJsPlayerOptions { - // debug?: boolean; - // responsive?: boolean; - // } - - // interface VideoJsPlayerPluginOptions { - // httpSourceSelector?: VideoJsHttpSourceSelectorPluginOptions; - // qualitySelector?: QualitySelectorOptions; - // } - - // interface VideoJsPlayer { - // // videojs-quality-selector-plugin - // 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; - // }; - // // p2p-media-loader-hlsjs - // config: { loader: { getEngine: () => Engine } }; - // media: { currentTime: number }; - // downloadVideoPlugin: (options: DownloadVideoPluginOptions) => void; - // sharedMediaPlugin: (options: SharedLiveMediaOptions) => void; - // transcriptPlugin: (option: TranscriptPluginOptions) => void; - // p2pHlsPlugin: () => void; - // id3Plugin: () => void; - // 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; - // } - // type VideoJsPlayerOptions = typeof PlayerC.options_ & { - // autoplay?: boolean; - // controls?: boolean; - // fluid?: boolean; - // debug?: boolean; - // responsive?: boolean; - // html5: { - // vhs?: { - // limitRenditionByPlayerDimensions?: boolean; - // overrideNative?: boolean; - // useDevicePixelRatio?: boolean; - // }; - // nativeAudioTracks?: boolean; - // nativeVideoTracks?: boolean; - // hlsjsConfig?: { - // liveSyncDurationCount?: number; - // loader: Engine; - // }; - // }; - // language?: string; - // liveui?: boolean; - // plugins?: VideoJsPlayerPluginOptions; - // sources?: VideoJsExtendedSourceObject[]; - // }; - 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; @@ -109,7 +46,7 @@ declare module 'video.js' { } export class Player extends PlayerInit { - qualityLevels?: () => QualityLevels; + qualityLevels: () => QualityLevels; currentSources(): Tech & Source[]; currentSource(): Tech & Source; videojs_quality_selector_plugin_default?: string; @@ -139,7 +76,6 @@ declare module 'video.js' { el(): Element; }; }; - // p2p-media-loader-hlsjs p2pHlsPlugin: () => void; config: { loader: { getEngine: () => Engine } }; media: { currentTime: number }; @@ -149,32 +85,11 @@ declare module 'video.js' { httpSourceSelector: () => void; id3Plugin: () => void; textTracks: () => TextTrackList; - //xapiPlugin: (options: XapiPluginOptions) => void; + xapiPlugin: (options: XapiPluginOptions) => void; + remoteTextTracks: () => TextTrackList; + seeking: () => boolean; } - // function createPlayer( - // id: string | Element, - // options?: any, - // ready?: ReadyCallback, - // ): Player; - - // type Player = PlayerInit & { - // 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; - // currentSources(): Tech & VideoJsExtendedSourceObject[]; - // currentSource(): Tech & VideoJsExtendedSourceObject; - // }; - // type Player = PlayerType & { - // currentSources(): Tech & VideoJsExtendedSourceObject[]; - // currentSource(): Tech & VideoJsExtendedSourceObject; - // }; - // type Player = typeof PlayerType & { - // currentSources(): Tech & VideoJsExtendedSourceObject[]; - // currentSource(): Tech & VideoJsExtendedSourceObject; - // }; - export interface Source { src: string; type?: string; @@ -182,32 +97,11 @@ declare module 'video.js' { selected?: boolean; } - //export class Plugin extends PluginInit {} - export type Plugins = typeof PluginInit & { qualitySelector?: QualitySelectorOptions; - //player: Player; }; - - // type SourcesObjectExtended = Tech & - // { - // src: string; - // type?: string; - // size?: string; - // selected?: boolean; - // }[]; - - type Tech = TechInit; } -//type VideoJsExtendedSourceObject = { -// type SourceOption = { -// src: string; -// type?: string; -// size?: string; -// selected?: boolean; -// }; - interface QualityLevels { [index: number]: VideoJsQualityLevelsPluginRepresentation; length: number; @@ -219,17 +113,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/packages/lib_video/src/types/libs/video.js/extend.d.tsToto b/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.tsToto deleted file mode 100644 index aa6f189942..0000000000 --- a/src/frontend/packages/lib_video/src/types/libs/video.js/extend.d.tsToto +++ /dev/null @@ -1,83 +0,0 @@ -import 'video.js'; -import { Engine } from 'p2p-media-loader-hlsjs'; - -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'; - -declare module 'video.js' { - interface VideoJsPlayerOptions { - debug?: boolean; - responsive?: boolean; - } - - interface VideoJsPlayerPluginOptions { - httpSourceSelector?: VideoJsHttpSourceSelectorPluginOptions; - qualitySelector?: QualitySelectorOptions; - } - - interface VideoJsPlayer { - // videojs-quality-selector-plugin - 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; - }; - // p2p-media-loader-hlsjs - config: { loader: { getEngine: () => Engine } }; - media: { currentTime: number }; - downloadVideoPlugin: (options: DownloadVideoPluginOptions) => void; - sharedMediaPlugin: (options: SharedLiveMediaOptions) => void; - transcriptPlugin: (option: TranscriptPluginOptions) => void; - p2pHlsPlugin: () => void; - id3Plugin: () => void; - 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; - } -} - -interface QualityLevels { - [index: number]: VideoJsQualityLevelsPluginRepresentation; - length: number; - selectedIndex: number; - on: ( - event: 'change' | 'addqualitylevel' | 'removequalitylevel', - action: () => void, - ) => void; - 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; - height: number; - bitrate: number; - /* - Callback to enable/disable QualityLevel - */ - enabled: () => boolean; -}