aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/assets/player
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-10-05 11:15:06 +0200
committerChocobozzz <me@florianbigard.com>2018-10-05 11:22:38 +0200
commit6e46de095d7169355dd83030f6ce4a582304153a (patch)
treedfa78e2008d3d135a00b798b05350b4975145acc /client/src/assets/player
parenta585824160d016db7c9bff0e1cb1ffa3aaf73d74 (diff)
downloadPeerTube-6e46de095d7169355dd83030f6ce4a582304153a.tar.gz
PeerTube-6e46de095d7169355dd83030f6ce4a582304153a.tar.zst
PeerTube-6e46de095d7169355dd83030f6ce4a582304153a.zip
Add user history and resume videos
Diffstat (limited to 'client/src/assets/player')
-rw-r--r--client/src/assets/player/peertube-player.ts8
-rw-r--r--client/src/assets/player/peertube-videojs-plugin.ts34
-rw-r--r--client/src/assets/player/peertube-videojs-typings.ts10
3 files changed, 47 insertions, 5 deletions
diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts
index 1bf6c9267..792662b6c 100644
--- a/client/src/assets/player/peertube-player.ts
+++ b/client/src/assets/player/peertube-player.ts
@@ -10,7 +10,7 @@ import './webtorrent-info-button'
10import './peertube-videojs-plugin' 10import './peertube-videojs-plugin'
11import './peertube-load-progress-bar' 11import './peertube-load-progress-bar'
12import './theater-button' 12import './theater-button'
13import { VideoJSCaption, videojsUntyped } from './peertube-videojs-typings' 13import { UserWatching, VideoJSCaption, videojsUntyped } from './peertube-videojs-typings'
14import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils' 14import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils'
15import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n' 15import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
16 16
@@ -34,10 +34,13 @@ function getVideojsOptions (options: {
34 startTime: number | string 34 startTime: number | string
35 theaterMode: boolean, 35 theaterMode: boolean,
36 videoCaptions: VideoJSCaption[], 36 videoCaptions: VideoJSCaption[],
37
37 language?: string, 38 language?: string,
38 controls?: boolean, 39 controls?: boolean,
39 muted?: boolean, 40 muted?: boolean,
40 loop?: boolean 41 loop?: boolean
42
43 userWatching?: UserWatching
41}) { 44}) {
42 const videojsOptions = { 45 const videojsOptions = {
43 // We don't use text track settings for now 46 // We don't use text track settings for now
@@ -57,7 +60,8 @@ function getVideojsOptions (options: {
57 playerElement: options.playerElement, 60 playerElement: options.playerElement,
58 videoViewUrl: options.videoViewUrl, 61 videoViewUrl: options.videoViewUrl,
59 videoDuration: options.videoDuration, 62 videoDuration: options.videoDuration,
60 startTime: options.startTime 63 startTime: options.startTime,
64 userWatching: options.userWatching
61 } 65 }
62 }, 66 },
63 controlBar: { 67 controlBar: {
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts
index adc376e94..2330f476f 100644
--- a/client/src/assets/player/peertube-videojs-plugin.ts
+++ b/client/src/assets/player/peertube-videojs-plugin.ts
@@ -3,7 +3,7 @@ import * as WebTorrent from 'webtorrent'
3import { VideoFile } from '../../../../shared/models/videos/video.model' 3import { VideoFile } from '../../../../shared/models/videos/video.model'
4import { renderVideo } from './video-renderer' 4import { renderVideo } from './video-renderer'
5import './settings-menu-button' 5import './settings-menu-button'
6import { PeertubePluginOptions, VideoJSCaption, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings' 6import { PeertubePluginOptions, UserWatching, VideoJSCaption, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings'
7import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution } from './utils' 7import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution } from './utils'
8import * as CacheChunkStore from 'cache-chunk-store' 8import * as CacheChunkStore from 'cache-chunk-store'
9import { PeertubeChunkStore } from './peertube-chunk-store' 9import { PeertubeChunkStore } from './peertube-chunk-store'
@@ -32,7 +32,8 @@ class PeerTubePlugin extends Plugin {
32 AUTO_QUALITY_THRESHOLD_PERCENT: 30, // Bandwidth should be 30% more important than a resolution bitrate to change to it 32 AUTO_QUALITY_THRESHOLD_PERCENT: 30, // Bandwidth should be 30% more important than a resolution bitrate to change to it
33 AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds after having change the resolution before another check 33 AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds after having change the resolution before another check
34 AUTO_QUALITY_HIGHER_RESOLUTION_DELAY: 5000, // Buffering higher resolution during 5 seconds 34 AUTO_QUALITY_HIGHER_RESOLUTION_DELAY: 5000, // Buffering higher resolution during 5 seconds
35 BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5 // Last 5 seconds to build average bandwidth 35 BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5, // Last 5 seconds to build average bandwidth
36 USER_WATCHING_VIDEO_INTERVAL: 5000 // Every 5 seconds, notify the user is watching the video
36 } 37 }
37 38
38 private readonly webtorrent = new WebTorrent({ 39 private readonly webtorrent = new WebTorrent({
@@ -67,6 +68,7 @@ class PeerTubePlugin extends Plugin {
67 private videoViewInterval 68 private videoViewInterval
68 private torrentInfoInterval 69 private torrentInfoInterval
69 private autoQualityInterval 70 private autoQualityInterval
71 private userWatchingVideoInterval
70 private addTorrentDelay 72 private addTorrentDelay
71 private qualityObservationTimer 73 private qualityObservationTimer
72 private runAutoQualitySchedulerTimer 74 private runAutoQualitySchedulerTimer
@@ -100,6 +102,8 @@ class PeerTubePlugin extends Plugin {
100 this.runTorrentInfoScheduler() 102 this.runTorrentInfoScheduler()
101 this.runViewAdd() 103 this.runViewAdd()
102 104
105 if (options.userWatching) this.runUserWatchVideo(options.userWatching)
106
103 this.player.one('play', () => { 107 this.player.one('play', () => {
104 // Don't run immediately scheduler, wait some seconds the TCP connections are made 108 // Don't run immediately scheduler, wait some seconds the TCP connections are made
105 this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER) 109 this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
@@ -121,6 +125,8 @@ class PeerTubePlugin extends Plugin {
121 clearInterval(this.torrentInfoInterval) 125 clearInterval(this.torrentInfoInterval)
122 clearInterval(this.autoQualityInterval) 126 clearInterval(this.autoQualityInterval)
123 127
128 if (this.userWatchingVideoInterval) clearInterval(this.userWatchingVideoInterval)
129
124 // Don't need to destroy renderer, video player will be destroyed 130 // Don't need to destroy renderer, video player will be destroyed
125 this.flushVideoFile(this.currentVideoFile, false) 131 this.flushVideoFile(this.currentVideoFile, false)
126 132
@@ -524,6 +530,21 @@ class PeerTubePlugin extends Plugin {
524 }, 1000) 530 }, 1000)
525 } 531 }
526 532
533 private runUserWatchVideo (options: UserWatching) {
534 let lastCurrentTime = 0
535
536 this.userWatchingVideoInterval = setInterval(() => {
537 const currentTime = Math.floor(this.player.currentTime())
538
539 if (currentTime - lastCurrentTime >= 1) {
540 lastCurrentTime = currentTime
541
542 this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader)
543 .catch(err => console.error('Cannot notify user is watching.', err))
544 }
545 }, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL)
546 }
547
527 private clearVideoViewInterval () { 548 private clearVideoViewInterval () {
528 if (this.videoViewInterval !== undefined) { 549 if (this.videoViewInterval !== undefined) {
529 clearInterval(this.videoViewInterval) 550 clearInterval(this.videoViewInterval)
@@ -537,6 +558,15 @@ class PeerTubePlugin extends Plugin {
537 return fetch(this.videoViewUrl, { method: 'POST' }) 558 return fetch(this.videoViewUrl, { method: 'POST' })
538 } 559 }
539 560
561 private notifyUserIsWatching (currentTime: number, url: string, authorizationHeader: string) {
562 const body = new URLSearchParams()
563 body.append('currentTime', currentTime.toString())
564
565 const headers = new Headers({ 'Authorization': authorizationHeader })
566
567 return fetch(url, { method: 'PUT', body, headers })
568 }
569
540 private fallbackToHttp (done?: Function, play = true) { 570 private fallbackToHttp (done?: Function, play = true) {
541 this.disableAutoResolution(true) 571 this.disableAutoResolution(true)
542 572
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts
index 993d5ee6b..b117007af 100644
--- a/client/src/assets/player/peertube-videojs-typings.ts
+++ b/client/src/assets/player/peertube-videojs-typings.ts
@@ -22,6 +22,11 @@ type VideoJSCaption = {
22 src: string 22 src: string
23} 23}
24 24
25type UserWatching = {
26 url: string,
27 authorizationHeader: string
28}
29
25type PeertubePluginOptions = { 30type PeertubePluginOptions = {
26 videoFiles: VideoFile[] 31 videoFiles: VideoFile[]
27 playerElement: HTMLVideoElement 32 playerElement: HTMLVideoElement
@@ -30,6 +35,8 @@ type PeertubePluginOptions = {
30 startTime: number | string 35 startTime: number | string
31 autoplay: boolean, 36 autoplay: boolean,
32 videoCaptions: VideoJSCaption[] 37 videoCaptions: VideoJSCaption[]
38
39 userWatching?: UserWatching
33} 40}
34 41
35// videojs typings don't have some method we need 42// videojs typings don't have some method we need
@@ -39,5 +46,6 @@ export {
39 VideoJSComponentInterface, 46 VideoJSComponentInterface,
40 PeertubePluginOptions, 47 PeertubePluginOptions,
41 videojsUntyped, 48 videojsUntyped,
42 VideoJSCaption 49 VideoJSCaption,
50 UserWatching
43} 51}