diff options
-rw-r--r-- | client/src/assets/player/peertube-player-local-storage.ts | 12 | ||||
-rw-r--r-- | client/src/assets/player/peertube-player.ts | 36 | ||||
-rw-r--r-- | client/src/assets/player/peertube-videojs-plugin.ts | 44 | ||||
-rw-r--r-- | client/src/assets/player/peertube-videojs-typings.ts | 1 | ||||
-rw-r--r-- | client/src/assets/player/utils.ts | 1 | ||||
-rw-r--r-- | client/src/standalone/videos/embed.ts | 28 |
6 files changed, 81 insertions, 41 deletions
diff --git a/client/src/assets/player/peertube-player-local-storage.ts b/client/src/assets/player/peertube-player-local-storage.ts index 7e3813570..059fca308 100644 --- a/client/src/assets/player/peertube-player-local-storage.ts +++ b/client/src/assets/player/peertube-player-local-storage.ts | |||
@@ -60,6 +60,14 @@ function getAverageBandwidthInStore () { | |||
60 | return undefined | 60 | return undefined |
61 | } | 61 | } |
62 | 62 | ||
63 | function saveLastSubtitle (language: string) { | ||
64 | return setLocalStorage('last-subtitle', language) | ||
65 | } | ||
66 | |||
67 | function getStoredLastSubtitle () { | ||
68 | return getLocalStorage('last-subtitle') | ||
69 | } | ||
70 | |||
63 | // --------------------------------------------------------------------------- | 71 | // --------------------------------------------------------------------------- |
64 | 72 | ||
65 | export { | 73 | export { |
@@ -71,7 +79,9 @@ export { | |||
71 | saveMuteInStore, | 79 | saveMuteInStore, |
72 | saveTheaterInStore, | 80 | saveTheaterInStore, |
73 | saveAverageBandwidth, | 81 | saveAverageBandwidth, |
74 | getAverageBandwidthInStore | 82 | getAverageBandwidthInStore, |
83 | saveLastSubtitle, | ||
84 | getStoredLastSubtitle | ||
75 | } | 85 | } |
76 | 86 | ||
77 | // --------------------------------------------------------------------------- | 87 | // --------------------------------------------------------------------------- |
diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts index aaa1170b6..e0e063838 100644 --- a/client/src/assets/player/peertube-player.ts +++ b/client/src/assets/player/peertube-player.ts | |||
@@ -26,23 +26,24 @@ videojsUntyped.getComponent('CaptionsButton').prototype.controlText_ = 'Subtitle | |||
26 | videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' ' | 26 | videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' ' |
27 | 27 | ||
28 | function getVideojsOptions (options: { | 28 | function getVideojsOptions (options: { |
29 | autoplay: boolean, | 29 | autoplay: boolean |
30 | playerElement: HTMLVideoElement, | 30 | playerElement: HTMLVideoElement |
31 | videoViewUrl: string, | 31 | videoViewUrl: string |
32 | videoDuration: number, | 32 | videoDuration: number |
33 | videoFiles: VideoFile[], | 33 | videoFiles: VideoFile[] |
34 | enableHotkeys: boolean, | 34 | enableHotkeys: boolean |
35 | inactivityTimeout: number, | 35 | inactivityTimeout: number |
36 | peertubeLink: boolean, | 36 | peertubeLink: boolean |
37 | poster: string, | 37 | poster: string |
38 | startTime: number | string | 38 | startTime: number | string |
39 | theaterMode: boolean, | 39 | theaterMode: boolean |
40 | videoCaptions: VideoJSCaption[], | 40 | videoCaptions: VideoJSCaption[] |
41 | 41 | ||
42 | language?: string, | 42 | language?: string |
43 | controls?: boolean, | 43 | controls?: boolean |
44 | muted?: boolean, | 44 | muted?: boolean |
45 | loop?: boolean | 45 | loop?: boolean |
46 | subtitle?: string | ||
46 | 47 | ||
47 | userWatching?: UserWatching | 48 | userWatching?: UserWatching |
48 | }) { | 49 | }) { |
@@ -50,8 +51,10 @@ function getVideojsOptions (options: { | |||
50 | // We don't use text track settings for now | 51 | // We don't use text track settings for now |
51 | textTrackSettings: false, | 52 | textTrackSettings: false, |
52 | controls: options.controls !== undefined ? options.controls : true, | 53 | controls: options.controls !== undefined ? options.controls : true, |
53 | muted: options.controls !== undefined ? options.muted : false, | ||
54 | loop: options.loop !== undefined ? options.loop : false, | 54 | loop: options.loop !== undefined ? options.loop : false, |
55 | |||
56 | muted: options.muted !== undefined ? options.muted : undefined, // Undefined so the player knows it has to check the local storage | ||
57 | |||
55 | poster: options.poster, | 58 | poster: options.poster, |
56 | autoplay: false, | 59 | autoplay: false, |
57 | inactivityTimeout: options.inactivityTimeout, | 60 | inactivityTimeout: options.inactivityTimeout, |
@@ -65,7 +68,8 @@ function getVideojsOptions (options: { | |||
65 | videoViewUrl: options.videoViewUrl, | 68 | videoViewUrl: options.videoViewUrl, |
66 | videoDuration: options.videoDuration, | 69 | videoDuration: options.videoDuration, |
67 | startTime: options.startTime, | 70 | startTime: options.startTime, |
68 | userWatching: options.userWatching | 71 | userWatching: options.userWatching, |
72 | subtitle: options.subtitle | ||
69 | } | 73 | } |
70 | }, | 74 | }, |
71 | controlBar: { | 75 | controlBar: { |
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index 4fd5a9be2..4a280b7ef 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts | |||
@@ -11,10 +11,12 @@ import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution | |||
11 | import { PeertubeChunkStore } from './peertube-chunk-store' | 11 | import { PeertubeChunkStore } from './peertube-chunk-store' |
12 | import { | 12 | import { |
13 | getAverageBandwidthInStore, | 13 | getAverageBandwidthInStore, |
14 | getStoredLastSubtitle, | ||
14 | getStoredMute, | 15 | getStoredMute, |
15 | getStoredVolume, | 16 | getStoredVolume, |
16 | getStoredWebTorrentEnabled, | 17 | getStoredWebTorrentEnabled, |
17 | saveAverageBandwidth, | 18 | saveAverageBandwidth, |
19 | saveLastSubtitle, | ||
18 | saveMuteInStore, | 20 | saveMuteInStore, |
19 | saveVolumeInStore | 21 | saveVolumeInStore |
20 | } from './peertube-player-local-storage' | 22 | } from './peertube-player-local-storage' |
@@ -67,10 +69,11 @@ class PeerTubePlugin extends Plugin { | |||
67 | private currentVideoFile: VideoFile | 69 | private currentVideoFile: VideoFile |
68 | private torrent: WebTorrent.Torrent | 70 | private torrent: WebTorrent.Torrent |
69 | private videoCaptions: VideoJSCaption[] | 71 | private videoCaptions: VideoJSCaption[] |
72 | private defaultSubtitle: string | ||
70 | 73 | ||
71 | private renderer: any | 74 | private renderer: any |
72 | private fakeRenderer: any | 75 | private fakeRenderer: any |
73 | private destoyingFakeRenderer = false | 76 | private destroyingFakeRenderer = false |
74 | 77 | ||
75 | private autoResolution = true | 78 | private autoResolution = true |
76 | private forbidAutoResolution = false | 79 | private forbidAutoResolution = false |
@@ -106,11 +109,34 @@ class PeerTubePlugin extends Plugin { | |||
106 | if (this.autoplay === true) this.player.addClass('vjs-has-autoplay') | 109 | if (this.autoplay === true) this.player.addClass('vjs-has-autoplay') |
107 | 110 | ||
108 | this.player.ready(() => { | 111 | this.player.ready(() => { |
112 | const playerOptions = this.player.options_ | ||
113 | |||
109 | const volume = getStoredVolume() | 114 | const volume = getStoredVolume() |
110 | if (volume !== undefined) this.player.volume(volume) | 115 | if (volume !== undefined) this.player.volume(volume) |
111 | const muted = getStoredMute() | 116 | |
117 | const muted = playerOptions.muted !== undefined ? playerOptions.muted : getStoredMute() | ||
112 | if (muted !== undefined) this.player.muted(muted) | 118 | if (muted !== undefined) this.player.muted(muted) |
113 | 119 | ||
120 | this.defaultSubtitle = options.subtitle || getStoredLastSubtitle() | ||
121 | |||
122 | this.player.on('volumechange', () => { | ||
123 | saveVolumeInStore(this.player.volume()) | ||
124 | saveMuteInStore(this.player.muted()) | ||
125 | }) | ||
126 | |||
127 | this.player.textTracks().on('change', () => { | ||
128 | const showing = this.player.textTracks().tracks_.find((t: { kind: string, mode: string }) => { | ||
129 | return t.kind === 'captions' && t.mode === 'showing' | ||
130 | }) | ||
131 | |||
132 | if (!showing) { | ||
133 | saveLastSubtitle('off') | ||
134 | return | ||
135 | } | ||
136 | |||
137 | saveLastSubtitle(showing.language) | ||
138 | }) | ||
139 | |||
114 | this.player.duration(options.videoDuration) | 140 | this.player.duration(options.videoDuration) |
115 | 141 | ||
116 | this.initializePlayer() | 142 | this.initializePlayer() |
@@ -124,11 +150,6 @@ class PeerTubePlugin extends Plugin { | |||
124 | this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER) | 150 | this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER) |
125 | }) | 151 | }) |
126 | }) | 152 | }) |
127 | |||
128 | this.player.on('volumechange', () => { | ||
129 | saveVolumeInStore(this.player.volume()) | ||
130 | saveMuteInStore(this.player.muted()) | ||
131 | }) | ||
132 | } | 153 | } |
133 | 154 | ||
134 | dispose () { | 155 | dispose () { |
@@ -657,14 +678,14 @@ class PeerTubePlugin extends Plugin { | |||
657 | } | 678 | } |
658 | 679 | ||
659 | private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) { | 680 | private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) { |
660 | this.destoyingFakeRenderer = false | 681 | this.destroyingFakeRenderer = false |
661 | 682 | ||
662 | const fakeVideoElem = document.createElement('video') | 683 | const fakeVideoElem = document.createElement('video') |
663 | renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => { | 684 | renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => { |
664 | this.fakeRenderer = renderer | 685 | this.fakeRenderer = renderer |
665 | 686 | ||
666 | // The renderer returns an error when we destroy it, so skip them | 687 | // The renderer returns an error when we destroy it, so skip them |
667 | if (this.destoyingFakeRenderer === false && err) { | 688 | if (this.destroyingFakeRenderer === false && err) { |
668 | console.error('Cannot render new torrent in fake video element.', err) | 689 | console.error('Cannot render new torrent in fake video element.', err) |
669 | } | 690 | } |
670 | 691 | ||
@@ -675,7 +696,7 @@ class PeerTubePlugin extends Plugin { | |||
675 | 696 | ||
676 | private destroyFakeRenderer () { | 697 | private destroyFakeRenderer () { |
677 | if (this.fakeRenderer) { | 698 | if (this.fakeRenderer) { |
678 | this.destoyingFakeRenderer = true | 699 | this.destroyingFakeRenderer = true |
679 | 700 | ||
680 | if (this.fakeRenderer.destroy) { | 701 | if (this.fakeRenderer.destroy) { |
681 | try { | 702 | try { |
@@ -695,7 +716,8 @@ class PeerTubePlugin extends Plugin { | |||
695 | label: caption.label, | 716 | label: caption.label, |
696 | language: caption.language, | 717 | language: caption.language, |
697 | id: caption.language, | 718 | id: caption.language, |
698 | src: caption.src | 719 | src: caption.src, |
720 | default: this.defaultSubtitle === caption.language | ||
699 | }, false) | 721 | }, false) |
700 | } | 722 | } |
701 | } | 723 | } |
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts index d127230fa..634c7fdc9 100644 --- a/client/src/assets/player/peertube-videojs-typings.ts +++ b/client/src/assets/player/peertube-videojs-typings.ts | |||
@@ -39,6 +39,7 @@ type PeertubePluginOptions = { | |||
39 | autoplay: boolean, | 39 | autoplay: boolean, |
40 | videoCaptions: VideoJSCaption[] | 40 | videoCaptions: VideoJSCaption[] |
41 | 41 | ||
42 | subtitle?: string | ||
42 | userWatching?: UserWatching | 43 | userWatching?: UserWatching |
43 | } | 44 | } |
44 | 45 | ||
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts index c87287482..8b9f34b99 100644 --- a/client/src/assets/player/utils.ts +++ b/client/src/assets/player/utils.ts | |||
@@ -39,6 +39,7 @@ function buildVideoLink (time?: number, url?: string) { | |||
39 | } | 39 | } |
40 | 40 | ||
41 | function timeToInt (time: number | string) { | 41 | function timeToInt (time: number | string) { |
42 | if (!time) return 0 | ||
42 | if (typeof time === 'number') return time | 43 | if (typeof time === 'number') return time |
43 | 44 | ||
44 | const reg = /^((\d+)h)?((\d+)m)?((\d+)s?)?$/ | 45 | const reg = /^((\d+)h)?((\d+)m)?((\d+)s?)?$/ |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index 7daa03f23..3a09f285e 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -157,10 +157,11 @@ class PeerTubeEmbed { | |||
157 | player: any | 157 | player: any |
158 | playerOptions: any | 158 | playerOptions: any |
159 | api: PeerTubeEmbedApi = null | 159 | api: PeerTubeEmbedApi = null |
160 | autoplay = false | 160 | autoplay: boolean |
161 | controls = true | 161 | controls: boolean |
162 | muted = false | 162 | muted: boolean |
163 | loop = false | 163 | loop: boolean |
164 | subtitle: string | ||
164 | enableApi = false | 165 | enableApi = false |
165 | startTime: number | string = 0 | 166 | startTime: number | string = 0 |
166 | scope = 'peertube' | 167 | scope = 'peertube' |
@@ -214,11 +215,11 @@ class PeerTubeEmbed { | |||
214 | this.displayError(text) | 215 | this.displayError(text) |
215 | } | 216 | } |
216 | 217 | ||
217 | getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) { | 218 | getParamToggle (params: URLSearchParams, name: string, defaultValue?: boolean) { |
218 | return params.has(name) ? (params.get(name) === '1' || params.get(name) === 'true') : defaultValue | 219 | return params.has(name) ? (params.get(name) === '1' || params.get(name) === 'true') : defaultValue |
219 | } | 220 | } |
220 | 221 | ||
221 | getParamString (params: URLSearchParams, name: string, defaultValue: string) { | 222 | getParamString (params: URLSearchParams, name: string, defaultValue?: string) { |
222 | return params.has(name) ? params.get(name) : defaultValue | 223 | return params.has(name) ? params.get(name) : defaultValue |
223 | } | 224 | } |
224 | 225 | ||
@@ -241,15 +242,15 @@ class PeerTubeEmbed { | |||
241 | try { | 242 | try { |
242 | let params = new URL(window.location.toString()).searchParams | 243 | let params = new URL(window.location.toString()).searchParams |
243 | 244 | ||
244 | this.autoplay = this.getParamToggle(params, 'autoplay', this.autoplay) | 245 | this.autoplay = this.getParamToggle(params, 'autoplay') |
245 | this.controls = this.getParamToggle(params, 'controls', this.controls) | 246 | this.controls = this.getParamToggle(params, 'controls') |
246 | this.muted = this.getParamToggle(params, 'muted', this.muted) | 247 | this.muted = this.getParamToggle(params, 'muted') |
247 | this.loop = this.getParamToggle(params, 'loop', this.loop) | 248 | this.loop = this.getParamToggle(params, 'loop') |
248 | this.enableApi = this.getParamToggle(params, 'api', this.enableApi) | 249 | this.enableApi = this.getParamToggle(params, 'api', this.enableApi) |
249 | this.scope = this.getParamString(params, 'scope', this.scope) | ||
250 | 250 | ||
251 | const startTimeParamString = params.get('start') | 251 | this.scope = this.getParamString(params, 'scope', this.scope) |
252 | if (startTimeParamString) this.startTime = startTimeParamString | 252 | this.subtitle = this.getParamString(params, 'subtitle') |
253 | this.startTime = this.getParamString(params, 'start') | ||
253 | } catch (err) { | 254 | } catch (err) { |
254 | console.error('Cannot get params from URL.', err) | 255 | console.error('Cannot get params from URL.', err) |
255 | } | 256 | } |
@@ -291,6 +292,7 @@ class PeerTubeEmbed { | |||
291 | muted: this.muted, | 292 | muted: this.muted, |
292 | loop: this.loop, | 293 | loop: this.loop, |
293 | startTime: this.startTime, | 294 | startTime: this.startTime, |
295 | subtitle: this.subtitle, | ||
294 | 296 | ||
295 | videoCaptions, | 297 | videoCaptions, |
296 | inactivityTimeout: 1500, | 298 | inactivityTimeout: 1500, |