diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index 0fb45dadd..3a1201377 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -120,15 +120,21 @@ export class AppComponent implements OnInit, OnDestroy { .getValueFromLocalStorage(STORE_KEY.Settings) .subscribe((settings: Settings) => { if (settings && Object.keys(settings).length > 0) { - this.dataService.sendIpcEvent(SETTINGS_UPDATE, settings); + // Send settings to Electron main process + if (window.electron) { + window.electron.updateSettings(settings); + } + this.translate.use(settings.language ?? this.DEFAULT_LANG); - /* if ( + + // Fetch EPG if URLs are configured + if ( + window.electron && settings.epgUrl?.length > 0 && - settings.epgUrl?.some((u) => u !== '') && - isTauri() + settings.epgUrl?.some((u) => u !== '') ) { this.epgService.fetchEpg(settings.epgUrl); - } */ + } if (settings.theme) { this.settingsService.changeTheme(settings.theme); diff --git a/apps/web/src/app/home/video-player/video-player.component.ts b/apps/web/src/app/home/video-player/video-player.component.ts index 6017108f1..8b9e635f5 100644 --- a/apps/web/src/app/home/video-player/video-player.component.ts +++ b/apps/web/src/app/home/video-player/video-player.component.ts @@ -35,7 +35,6 @@ import { import { Observable, combineLatestWith, filter, map, switchMap } from 'rxjs'; import { DataService, PlaylistsService } from 'services'; import { - CHANNEL_SET_USER_AGENT, COMPONENT_OVERLAY_REF, Channel, ERROR, @@ -44,14 +43,12 @@ import { Playlist, STORE_KEY, Settings, + SidebarView, VideoPlayer, } from 'shared-interfaces'; import { SettingsStore } from '../../services/settings-store.service'; import { SettingsComponent } from '../../settings/settings.component'; -/** Possible sidebar view options */ -export type SidebarView = 'CHANNELS' | 'PLAYLISTS'; - @Component({ imports: [ AsyncPipe, @@ -175,15 +172,13 @@ export class VideoPlayerComponent implements OnInit { ); return this.playlistsService.getPlaylist(params['id']).pipe( map((playlist) => { - this.dataService.sendIpcEvent( - CHANNEL_SET_USER_AGENT, - playlist.userAgent - ? { - referer: 'localhost', - userAgent: playlist.userAgent, - } - : {} - ); + // Set user agent if specified on playlist level + if (playlist.userAgent) { + window.electron?.setUserAgent( + playlist.userAgent, + 'localhost' + ); + } this.store.dispatch( PlaylistActions.setChannels({ diff --git a/apps/web/src/app/services/electron.service.ts b/apps/web/src/app/services/electron.service.ts index 53a567e08..64f475e56 100644 --- a/apps/web/src/app/services/electron.service.ts +++ b/apps/web/src/app/services/electron.service.ts @@ -5,7 +5,6 @@ import { DataService } from 'services'; import { AUTO_UPDATE_PLAYLISTS, AUTO_UPDATE_PLAYLISTS_RESPONSE, - EPG_GET_PROGRAM_DONE, ERROR, Playlist, PLAYLIST_PARSE_BY_URL, @@ -92,11 +91,6 @@ export class ElectronService extends DataService { console.error('VLC launch error:', error); throw error; } - } else if (type === 'EPG_FETCH_DONE') { - window.postMessage({ - type: EPG_GET_PROGRAM_DONE, - payload, - }); } else if (type === AUTO_UPDATE_PLAYLISTS) { const data = payload as Playlist[]; const playlists = await window.electron.autoUpdatePlaylists(data); diff --git a/apps/web/src/app/services/settings-store.service.ts b/apps/web/src/app/services/settings-store.service.ts index e9735cb01..6215f28dc 100644 --- a/apps/web/src/app/services/settings-store.service.ts +++ b/apps/web/src/app/services/settings-store.service.ts @@ -36,14 +36,19 @@ export const SettingsStore = signalStore( withState(DEFAULT_SETTINGS), withMethods((store, storage = inject(StorageMap)) => ({ async loadSettings() { - const stored = await firstValueFrom( - storage.get(STORE_KEY.Settings) - ); - if (stored) { - patchState(store, { - ...DEFAULT_SETTINGS, - ...(stored as Settings), - }); + try { + const stored = await firstValueFrom( + storage.get(STORE_KEY.Settings) + ); + if (stored) { + patchState(store, { + ...DEFAULT_SETTINGS, + ...(stored as Settings), + }); + } + } catch (error) { + console.error('Failed to load settings:', error); + // Keep default settings if loading fails } }, @@ -51,9 +56,14 @@ export const SettingsStore = signalStore( patchState(store, settings); // Save the complete settings object, not just the partial update const completeSettings = this.getSettings(); - await firstValueFrom( - storage.set(STORE_KEY.Settings, completeSettings) - ); + try { + await firstValueFrom( + storage.set(STORE_KEY.Settings, completeSettings) + ); + } catch (error) { + console.error('Failed to save settings:', error); + throw error; + } }, getSettings() { diff --git a/apps/web/src/app/settings/settings.component.ts b/apps/web/src/app/settings/settings.component.ts index 2f69ea6ed..136bc4ce4 100644 --- a/apps/web/src/app/settings/settings.component.ts +++ b/apps/web/src/app/settings/settings.component.ts @@ -41,8 +41,6 @@ import { DataService, EpgService, PlaylistsService } from 'services'; import { Language, Playlist, - SET_MPV_PLAYER_PATH, - SET_VLC_PLAYER_PATH, StreamFormat, Theme, VideoPlayer, @@ -165,7 +163,9 @@ export class SettingsComponent implements OnInit { * Reads the config object from the browsers * storage (indexed db) */ - ngOnInit(): void { + async ngOnInit(): Promise { + // Wait for settings to load before setting the form + await this.settingsStore.loadSettings(); this.setSettings(); this.checkAppVersion(); } @@ -252,21 +252,18 @@ export class SettingsComponent implements OnInit { onSubmit(): void { this.settingsStore.updateSettings(this.settingsForm.value).then(() => { this.applyChangedSettings(); - /* this.dataService.sendIpcEvent( - SETTINGS_UPDATE, - this.settingsForm.value - ); */ - window.electron?.updateSettings(this.settingsForm.value); - - this.dataService.sendIpcEvent( - SET_MPV_PLAYER_PATH, - this.settingsForm.value.mpvPlayerPath - ); - - this.dataService.sendIpcEvent( - SET_VLC_PLAYER_PATH, - this.settingsForm.value.mpvPlayerPath - ); + + if (window.electron) { + window.electron.updateSettings(this.settingsForm.value); + + // Set player paths if using external players + if (this.settingsForm.value.mpvPlayerPath) { + window.electron.setMpvPlayerPath(this.settingsForm.value.mpvPlayerPath); + } + if (this.settingsForm.value.vlcPlayerPath) { + window.electron.setVlcPlayerPath(this.settingsForm.value.vlcPlayerPath); + } + } }); if (this.isDialog) { this.matDialog.closeAll(); diff --git a/libs/m3u-state/src/lib/effects.ts b/libs/m3u-state/src/lib/effects.ts index 8860543ba..b15fdd71d 100644 --- a/libs/m3u-state/src/lib/effects.ts +++ b/libs/m3u-state/src/lib/effects.ts @@ -13,10 +13,8 @@ import { tap, withLatestFrom, } from 'rxjs'; -import { DataService, PlaylistsService } from 'services'; +import { DataService, EpgService, PlaylistsService } from 'services'; import { - CHANNEL_SET_USER_AGENT, - EPG_GET_PROGRAM, OPEN_MPV_PLAYER, OPEN_VLC_PLAYER, Playlist, @@ -36,6 +34,7 @@ export class PlaylistEffects { private actions$ = inject(Actions); private playlistsService = inject(PlaylistsService); private dataService = inject(DataService); + private epgService = inject(EpgService); private router = inject(Router); private snackBar = inject(MatSnackBar); private storage = inject(StorageMap); @@ -126,15 +125,19 @@ export class PlaylistEffects { ofType(PlaylistActions.setActiveChannel), map((action) => { const { channel } = action; - this.dataService.sendIpcEvent(EPG_GET_PROGRAM, { - channel, - }); + + // Use modern EPG service to get channel programs + const channelId = channel.tvg?.id || channel.name; + if (channelId) { + this.epgService.getChannelPrograms(channelId); + } + + // Set user agent if specified on channel if (channel.http['user-agent']) { - this.dataService.sendIpcEvent(CHANNEL_SET_USER_AGENT, { - referer: channel.http.referrer, - userAgent: channel.http['user-agent'], - origin: channel.http.origin, - }); + window.electron?.setUserAgent( + channel.http['user-agent'], + channel.http.referrer + ); } firstValueFrom(this.storage.get(STORE_KEY.Settings)).then( diff --git a/libs/shared/interfaces/src/lib/channel.model.ts b/libs/shared/interfaces/src/lib/channel.model.ts index fe11cb104..9ef7f065f 100755 --- a/libs/shared/interfaces/src/lib/channel.model.ts +++ b/libs/shared/interfaces/src/lib/channel.model.ts @@ -1,4 +1,4 @@ -import { Channel } from 'shared-interfaces'; +import { Channel } from './channel.interface'; /** * Creates new channel object based on the given fields @@ -15,3 +15,6 @@ export function createChannel(params: Partial): Channel { http: params.http, } as Channel; } + +/** Possible sidebar view options */ +export type SidebarView = 'CHANNELS' | 'PLAYLISTS'; diff --git a/libs/shared/interfaces/src/lib/ipc-commands.ts b/libs/shared/interfaces/src/lib/ipc-commands.ts index 84783f203..871747f70 100644 --- a/libs/shared/interfaces/src/lib/ipc-commands.ts +++ b/libs/shared/interfaces/src/lib/ipc-commands.ts @@ -2,8 +2,6 @@ export const EPG_FETCH = 'EPG:FETCH'; export const EPG_FETCH_DONE = 'EPG:FETCH_DONE'; export const EPG_ERROR = 'EPG:ERROR'; -export const EPG_GET_PROGRAM = 'EPG:GET_PROGRAM'; -export const EPG_GET_PROGRAM_DONE = 'EPG:GET_PROGRAM_DONE'; export const EPG_GET_CHANNELS = 'EPG:GET_CHANNELS'; export const EPG_GET_CHANNELS_DONE = 'EPG:GET_CHANNELS_DONE'; export const EPG_GET_CHANNELS_BY_RANGE = 'EPG:EPG_GET_CHANNELS_BY_RANGE'; @@ -21,9 +19,6 @@ export const PLAYLIST_UPDATE_RESPONSE = 'PLAYLIST:UPDATE_RESPONSE'; export const ERROR = 'ERROR'; export const OPEN_FILE = 'OPEN_FILE'; -// Channels -export const CHANNEL_SET_USER_AGENT = 'CHANNEL:SET_USER_AGENT'; - // Views export const VIEW_SETTINGS = 'VIEW:SETTINGS'; export const VIEW_ADD_PLAYLIST = 'VIEW:PLAYLISTS'; diff --git a/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts b/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts index 256482b03..27270b909 100644 --- a/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts +++ b/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts @@ -12,7 +12,7 @@ import { import Hls from 'hls.js'; import { getExtensionFromUrl } from 'm3u-utils'; import { DataService } from 'services'; -import { Channel, CHANNEL_SET_USER_AGENT } from 'shared-interfaces'; +import { Channel } from 'shared-interfaces'; /** * This component contains the implementation of HTML5 based video player @@ -74,61 +74,38 @@ export class HtmlVideoPlayerComponent implements OnInit, OnChanges, OnDestroy { const url = channel.url + (channel.epgParams ?? ''); const extension = getExtensionFromUrl(channel.url); - // Send IPC event and handle the response - this.dataService - .sendIpcEvent(CHANNEL_SET_USER_AGENT, { - userAgent: channel.http?.['user-agent'] ?? '', - referer: channel.http?.referrer ?? '', - origin: channel.http?.origin ?? '', - }) - .then(() => { - if ( - extension !== 'mp4' && - extension !== 'mpv' && - Hls && - Hls.isSupported() - ) { - console.log( - '... switching channel to ', - channel.name, - url - ); - this.hls = new Hls(); - this.hls.attachMedia(this.videoPlayer.nativeElement); - this.hls.loadSource(url); - this.handlePlayOperation(); - } else { - console.log('Using native video player...'); - this.addSourceToVideo( - this.videoPlayer.nativeElement, - url, - 'video/mp4' - ); - this.videoPlayer.nativeElement.play(); - } - }) - .catch((error: any) => { - console.error('Error setting user agent:', error); - // Continue playback even if setting user agent fails - if ( - extension !== 'mp4' && - extension !== 'mpv' && - Hls && - Hls.isSupported() - ) { - this.hls = new Hls(); - this.hls.attachMedia(this.videoPlayer.nativeElement); - this.hls.loadSource(url); - this.handlePlayOperation(); - } else { - this.addSourceToVideo( - this.videoPlayer.nativeElement, - url, - 'video/mp4' - ); - this.videoPlayer.nativeElement.play(); - } - }); + // Set user agent if specified on channel + if (channel.http?.['user-agent']) { + window.electron?.setUserAgent( + channel.http['user-agent'], + channel.http.referrer + ); + } + + if ( + extension !== 'mp4' && + extension !== 'mpv' && + Hls && + Hls.isSupported() + ) { + console.log( + '... switching channel to ', + channel.name, + url + ); + this.hls = new Hls(); + this.hls.attachMedia(this.videoPlayer.nativeElement); + this.hls.loadSource(url); + this.handlePlayOperation(); + } else { + console.log('Using native video player...'); + this.addSourceToVideo( + this.videoPlayer.nativeElement, + url, + 'video/mp4' + ); + this.videoPlayer.nativeElement.play(); + } } } diff --git a/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts b/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts index e6dc50074..172c4fecc 100644 --- a/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts +++ b/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts @@ -12,7 +12,7 @@ import { import '@yangkghjh/videojs-aspect-ratio-panel'; import videoJs from 'video.js'; import 'videojs-contrib-quality-levels'; -import 'videojs-hls-quality-selector'; +//import 'videojs-hls-quality-selector'; /** * This component contains the implementation of video player that is based on video.js library @@ -28,9 +28,9 @@ export class VjsPlayerComponent implements OnInit, OnChanges, OnDestroy { /** DOM-element reference */ @ViewChild('target', { static: true }) target!: ElementRef; /** Options of VideoJs player */ - @Input() options!: videoJs.PlayerOptions; + @Input() options!: any; /** VideoJs object */ - player!: videoJs.Player; + player!: any; @Input() volume = 1; /** @@ -56,9 +56,11 @@ export class VjsPlayerComponent implements OnInit, OnChanges, OnDestroy { }); } ); - this.player.hlsQualitySelector({ + /* this.player.hlsQualitySelector({ displayCurrentQuality: true, }); + // this one produces warning in console + */ this.player['aspectRatioPanel'](); } diff --git a/package-lock.json b/package-lock.json index 23cdbc3e9..c36eb71b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "rxjs": "7.8.2", "semver": "7.7.3", "uuid": "9.0.0", - "video.js": "7.20.3", + "video.js": "8.23.4", "videojs-contrib-quality-levels": "2.2.0", "videojs-hls-quality-selector": "1.1.4", "zone.js": "~0.15.1" @@ -11964,6 +11964,97 @@ "video.js": "^6 || ^7" } }, + "node_modules/@videojs/http-streaming/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "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" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/@videojs/http-streaming/node_modules/@videojs/http-streaming/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, + "node_modules/@videojs/http-streaming/node_modules/@videojs/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/@videojs/http-streaming/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "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" + } + }, + "node_modules/@videojs/http-streaming/node_modules/video.js/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, + "node_modules/@videojs/http-streaming/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/@videojs/vhs-utils": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", @@ -11980,9 +12071,9 @@ } }, "node_modules/@videojs/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.7.0.tgz", + "integrity": "sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", @@ -12168,7 +12259,6 @@ "version": "0.8.11", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -12202,6 +12292,82 @@ "npm": ">=5" } }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "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" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/@videojs/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "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" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -36762,85 +36928,133 @@ "optional": true }, "node_modules/video.js": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz", - "integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==", + "version": "8.23.4", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.4.tgz", + "integrity": "sha512-qI0VTlYmKzEqRsz1Nppdfcaww4RSxZAq77z2oNSl3cNg2h6do5C8Ffl0KqWQ1OpD8desWXsCrde7tKJ9gGTEyQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "2.14.3", - "@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.7.1", - "mpd-parser": "0.21.1", - "mux.js": "6.0.1", - "safe-json-parse": "4.0.0", - "videojs-font": "3.2.0", - "videojs-vtt.js": "^0.15.4" + "@videojs/http-streaming": "^3.17.2", + "@videojs/vhs-utils": "^4.1.1", + "@videojs/xhr": "2.7.0", + "aes-decrypter": "^4.0.2", + "global": "4.4.0", + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "^7.0.1", + "videojs-contrib-quality-levels": "4.1.0", + "videojs-font": "4.2.0", + "videojs-vtt.js": "0.15.5" } }, "node_modules/video.js/node_modules/@videojs/http-streaming": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz", - "integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==", + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.2.tgz", + "integrity": "sha512-VBQ3W4wnKnVKb/limLdtSD2rAd5cmHN70xoMf4OmuDd0t2kfJX04G+sfw6u2j8oOm2BXYM9E1f4acHruqKnM1g==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "3.0.5", - "aes-decrypter": "3.1.3", + "@videojs/vhs-utils": "^4.1.1", + "aes-decrypter": "^4.0.2", "global": "^4.4.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", - "mux.js": "6.0.1", - "video.js": "^6 || ^7" + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "7.1.0", + "video.js": "^7 || ^8" }, "engines": { "node": ">=8", "npm": ">=5" }, "peerDependencies": { - "video.js": "^6 || ^7" + "video.js": "^8.19.0" } }, - "node_modules/video.js/node_modules/@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", - "deprecated": "this version is no longer supported, please update to at least 0.8.*", + "node_modules/video.js/node_modules/@videojs/vhs-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz", + "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==", "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0" + }, "engines": { - "node": ">=10.0.0" + "node": ">=8", + "npm": ">=5" } }, - "node_modules/video.js/node_modules/m3u8-parser": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz", - "integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==", + "node_modules/video.js/node_modules/aes-decrypter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz", + "integrity": "sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", + "@videojs/vhs-utils": "^4.1.1", + "global": "^4.4.0", + "pkcs7": "^1.0.4" + } + }, + "node_modules/video.js/node_modules/m3u8-parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz", + "integrity": "sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.1.1", "global": "^4.4.0" } }, "node_modules/video.js/node_modules/mpd-parser": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz", - "integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.1.tgz", + "integrity": "sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "@xmldom/xmldom": "^0.7.2", + "@videojs/vhs-utils": "^4.0.0", + "@xmldom/xmldom": "^0.8.3", "global": "^4.4.0" }, "bin": { "mpd-to-m3u8-json": "bin/parse.js" } }, + "node_modules/video.js/node_modules/mux.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz", + "integrity": "sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.11.2", + "global": "^4.4.0" + }, + "bin": { + "muxjs-transmux": "bin/transmux.js" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, + "node_modules/video.js/node_modules/videojs-contrib-quality-levels": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz", + "integrity": "sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==", + "license": "Apache-2.0", + "dependencies": { + "global": "^4.4.0" + }, + "engines": { + "node": ">=16", + "npm": ">=8" + }, + "peerDependencies": { + "video.js": "^8" + } + }, "node_modules/videojs-contrib-quality-levels": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-2.2.0.tgz", @@ -36854,12 +37068,88 @@ "video.js": "^6 || ^7" } }, - "node_modules/videojs-font": { + "node_modules/videojs-contrib-quality-levels/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "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" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/@videojs/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "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" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/videojs-font": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", "license": "Apache-2.0" }, + "node_modules/videojs-font": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-4.2.0.tgz", + "integrity": "sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==", + "license": "Apache-2.0" + }, "node_modules/videojs-hls-quality-selector": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/videojs-hls-quality-selector/-/videojs-hls-quality-selector-1.1.4.tgz", @@ -36872,6 +37162,82 @@ "videojs-contrib-quality-levels": "^2.0.9" } }, + "node_modules/videojs-hls-quality-selector/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "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" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/@videojs/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^3.0.5", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "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" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/videojs-vtt.js": { "version": "0.15.5", "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", diff --git a/package.json b/package.json index 15cd59169..28096e391 100644 --- a/package.json +++ b/package.json @@ -81,9 +81,9 @@ "rxjs": "7.8.2", "semver": "7.7.3", "uuid": "9.0.0", - "video.js": "7.20.3", - "videojs-contrib-quality-levels": "2.2.0", - "videojs-hls-quality-selector": "1.1.4", + "video.js": "8.23.4", + "videojs-contrib-quality-levels": "4.1.0", + "videojs-hls-quality-selector": "2.0.0", "zone.js": "~0.15.1" }, "devDependencies": {