X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fassets%2Fplayer%2Fpeertube-videojs-plugin.ts;h=90ca8f9faaeb2df12956cc1b74f6a69c6d3f5dbd;hb=64cc5e8575fda47b281ae20abf0020e27fc8ce7c;hp=36b80bd72b543b636cd54f99931552e8cf13de02;hpb=0491173a61aed66205c017e0d7e0503ea316c144;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index 36b80bd72..90ca8f9fa 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts @@ -3,11 +3,12 @@ import * as WebTorrent from 'webtorrent' import { VideoFile } from '../../../../shared/models/videos/video.model' import { renderVideo } from './video-renderer' import './settings-menu-button' -import { PeertubePluginOptions, VideoJSCaption, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings' +import { PeertubePluginOptions, UserWatching, VideoJSCaption, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings' import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution } from './utils' import * as CacheChunkStore from 'cache-chunk-store' import { PeertubeChunkStore } from './peertube-chunk-store' import { + getStoredWebTorrentPolicy, getAverageBandwidthInStore, getStoredMute, getStoredVolume, @@ -32,7 +33,8 @@ class PeerTubePlugin extends Plugin { AUTO_QUALITY_THRESHOLD_PERCENT: 30, // Bandwidth should be 30% more important than a resolution bitrate to change to it AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds after having change the resolution before another check AUTO_QUALITY_HIGHER_RESOLUTION_DELAY: 5000, // Buffering higher resolution during 5 seconds - BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5 // Last 5 seconds to build average bandwidth + BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5, // Last 5 seconds to build average bandwidth + USER_WATCHING_VIDEO_INTERVAL: 5000 // Every 5 seconds, notify the user is watching the video } private readonly webtorrent = new WebTorrent({ @@ -55,15 +57,20 @@ class PeerTubePlugin extends Plugin { private currentVideoFile: VideoFile private torrent: WebTorrent.Torrent private videoCaptions: VideoJSCaption[] + private renderer private fakeRenderer + private destoyingFakeRenderer = false + private autoResolution = true private forbidAutoResolution = false private isAutoResolutionObservation = false + private playerRefusedP2P = false private videoViewInterval private torrentInfoInterval private autoQualityInterval + private userWatchingVideoInterval private addTorrentDelay private qualityObservationTimer private runAutoQualitySchedulerTimer @@ -92,11 +99,14 @@ class PeerTubePlugin extends Plugin { if (volume !== undefined) this.player.volume(volume) const muted = getStoredMute() if (muted !== undefined) this.player.muted(muted) + this.playerRefusedP2P = getStoredWebTorrentPolicy() || false this.initializePlayer() this.runTorrentInfoScheduler() this.runViewAdd() + if (options.userWatching) this.runUserWatchVideo(options.userWatching) + this.player.one('play', () => { // Don't run immediately scheduler, wait some seconds the TCP connections are made this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER) @@ -118,6 +128,8 @@ class PeerTubePlugin extends Plugin { clearInterval(this.torrentInfoInterval) clearInterval(this.autoQualityInterval) + if (this.userWatchingVideoInterval) clearInterval(this.userWatchingVideoInterval) + // Don't need to destroy renderer, video player will be destroyed this.flushVideoFile(this.currentVideoFile, false) @@ -279,7 +291,8 @@ class PeerTubePlugin extends Plugin { renderVideo(torrent.files[ 0 ], this.playerElement, renderVideoOptions, (err, renderer) => { this.renderer = renderer - if (err) return this.fallbackToHttp(done) + console.log('value this.playerRefusedP2P', this.playerRefusedP2P) + if (err || this.playerRefusedP2P) return this.fallbackToHttp(done) return this.tryToPlay(err => { if (err) return done(err) @@ -521,6 +534,21 @@ class PeerTubePlugin extends Plugin { }, 1000) } + private runUserWatchVideo (options: UserWatching) { + let lastCurrentTime = 0 + + this.userWatchingVideoInterval = setInterval(() => { + const currentTime = Math.floor(this.player.currentTime()) + + if (currentTime - lastCurrentTime >= 1) { + lastCurrentTime = currentTime + + this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader) + .catch(err => console.error('Cannot notify user is watching.', err)) + } + }, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL) + } + private clearVideoViewInterval () { if (this.videoViewInterval !== undefined) { clearInterval(this.videoViewInterval) @@ -534,6 +562,15 @@ class PeerTubePlugin extends Plugin { return fetch(this.videoViewUrl, { method: 'POST' }) } + private notifyUserIsWatching (currentTime: number, url: string, authorizationHeader: string) { + const body = new URLSearchParams() + body.append('currentTime', currentTime.toString()) + + const headers = new Headers({ 'Authorization': authorizationHeader }) + + return fetch(url, { method: 'PUT', body, headers }) + } + private fallbackToHttp (done?: Function, play = true) { this.disableAutoResolution(true) @@ -599,11 +636,16 @@ class PeerTubePlugin extends Plugin { } private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) { + this.destoyingFakeRenderer = false + const fakeVideoElem = document.createElement('video') renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => { this.fakeRenderer = renderer - if (err) console.error('Cannot render new torrent in fake video element.', err) + // The renderer returns an error when we destroy it, so skip them + if (this.destoyingFakeRenderer === false && err) { + console.error('Cannot render new torrent in fake video element.', err) + } // Load the future file at the correct time (in delay MS - 2 seconds) fakeVideoElem.currentTime = this.player.currentTime() + (delay - 2000) @@ -612,6 +654,8 @@ class PeerTubePlugin extends Plugin { private destroyFakeRenderer () { if (this.fakeRenderer) { + this.destoyingFakeRenderer = true + if (this.fakeRenderer.destroy) { try { this.fakeRenderer.destroy()