aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/assets
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/assets')
-rw-r--r--client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts2
-rw-r--r--client/src/assets/player/peertube-player-manager.ts43
-rw-r--r--client/src/assets/player/peertube-plugin.ts12
-rw-r--r--client/src/assets/player/peertube-videojs-typings.ts5
-rw-r--r--client/src/assets/player/playlist/playlist-menu-item.ts2
-rw-r--r--client/src/assets/player/stats/stats-card.ts3
-rw-r--r--client/src/assets/player/utils.ts136
-rw-r--r--client/src/assets/player/videojs-components/peertube-link-button.ts20
-rw-r--r--client/src/assets/player/webtorrent/webtorrent-plugin.ts11
9 files changed, 73 insertions, 161 deletions
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 f1bd9f0c4..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
@@ -2,8 +2,8 @@ import * as Hlsjs from 'hls.js/dist/hls.light.js'
2import { Events, Segment } from 'p2p-media-loader-core' 2import { Events, Segment } from 'p2p-media-loader-core'
3import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs' 3import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs'
4import videojs from 'video.js' 4import videojs from 'video.js'
5import { timeToInt } from '@shared/core-utils'
5import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings' 6import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings'
6import { timeToInt } from '../utils'
7import { registerConfigPlugin, registerSourceHandler } from './hls-plugin' 7import { registerConfigPlugin, registerSourceHandler } from './hls-plugin'
8 8
9registerConfigPlugin(videojs) 9registerConfigPlugin(videojs)
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts
index b071a0938..766ad203e 100644
--- a/client/src/assets/player/peertube-player-manager.ts
+++ b/client/src/assets/player/peertube-player-manager.ts
@@ -23,6 +23,7 @@ import './videojs-components/theater-button'
23import './playlist/playlist-plugin' 23import './playlist/playlist-plugin'
24import videojs from 'video.js' 24import videojs from 'video.js'
25import { PluginsManager } from '@root-helpers/plugins-manager' 25import { PluginsManager } from '@root-helpers/plugins-manager'
26import { buildVideoLink, decorateVideoLink } from '@shared/core-utils'
26import { isDefaultLocale } from '@shared/core-utils/i18n' 27import { isDefaultLocale } from '@shared/core-utils/i18n'
27import { VideoFile } from '@shared/models' 28import { VideoFile } from '@shared/models'
28import { copyToClipboard } from '../../root-helpers/utils' 29import { copyToClipboard } from '../../root-helpers/utils'
@@ -33,13 +34,14 @@ import { getStoredP2PEnabled } from './peertube-player-local-storage'
33import { 34import {
34 NextPreviousVideoButtonOptions, 35 NextPreviousVideoButtonOptions,
35 P2PMediaLoaderPluginOptions, 36 P2PMediaLoaderPluginOptions,
37 PeerTubeLinkButtonOptions,
36 PlaylistPluginOptions, 38 PlaylistPluginOptions,
37 UserWatching, 39 UserWatching,
38 VideoJSCaption, 40 VideoJSCaption,
39 VideoJSPluginOptions 41 VideoJSPluginOptions
40} from './peertube-videojs-typings' 42} from './peertube-videojs-typings'
41import { TranslationsManager } from './translations-manager' 43import { TranslationsManager } from './translations-manager'
42import { buildVideoLink, buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils' 44import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils'
43 45
44// Change 'Playback Rate' to 'Speed' (smaller for our settings menu) 46// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
45(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed' 47(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed'
@@ -110,6 +112,7 @@ export interface CommonOptions extends CustomizationOptions {
110 videoCaptions: VideoJSCaption[] 112 videoCaptions: VideoJSCaption[]
111 113
112 videoUUID: string 114 videoUUID: string
115 videoShortUUID: string
113 116
114 userWatching?: UserWatching 117 userWatching?: UserWatching
115 118
@@ -175,7 +178,13 @@ export class PeertubePlayerManager {
175 PeertubePlayerManager.alreadyPlayed = true 178 PeertubePlayerManager.alreadyPlayed = true
176 }) 179 })
177 180
178 self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle) 181 self.addContextMenu({
182 mode,
183 player,
184 videoShortUUID: options.common.videoShortUUID,
185 videoEmbedUrl: options.common.embedUrl,
186 videoEmbedTitle: options.common.embedTitle
187 })
179 188
180 player.bezels() 189 player.bezels()
181 player.stats({ 190 player.stats({
@@ -218,7 +227,13 @@ export class PeertubePlayerManager {
218 videojs(newVideoElement, videojsOptions, function (this: videojs.Player) { 227 videojs(newVideoElement, videojsOptions, function (this: videojs.Player) {
219 const player = this 228 const player = this
220 229
221 self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle) 230 self.addContextMenu({
231 mode,
232 player,
233 videoShortUUID: options.common.videoShortUUID,
234 videoEmbedUrl: options.common.embedUrl,
235 videoEmbedTitle: options.common.embedTitle
236 })
222 237
223 PeertubePlayerManager.onPlayerChange(player) 238 PeertubePlayerManager.onPlayerChange(player)
224 }) 239 })
@@ -295,6 +310,8 @@ export class PeertubePlayerManager {
295 310
296 controlBar: { 311 controlBar: {
297 children: this.getControlBarChildren(mode, { 312 children: this.getControlBarChildren(mode, {
313 videoShortUUID: commonOptions.videoShortUUID,
314
298 captions: commonOptions.captions, 315 captions: commonOptions.captions,
299 peertubeLink: commonOptions.peertubeLink, 316 peertubeLink: commonOptions.peertubeLink,
300 theaterButton: commonOptions.theaterButton, 317 theaterButton: commonOptions.theaterButton,
@@ -409,6 +426,8 @@ export class PeertubePlayerManager {
409 } 426 }
410 427
411 private static getControlBarChildren (mode: PlayerMode, options: { 428 private static getControlBarChildren (mode: PlayerMode, options: {
429 videoShortUUID: string
430
412 peertubeLink: boolean 431 peertubeLink: boolean
413 theaterButton: boolean 432 theaterButton: boolean
414 captions: boolean 433 captions: boolean
@@ -497,7 +516,7 @@ export class PeertubePlayerManager {
497 516
498 if (options.peertubeLink === true) { 517 if (options.peertubeLink === true) {
499 Object.assign(children, { 518 Object.assign(children, {
500 'peerTubeLinkButton': {} 519 'peerTubeLinkButton': { shortUUID: options.videoShortUUID } as PeerTubeLinkButtonOptions
501 }) 520 })
502 } 521 }
503 522
@@ -514,7 +533,15 @@ export class PeertubePlayerManager {
514 return children 533 return children
515 } 534 }
516 535
517 private static addContextMenu (mode: PlayerMode, player: videojs.Player, videoEmbedUrl: string, videoEmbedTitle: string) { 536 private static addContextMenu (options: {
537 mode: PlayerMode
538 player: videojs.Player
539 videoShortUUID: string
540 videoEmbedUrl: string
541 videoEmbedTitle: string
542 }) {
543 const { mode, player, videoEmbedTitle, videoEmbedUrl, videoShortUUID } = options
544
518 const content = () => { 545 const content = () => {
519 const isLoopEnabled = player.options_['loop'] 546 const isLoopEnabled = player.options_['loop']
520 const items = [ 547 const items = [
@@ -528,13 +555,15 @@ export class PeertubePlayerManager {
528 { 555 {
529 label: player.localize('Copy the video URL'), 556 label: player.localize('Copy the video URL'),
530 listener: function () { 557 listener: function () {
531 copyToClipboard(buildVideoLink()) 558 copyToClipboard(buildVideoLink({ shortUUID: videoShortUUID }))
532 } 559 }
533 }, 560 },
534 { 561 {
535 label: player.localize('Copy the video URL at the current time'), 562 label: player.localize('Copy the video URL at the current time'),
536 listener: function (this: videojs.Player) { 563 listener: function (this: videojs.Player) {
537 copyToClipboard(buildVideoLink({ startTime: this.currentTime() })) 564 const url = buildVideoLink({ shortUUID: videoShortUUID })
565
566 copyToClipboard(decorateVideoLink({ url, startTime: this.currentTime() }))
538 } 567 }
539 }, 568 },
540 { 569 {
diff --git a/client/src/assets/player/peertube-plugin.ts b/client/src/assets/player/peertube-plugin.ts
index 07c7e33f6..919b7c239 100644
--- a/client/src/assets/player/peertube-plugin.ts
+++ b/client/src/assets/player/peertube-plugin.ts
@@ -1,12 +1,6 @@
1import videojs from 'video.js'
2import './videojs-components/settings-menu-button' 1import './videojs-components/settings-menu-button'
3import { 2import videojs from 'video.js'
4 PeerTubePluginOptions, 3import { timeToInt } from '@shared/core-utils'
5 ResolutionUpdateData,
6 UserWatching,
7 VideoJSCaption
8} from './peertube-videojs-typings'
9import { isMobile, timeToInt } from './utils'
10import { 4import {
11 getStoredLastSubtitle, 5 getStoredLastSubtitle,
12 getStoredMute, 6 getStoredMute,
@@ -16,6 +10,8 @@ import {
16 saveVideoWatchHistory, 10 saveVideoWatchHistory,
17 saveVolumeInStore 11 saveVolumeInStore
18} from './peertube-player-local-storage' 12} from './peertube-player-local-storage'
13import { PeerTubePluginOptions, ResolutionUpdateData, UserWatching, VideoJSCaption } from './peertube-videojs-typings'
14import { isMobile } from './utils'
19 15
20const Plugin = videojs.getPlugin('plugin') 16const Plugin = videojs.getPlugin('plugin')
21 17
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts
index 8afb424a7..d3c75990b 100644
--- a/client/src/assets/player/peertube-videojs-typings.ts
+++ b/client/src/assets/player/peertube-videojs-typings.ts
@@ -132,6 +132,10 @@ type NextPreviousVideoButtonOptions = {
132 isDisabled: () => boolean 132 isDisabled: () => boolean
133} 133}
134 134
135type PeerTubeLinkButtonOptions = {
136 shortUUID: string
137}
138
135type WebtorrentPluginOptions = { 139type WebtorrentPluginOptions = {
136 playerElement: HTMLVideoElement 140 playerElement: HTMLVideoElement
137 141
@@ -225,5 +229,6 @@ export {
225 VideoJSPluginOptions, 229 VideoJSPluginOptions,
226 LoadedQualityData, 230 LoadedQualityData,
227 QualityLevelRepresentation, 231 QualityLevelRepresentation,
232 PeerTubeLinkButtonOptions,
228 QualityLevels 233 QualityLevels
229} 234}
diff --git a/client/src/assets/player/playlist/playlist-menu-item.ts b/client/src/assets/player/playlist/playlist-menu-item.ts
index 87a72b6a3..2519a34c7 100644
--- a/client/src/assets/player/playlist/playlist-menu-item.ts
+++ b/client/src/assets/player/playlist/playlist-menu-item.ts
@@ -1,7 +1,7 @@
1import videojs from 'video.js' 1import videojs from 'video.js'
2import { secondsToTime } from '@shared/core-utils'
2import { VideoPlaylistElement } from '@shared/models' 3import { VideoPlaylistElement } from '@shared/models'
3import { PlaylistItemOptions } from '../peertube-videojs-typings' 4import { PlaylistItemOptions } from '../peertube-videojs-typings'
4import { secondsToTime } from '../utils'
5 5
6const Component = videojs.getComponent('Component') 6const Component = videojs.getComponent('Component')
7 7
diff --git a/client/src/assets/player/stats/stats-card.ts b/client/src/assets/player/stats/stats-card.ts
index a93f59506..b271d0526 100644
--- a/client/src/assets/player/stats/stats-card.ts
+++ b/client/src/assets/player/stats/stats-card.ts
@@ -1,6 +1,7 @@
1import videojs from 'video.js' 1import videojs from 'video.js'
2import { secondsToTime } from '@shared/core-utils'
2import { PlayerNetworkInfo as EventPlayerNetworkInfo } from '../peertube-videojs-typings' 3import { PlayerNetworkInfo as EventPlayerNetworkInfo } from '../peertube-videojs-typings'
3import { bytes, secondsToTime } from '../utils' 4import { bytes } from '../utils'
4 5
5interface StatsCardOptions extends videojs.ComponentOptions { 6interface StatsCardOptions extends videojs.ComponentOptions {
6 videoUUID: string 7 videoUUID: string
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts
index f26176acc..f0a1b1aee 100644
--- a/client/src/assets/player/utils.ts
+++ b/client/src/assets/player/utils.ts
@@ -1,5 +1,5 @@
1import { VideoFile } from '@shared/models'
2import { escapeHTML } from '@shared/core-utils/renderer' 1import { escapeHTML } from '@shared/core-utils/renderer'
2import { VideoFile } from '@shared/models'
3 3
4function toTitleCase (str: string) { 4function toTitleCase (str: string) {
5 return str.charAt(0).toUpperCase() + str.slice(1) 5 return str.charAt(0).toUpperCase() + str.slice(1)
@@ -43,136 +43,9 @@ function isMobile () {
43 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) 43 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
44} 44}
45 45
46function buildVideoLink (options: {
47 baseUrl?: string
48
49 startTime?: number
50 stopTime?: number
51
52 subtitle?: string
53
54 loop?: boolean
55 autoplay?: boolean
56 muted?: boolean
57
58 // Embed options
59 title?: boolean
60 warningTitle?: boolean
61 controls?: boolean
62 peertubeLink?: boolean
63} = {}) {
64 const { baseUrl } = options
65
66 const url = baseUrl
67 ? baseUrl
68 : window.location.origin + window.location.pathname.replace('/videos/embed/', '/w/')
69
70 const params = generateParams(window.location.search)
71
72 if (options.startTime !== undefined && options.startTime !== null) {
73 const startTimeInt = Math.floor(options.startTime)
74 params.set('start', secondsToTime(startTimeInt))
75 }
76
77 if (options.stopTime) {
78 const stopTimeInt = Math.floor(options.stopTime)
79 params.set('stop', secondsToTime(stopTimeInt))
80 }
81
82 if (options.subtitle) params.set('subtitle', options.subtitle)
83
84 if (options.loop === true) params.set('loop', '1')
85 if (options.autoplay === true) params.set('autoplay', '1')
86 if (options.muted === true) params.set('muted', '1')
87 if (options.title === false) params.set('title', '0')
88 if (options.warningTitle === false) params.set('warningTitle', '0')
89 if (options.controls === false) params.set('controls', '0')
90 if (options.peertubeLink === false) params.set('peertubeLink', '0')
91
92 return buildUrl(url, params)
93}
94
95function buildPlaylistLink (options: {
96 baseUrl?: string
97
98 playlistPosition?: number
99}) {
100 const { baseUrl } = options
101
102 const url = baseUrl
103 ? baseUrl
104 : window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/w/p/')
105
106 const params = generateParams(window.location.search)
107
108 if (options.playlistPosition) params.set('playlistPosition', '' + options.playlistPosition)
109
110 return buildUrl(url, params)
111}
112
113function buildUrl (url: string, params: URLSearchParams) {
114 let hasParams = false
115 params.forEach(() => hasParams = true)
116
117 if (hasParams) return url + '?' + params.toString()
118
119 return url
120}
121
122function generateParams (url: string) {
123 const params = new URLSearchParams(window.location.search)
124 // Unused parameters in embed
125 params.delete('videoId')
126 params.delete('resume')
127
128 return params
129}
130
131function timeToInt (time: number | string) {
132 if (!time) return 0
133 if (typeof time === 'number') return time
134
135 const reg = /^((\d+)[h:])?((\d+)[m:])?((\d+)s?)?$/
136 const matches = time.match(reg)
137
138 if (!matches) return 0
139
140 const hours = parseInt(matches[2] || '0', 10)
141 const minutes = parseInt(matches[4] || '0', 10)
142 const seconds = parseInt(matches[6] || '0', 10)
143
144 return hours * 3600 + minutes * 60 + seconds
145}
146
147function secondsToTime (seconds: number, full = false, symbol?: string) {
148 let time = ''
149
150 if (seconds === 0 && !full) return '0s'
151
152 const hourSymbol = (symbol || 'h')
153 const minuteSymbol = (symbol || 'm')
154 const secondsSymbol = full ? '' : 's'
155
156 const hours = Math.floor(seconds / 3600)
157 if (hours >= 1) time = hours + hourSymbol
158 else if (full) time = '0' + hourSymbol
159
160 seconds %= 3600
161 const minutes = Math.floor(seconds / 60)
162 if (minutes >= 1 && minutes < 10 && full) time += '0' + minutes + minuteSymbol
163 else if (minutes >= 1) time += minutes + minuteSymbol
164 else if (full) time += '00' + minuteSymbol
165
166 seconds %= 60
167 if (seconds >= 1 && seconds < 10 && full) time += '0' + seconds + secondsSymbol
168 else if (seconds >= 1) time += seconds + secondsSymbol
169 else if (full) time += '00'
170
171 return time
172}
173
174function buildVideoOrPlaylistEmbed (embedUrl: string, embedTitle: string) { 46function buildVideoOrPlaylistEmbed (embedUrl: string, embedTitle: string) {
175 const title = escapeHTML(embedTitle) 47 const title = escapeHTML(embedTitle)
48
176 return '<iframe width="560" height="315" ' + 49 return '<iframe width="560" height="315" ' +
177 'sandbox="allow-same-origin allow-scripts allow-popups" ' + 50 'sandbox="allow-same-origin allow-scripts allow-popups" ' +
178 'title="' + title + '" ' + 51 'title="' + title + '" ' +
@@ -221,11 +94,8 @@ function getRtcConfig () {
221export { 94export {
222 getRtcConfig, 95 getRtcConfig,
223 toTitleCase, 96 toTitleCase,
224 timeToInt,
225 secondsToTime,
226 isWebRTCDisabled, 97 isWebRTCDisabled,
227 buildPlaylistLink, 98
228 buildVideoLink,
229 buildVideoOrPlaylistEmbed, 99 buildVideoOrPlaylistEmbed,
230 videoFileMaxByResolution, 100 videoFileMaxByResolution,
231 videoFileMinByResolution, 101 videoFileMinByResolution,
diff --git a/client/src/assets/player/videojs-components/peertube-link-button.ts b/client/src/assets/player/videojs-components/peertube-link-button.ts
index e73c95900..98434898c 100644
--- a/client/src/assets/player/videojs-components/peertube-link-button.ts
+++ b/client/src/assets/player/videojs-components/peertube-link-button.ts
@@ -1,11 +1,15 @@
1import { buildVideoLink } from '../utils'
2import videojs from 'video.js' 1import videojs from 'video.js'
2import { buildVideoLink, decorateVideoLink } from '@shared/core-utils'
3import { PeerTubeLinkButtonOptions } from '../peertube-videojs-typings'
3 4
4const Button = videojs.getComponent('Button') 5const Button = videojs.getComponent('Button')
5class PeerTubeLinkButton extends Button { 6class PeerTubeLinkButton extends Button {
7 private shortUUID: string
6 8
7 constructor (player: videojs.Player, options?: videojs.ComponentOptions) { 9 constructor (player: videojs.Player, options?: PeerTubeLinkButtonOptions) {
8 super(player, options) 10 super(player, options as any)
11
12 this.shortUUID = options.shortUUID
9 } 13 }
10 14
11 createEl () { 15 createEl () {
@@ -13,7 +17,7 @@ class PeerTubeLinkButton extends Button {
13 } 17 }
14 18
15 updateHref () { 19 updateHref () {
16 this.el().setAttribute('href', buildVideoLink({ startTime: this.player().currentTime() })) 20 this.el().setAttribute('href', this.buildLink())
17 } 21 }
18 22
19 handleClick () { 23 handleClick () {
@@ -22,7 +26,7 @@ class PeerTubeLinkButton extends Button {
22 26
23 private buildElement () { 27 private buildElement () {
24 const el = videojs.dom.createEl('a', { 28 const el = videojs.dom.createEl('a', {
25 href: buildVideoLink(), 29 href: this.buildLink(),
26 innerHTML: 'PeerTube', 30 innerHTML: 'PeerTube',
27 title: this.player().localize('Video page (new window)'), 31 title: this.player().localize('Video page (new window)'),
28 className: 'vjs-peertube-link', 32 className: 'vjs-peertube-link',
@@ -33,6 +37,12 @@ class PeerTubeLinkButton extends Button {
33 37
34 return el as HTMLButtonElement 38 return el as HTMLButtonElement
35 } 39 }
40
41 private buildLink () {
42 const url = buildVideoLink({ shortUUID: this.shortUUID })
43
44 return decorateVideoLink({ url, startTime: this.player().currentTime() })
45 }
36} 46}
37 47
38videojs.registerComponent('PeerTubeLinkButton', PeerTubeLinkButton) 48videojs.registerComponent('PeerTubeLinkButton', PeerTubeLinkButton)
diff --git a/client/src/assets/player/webtorrent/webtorrent-plugin.ts b/client/src/assets/player/webtorrent/webtorrent-plugin.ts
index b648b29e8..17d369c10 100644
--- a/client/src/assets/player/webtorrent/webtorrent-plugin.ts
+++ b/client/src/assets/player/webtorrent/webtorrent-plugin.ts
@@ -1,9 +1,7 @@
1import videojs from 'video.js' 1import videojs from 'video.js'
2import * as WebTorrent from 'webtorrent' 2import * as WebTorrent from 'webtorrent'
3import { renderVideo } from './video-renderer' 3import { timeToInt } from '@shared/core-utils'
4import { LoadedQualityData, PlayerNetworkInfo, WebtorrentPluginOptions } from '../peertube-videojs-typings' 4import { VideoFile } from '@shared/models'
5import { getRtcConfig, timeToInt, videoFileMaxByResolution, videoFileMinByResolution, isIOS, isSafari } from '../utils'
6import { PeertubeChunkStore } from './peertube-chunk-store'
7import { 5import {
8 getAverageBandwidthInStore, 6 getAverageBandwidthInStore,
9 getStoredMute, 7 getStoredMute,
@@ -11,7 +9,10 @@ import {
11 getStoredVolume, 9 getStoredVolume,
12 saveAverageBandwidth 10 saveAverageBandwidth
13} from '../peertube-player-local-storage' 11} from '../peertube-player-local-storage'
14import { VideoFile } from '@shared/models' 12import { LoadedQualityData, PlayerNetworkInfo, WebtorrentPluginOptions } from '../peertube-videojs-typings'
13import { getRtcConfig, isIOS, videoFileMaxByResolution, videoFileMinByResolution } from '../utils'
14import { PeertubeChunkStore } from './peertube-chunk-store'
15import { renderVideo } from './video-renderer'
15 16
16const CacheChunkStore = require('cache-chunk-store') 17const CacheChunkStore = require('cache-chunk-store')
17 18