]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/assets/player/shared/manager-options/manager-options-builder.ts
Bumped to version v5.2.1
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / shared / manager-options / manager-options-builder.ts
1 import videojs from 'video.js'
2 import { copyToClipboard } from '@root-helpers/utils'
3 import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
4 import { isIOS, isSafari } from '@root-helpers/web-browser'
5 import { buildVideoLink, decorateVideoLink, pick } from '@shared/core-utils'
6 import { isDefaultLocale } from '@shared/core-utils/i18n'
7 import { VideoJSPluginOptions } from '../../types'
8 import { CommonOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../types/manager-options'
9 import { ControlBarOptionsBuilder } from './control-bar-options-builder'
10 import { HLSOptionsBuilder } from './hls-options-builder'
11 import { WebTorrentOptionsBuilder } from './webtorrent-options-builder'
12
13 export class ManagerOptionsBuilder {
14
15 constructor (
16 private mode: PlayerMode,
17 private options: PeertubePlayerManagerOptions,
18 private p2pMediaLoaderModule?: any
19 ) {
20
21 }
22
23 async getVideojsOptions (alreadyPlayed: boolean): Promise<videojs.PlayerOptions> {
24 const commonOptions = this.options.common
25
26 let autoplay = this.getAutoPlayValue(commonOptions.autoplay, alreadyPlayed)
27 const html5 = {
28 preloadTextTracks: false
29 }
30
31 const plugins: VideoJSPluginOptions = {
32 peertube: {
33 mode: this.mode,
34 autoplay, // Use peertube plugin autoplay because we could get the file by webtorrent
35
36 ...pick(commonOptions, [
37 'videoViewUrl',
38 'videoViewIntervalMs',
39 'authorizationHeader',
40 'startTime',
41 'videoDuration',
42 'subtitle',
43 'videoCaptions',
44 'stopTime',
45 'isLive',
46 'videoUUID'
47 ])
48 },
49 metrics: {
50 mode: this.mode,
51
52 ...pick(commonOptions, [
53 'metricsUrl',
54 'videoUUID'
55 ])
56 }
57 }
58
59 if (commonOptions.playlist) {
60 plugins.playlist = commonOptions.playlist
61 }
62
63 if (this.mode === 'p2p-media-loader') {
64 const hlsOptionsBuilder = new HLSOptionsBuilder(this.options, this.p2pMediaLoaderModule)
65 const options = await hlsOptionsBuilder.getPluginOptions()
66
67 Object.assign(plugins, pick(options, [ 'hlsjs', 'p2pMediaLoader' ]))
68 Object.assign(html5, options.html5)
69 } else if (this.mode === 'webtorrent') {
70 const webtorrentOptionsBuilder = new WebTorrentOptionsBuilder(this.options, this.getAutoPlayValue(autoplay, alreadyPlayed))
71
72 Object.assign(plugins, webtorrentOptionsBuilder.getPluginOptions())
73
74 // WebTorrent plugin handles autoplay, because we do some hackish stuff in there
75 autoplay = false
76 }
77
78 const controlBarOptionsBuilder = new ControlBarOptionsBuilder(this.options, this.mode)
79
80 const videojsOptions = {
81 html5,
82
83 // We don't use text track settings for now
84 textTrackSettings: false as any, // FIXME: typings
85 controls: commonOptions.controls !== undefined ? commonOptions.controls : true,
86 loop: commonOptions.loop !== undefined ? commonOptions.loop : false,
87
88 muted: commonOptions.muted !== undefined
89 ? commonOptions.muted
90 : undefined, // Undefined so the player knows it has to check the local storage
91
92 autoplay: this.getAutoPlayValue(autoplay, alreadyPlayed),
93
94 poster: commonOptions.poster,
95 inactivityTimeout: commonOptions.inactivityTimeout,
96 playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2 ],
97
98 plugins,
99
100 controlBar: {
101 children: controlBarOptionsBuilder.getChildrenOptions() as any // FIXME: typings
102 }
103 }
104
105 if (commonOptions.language && !isDefaultLocale(commonOptions.language)) {
106 Object.assign(videojsOptions, { language: commonOptions.language })
107 }
108
109 return videojsOptions
110 }
111
112 private getAutoPlayValue (autoplay: videojs.Autoplay, alreadyPlayed: boolean) {
113 if (autoplay !== true) return autoplay
114
115 // On first play, disable autoplay to avoid issues
116 // But if the player already played videos, we can safely autoplay next ones
117 if (isIOS() || isSafari()) {
118 return alreadyPlayed ? 'play' : false
119 }
120
121 return this.options.common.forceAutoplay
122 ? 'any'
123 : 'play'
124 }
125
126 getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) {
127 const content = () => {
128 const isLoopEnabled = player.options_['loop']
129
130 const items = [
131 {
132 icon: 'repeat',
133 label: player.localize('Play in loop') + (isLoopEnabled ? '<span class="vjs-icon-tick-white"></span>' : ''),
134 listener: function () {
135 player.options_['loop'] = !isLoopEnabled
136 }
137 },
138 {
139 label: player.localize('Copy the video URL'),
140 listener: function () {
141 copyToClipboard(buildVideoLink({ shortUUID: commonOptions.videoShortUUID }))
142 }
143 },
144 {
145 label: player.localize('Copy the video URL at the current time'),
146 listener: function (this: videojs.Player) {
147 const url = buildVideoLink({ shortUUID: commonOptions.videoShortUUID })
148
149 copyToClipboard(decorateVideoLink({ url, startTime: this.currentTime() }))
150 }
151 },
152 {
153 icon: 'code',
154 label: player.localize('Copy embed code'),
155 listener: () => {
156 copyToClipboard(buildVideoOrPlaylistEmbed({ embedUrl: commonOptions.embedUrl, embedTitle: commonOptions.embedTitle }))
157 }
158 }
159 ]
160
161 if (this.mode === 'webtorrent') {
162 items.push({
163 label: player.localize('Copy magnet URI'),
164 listener: function (this: videojs.Player) {
165 copyToClipboard(this.webtorrent().getCurrentVideoFile().magnetUri)
166 }
167 })
168 }
169
170 items.push({
171 icon: 'info',
172 label: player.localize('Stats for nerds'),
173 listener: () => {
174 player.stats().show()
175 }
176 })
177
178 return items.map(i => ({
179 ...i,
180 label: `<span class="vjs-icon-${i.icon || 'link-2'}"></span>` + i.label
181 }))
182 }
183
184 return { content }
185 }
186 }