X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;ds=sidebyside;f=client%2Fsrc%2Fassets%2Fplayer%2Fp2p-media-loader%2Fp2p-media-loader-plugin.ts;h=2eb849d2b157f34849c35b878458a0f705c4d291;hb=15a7eafb892441957ba7dd6fcbf556086fe5b2b3;hp=e86900faab957ffb09208247d5af00f17eb8c82f;hpb=a30a136c9896c656cab98d2c92cde32c534dc098;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts index e86900faa..2eb849d2b 100644 --- a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts +++ b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts @@ -1,10 +1,10 @@ -import videojs, { VideoJsPlayer } from 'video.js' -import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings' -import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs' +import * as Hlsjs from 'hls.js/dist/hls.light.js' import { Events, Segment } from 'p2p-media-loader-core' -import { timeToInt } from '../utils' +import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs' +import videojs from 'video.js' +import { timeToInt } from '@shared/core-utils' +import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings' import { registerConfigPlugin, registerSourceHandler } from './hls-plugin' -import * as Hlsjs from 'hls.js' registerConfigPlugin(videojs) registerSourceHandler(videojs) @@ -36,26 +36,33 @@ class P2pMediaLoaderPlugin extends Plugin { private networkInfoInterval: any - constructor (player: VideoJsPlayer, options?: P2PMediaLoaderPluginOptions) { + private hlsjsCurrentLevel: number + private hlsjsLevels: Hlsjs.Level[] + + constructor (player: videojs.Player, options?: P2PMediaLoaderPluginOptions) { super(player) this.options = options // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 if (!(videojs as any).Html5Hlsjs) { - const message = 'HLS.js does not seem to be supported.' - console.warn(message) + console.warn('HLS.js does not seem to be supported. Try to fallback to built in HLS.') - player.ready(() => player.trigger('error', new Error(message))) - return - } + if (!player.canPlayType('application/vnd.apple.mpegurl')) { + const message = 'Cannot fallback to built-in HLS' + console.warn(message) - // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 - (videojs as any).Html5Hlsjs.addHook('beforeinitialize', (videojsPlayer: any, hlsjs: any) => { - this.hlsjs = hlsjs - }) + player.ready(() => player.trigger('error', new Error(message))) + return + } + } else { + // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 + (videojs as any).Html5Hlsjs.addHook('beforeinitialize', (videojsPlayer: any, hlsjs: any) => { + this.hlsjs = hlsjs + }) - initVideoJsContribHlsJsPlayer(player) + initVideoJsContribHlsJsPlayer(player) + } this.startTime = timeToInt(options.startTime) @@ -64,11 +71,13 @@ class P2pMediaLoaderPlugin extends Plugin { src: options.src }) - player.one('play', () => { - player.addClass('vjs-has-big-play-button-clicked') - }) + player.ready(() => { + this.initializeCore() - player.ready(() => this.initialize()) + if ((videojs as any).Html5Hlsjs) { + this.initializePlugin() + } + }) } dispose () { @@ -78,11 +87,33 @@ class P2pMediaLoaderPlugin extends Plugin { clearInterval(this.networkInfoInterval) } + getCurrentLevel () { + return this.hlsjsLevels.find(l => l.level === this.hlsjsCurrentLevel) + } + + getLiveLatency () { + return undefined as number + // FIXME: Use latency when hls >= V1 + // return this.hlsjs.latency + } + getHLSJS () { return this.hlsjs } - private initialize () { + private initializeCore () { + this.player.one('play', () => { + this.player.addClass('vjs-has-big-play-button-clicked') + }) + + this.player.one('canplay', () => { + if (this.startTime) { + this.player.currentTime(this.startTime) + } + }) + } + + private initializePlugin () { initHlsJsPlayer(this.hlsjs) // FIXME: typings @@ -93,6 +124,10 @@ class P2pMediaLoaderPlugin extends Plugin { this.trigger('resolutionChange', { auto: this.hlsjs.autoLevelEnabled, resolutionId: data.height }) }) + this.hlsjs.on(Hlsjs.Events.MANIFEST_LOADED, (_: any, data: any) => { + this.trigger('resolutionsLoaded') + }) + this.p2pEngine.on(Events.SegmentError, (segment: Segment, err) => { console.error('Segment error.', segment, err) @@ -102,12 +137,6 @@ class P2pMediaLoaderPlugin extends Plugin { this.statsP2PBytes.numPeers = 1 + this.options.redundancyUrlManager.countBaseUrls() this.runStats() - - this.player.one('canplay', () => { - if (this.startTime) { - this.player.currentTime(this.startTime) - } - }) } private runStats () { @@ -128,6 +157,14 @@ class P2pMediaLoaderPlugin extends Plugin { this.p2pEngine.on(Events.PeerConnect, () => this.statsP2PBytes.numPeers++) this.p2pEngine.on(Events.PeerClose, () => this.statsP2PBytes.numPeers--) + this.hlsjs.on(Hlsjs.Events.MANIFEST_PARSED, (_e, manifest) => { + this.hlsjsCurrentLevel = manifest.firstLevel + this.hlsjsLevels = manifest.levels + }) + this.hlsjs.on(Hlsjs.Events.LEVEL_LOADED, (_e, level) => { + this.hlsjsCurrentLevel = level.levelId || (level as any).id + }) + this.networkInfoInterval = setInterval(() => { const p2pDownloadSpeed = this.arraySum(this.statsP2PBytes.pendingDownload) const p2pUploadSpeed = this.arraySum(this.statsP2PBytes.pendingUpload) @@ -141,6 +178,7 @@ class P2pMediaLoaderPlugin extends Plugin { this.statsHTTPBytes.pendingUpload = [] return this.player.trigger('p2pInfo', { + source: 'p2p-media-loader', http: { downloadSpeed: httpDownloadSpeed, uploadSpeed: httpUploadSpeed, @@ -153,7 +191,8 @@ class P2pMediaLoaderPlugin extends Plugin { numPeers: this.statsP2PBytes.numPeers, downloaded: this.statsP2PBytes.totalDownload, uploaded: this.statsP2PBytes.totalUpload - } + }, + bandwidthEstimate: (this.hlsjs as any).bandwidthEstimate / 8 } as PlayerNetworkInfo) }, this.CONSTANTS.INFO_SCHEDULER) }