]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/standalone/videos/shared/player-manager-options.ts
Add ability to list comments on local videos
[github/Chocobozzz/PeerTube.git] / client / src / standalone / videos / shared / player-manager-options.ts
CommitLineData
f1a0f3b7
C
1import { peertubeTranslate } from '../../../../../shared/core-utils/i18n'
2import {
3 HTMLServerConfig,
4 LiveVideo,
5 Video,
6 VideoCaption,
7 VideoDetails,
8 VideoPlaylistElement,
aeb112ed 9 VideoState,
f1a0f3b7
C
10 VideoStreamingPlaylistType
11} from '../../../../../shared/models'
12import { P2PMediaLoaderOptions, PeertubePlayerManagerOptions, PlayerMode, VideoJSCaption } from '../../../assets/player'
13import {
14 getBoolOrDefault,
15 getParamString,
16 getParamToggle,
17 isP2PEnabled,
42b40636 18 logger,
f1a0f3b7
C
19 peertubeLocalStorage,
20 UserLocalStorageKeys
21} from '../../../root-helpers'
22import { PeerTubePlugin } from './peertube-plugin'
23import { PlayerHTML } from './player-html'
24import { PlaylistTracker } from './playlist-tracker'
25import { Translations } from './translations'
26import { VideoFetcher } from './video-fetcher'
27
28export class PlayerManagerOptions {
29 private autoplay: boolean
30
31 private controls: boolean
32 private controlBar: boolean
33
34 private muted: boolean
35 private loop: boolean
36 private subtitle: string
37 private enableApi = false
38 private startTime: number | string = 0
39 private stopTime: number | string
40
41 private title: boolean
42 private warningTitle: boolean
43 private peertubeLink: boolean
44 private p2pEnabled: boolean
45 private bigPlayBackgroundColor: string
46 private foregroundColor: string
47
48 private mode: PlayerMode
49 private scope = 'peertube'
50
51 constructor (
52 private readonly playerHTML: PlayerHTML,
53 private readonly videoFetcher: VideoFetcher,
54 private readonly peertubePlugin: PeerTubePlugin
55 ) {}
56
57 hasAPIEnabled () {
58 return this.enableApi
59 }
60
61 hasAutoplay () {
62 return this.autoplay
63 }
64
65 hasControls () {
66 return this.controls
67 }
68
69 hasTitle () {
70 return this.title
71 }
72
73 hasWarningTitle () {
74 return this.warningTitle
75 }
76
77 hasP2PEnabled () {
78 return !!this.p2pEnabled
79 }
80
81 hasBigPlayBackgroundColor () {
82 return !!this.bigPlayBackgroundColor
83 }
84
85 getBigPlayBackgroundColor () {
86 return this.bigPlayBackgroundColor
87 }
88
89 hasForegroundColor () {
90 return !!this.foregroundColor
91 }
92
93 getForegroundColor () {
94 return this.foregroundColor
95 }
96
97 getMode () {
98 return this.mode
99 }
100
101 getScope () {
102 return this.scope
103 }
104
105 // ---------------------------------------------------------------------------
106
107 loadParams (config: HTMLServerConfig, video: VideoDetails) {
108 try {
109 const params = new URL(window.location.toString()).searchParams
110
111 this.autoplay = getParamToggle(params, 'autoplay', false)
aeb112ed
C
112 // Disable auto play on live videos that are not streamed
113 if (video.state.id === VideoState.LIVE_ENDED || video.state.id === VideoState.WAITING_FOR_LIVE) {
114 this.autoplay = false
115 }
f1a0f3b7
C
116
117 this.controls = getParamToggle(params, 'controls', true)
118 this.controlBar = getParamToggle(params, 'controlBar', true)
119
120 this.muted = getParamToggle(params, 'muted', undefined)
121 this.loop = getParamToggle(params, 'loop', false)
122 this.title = getParamToggle(params, 'title', true)
123 this.enableApi = getParamToggle(params, 'api', this.enableApi)
124 this.warningTitle = getParamToggle(params, 'warningTitle', true)
125 this.peertubeLink = getParamToggle(params, 'peertubeLink', true)
126 this.p2pEnabled = getParamToggle(params, 'p2p', this.isP2PEnabled(config, video))
127
128 this.scope = getParamString(params, 'scope', this.scope)
129 this.subtitle = getParamString(params, 'subtitle')
130 this.startTime = getParamString(params, 'start')
131 this.stopTime = getParamString(params, 'stop')
132
133 this.bigPlayBackgroundColor = getParamString(params, 'bigPlayBackgroundColor')
134 this.foregroundColor = getParamString(params, 'foregroundColor')
135
136 const modeParam = getParamString(params, 'mode')
137
138 if (modeParam) {
139 if (modeParam === 'p2p-media-loader') this.mode = 'p2p-media-loader'
140 else this.mode = 'webtorrent'
141 } else {
142 if (Array.isArray(video.streamingPlaylists) && video.streamingPlaylists.length !== 0) this.mode = 'p2p-media-loader'
143 else this.mode = 'webtorrent'
144 }
145 } catch (err) {
42b40636 146 logger.error('Cannot get params from URL.', err)
f1a0f3b7
C
147 }
148 }
149
150 // ---------------------------------------------------------------------------
151
152 async getPlayerOptions (options: {
153 video: VideoDetails
154 captionsResponse: Response
155 live?: LiveVideo
156
bd2b51be
C
157 serverConfig: HTMLServerConfig
158
f1a0f3b7
C
159 alreadyHadPlayer: boolean
160
161 translations: Translations
162
163 playlistTracker?: PlaylistTracker
164 playNextPlaylistVideo?: () => any
165 playPreviousPlaylistVideo?: () => any
166 onVideoUpdate?: (uuid: string) => any
167 }) {
168 const {
169 video,
170 captionsResponse,
171 alreadyHadPlayer,
172 translations,
173 playlistTracker,
bd2b51be
C
174 live,
175 serverConfig
f1a0f3b7
C
176 } = options
177
178 const videoCaptions = await this.buildCaptions(captionsResponse, translations)
179
180 const playerOptions: PeertubePlayerManagerOptions = {
181 common: {
182 // Autoplay in playlist mode
183 autoplay: alreadyHadPlayer ? true : this.autoplay,
184
185 controls: this.controls,
186 controlBar: this.controlBar,
187
188 muted: this.muted,
189 loop: this.loop,
190
191 p2pEnabled: this.p2pEnabled,
192
193 captions: videoCaptions.length !== 0,
194 subtitle: this.subtitle,
195
196 startTime: playlistTracker
197 ? playlistTracker.getCurrentElement().startTimestamp
198 : this.startTime,
199 stopTime: playlistTracker
200 ? playlistTracker.getCurrentElement().stopTimestamp
201 : this.stopTime,
202
203 videoCaptions,
204 inactivityTimeout: 2500,
205 videoViewUrl: this.videoFetcher.getVideoViewsUrl(video.uuid),
206
207 videoShortUUID: video.shortUUID,
208 videoUUID: video.uuid,
209
210 playerElement: this.playerHTML.getPlayerElement(),
211 onPlayerElementChange: (element: HTMLVideoElement) => {
212 this.playerHTML.setPlayerElement(element)
213 },
214
215 videoDuration: video.duration,
216 enableHotkeys: true,
bd2b51be 217
f1a0f3b7 218 peertubeLink: this.peertubeLink,
bd2b51be
C
219 instanceName: serverConfig.instance.name,
220
f1a0f3b7
C
221 poster: window.location.origin + video.previewPath,
222 theaterButton: false,
223
224 serverUrl: window.location.origin,
225 language: navigator.language,
226 embedUrl: window.location.origin + video.embedPath,
227 embedTitle: video.name,
228
229 errorNotifier: () => {
230 // Empty, we don't have a notifier in the embed
231 },
232
233 ...this.buildLiveOptions(video, live),
234
235 ...this.buildPlaylistOptions(options)
236 },
237
238 webtorrent: {
239 videoFiles: video.files
240 },
241
242 ...this.buildP2PMediaLoaderOptions(video),
243
244 pluginsManager: this.peertubePlugin.getPluginsManager()
245 }
246
247 return playerOptions
248 }
249
250 private buildLiveOptions (video: VideoDetails, live: LiveVideo) {
251 if (!video.isLive) return { isLive: false }
252
253 return {
254 isLive: true,
255 liveOptions: {
256 latencyMode: live.latencyMode
257 }
258 }
259 }
260
261 private buildPlaylistOptions (options: {
262 playlistTracker?: PlaylistTracker
263 playNextPlaylistVideo?: () => any
264 playPreviousPlaylistVideo?: () => any
265 onVideoUpdate?: (uuid: string) => any
266 }) {
267 const { playlistTracker, playNextPlaylistVideo, playPreviousPlaylistVideo, onVideoUpdate } = options
268
269 if (!playlistTracker) return {}
270
271 return {
272 playlist: {
273 elements: playlistTracker.getPlaylistElements(),
274 playlist: playlistTracker.getPlaylist(),
275
276 getCurrentPosition: () => playlistTracker.getCurrentPosition(),
277
278 onItemClicked: (videoPlaylistElement: VideoPlaylistElement) => {
279 playlistTracker.setCurrentElement(videoPlaylistElement)
280
281 onVideoUpdate(videoPlaylistElement.video.uuid)
282 }
283 },
284
285 nextVideo: () => playNextPlaylistVideo(),
286 hasNextVideo: () => playlistTracker.hasNextPlaylistElement(),
287
288 previousVideo: () => playPreviousPlaylistVideo(),
289 hasPreviousVideo: () => playlistTracker.hasPreviousPlaylistElement()
290 }
291 }
292
293 private buildP2PMediaLoaderOptions (video: VideoDetails) {
294 if (this.mode !== 'p2p-media-loader') return {}
295
296 const hlsPlaylist = video.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
297
298 return {
299 p2pMediaLoader: {
300 playlistUrl: hlsPlaylist.playlistUrl,
301 segmentsSha256Url: hlsPlaylist.segmentsSha256Url,
302 redundancyBaseUrls: hlsPlaylist.redundancies.map(r => r.baseUrl),
303 trackerAnnounce: video.trackerUrls,
304 videoFiles: hlsPlaylist.files
305 } as P2PMediaLoaderOptions
306 }
307 }
308
309 // ---------------------------------------------------------------------------
310
311 private async buildCaptions (captionsResponse: Response, translations: Translations): Promise<VideoJSCaption[]> {
312 if (captionsResponse.ok) {
313 const { data } = await captionsResponse.json()
314
315 return data.map((c: VideoCaption) => ({
316 label: peertubeTranslate(c.language.label, translations),
317 language: c.language.id,
318 src: window.location.origin + c.captionPath
319 }))
320 }
321
322 return []
323 }
324
325 // ---------------------------------------------------------------------------
326
327 private isP2PEnabled (config: HTMLServerConfig, video: Video) {
328 const userP2PEnabled = getBoolOrDefault(
329 peertubeLocalStorage.getItem(UserLocalStorageKeys.P2P_ENABLED),
330 config.defaults.p2p.embed.enabled
331 )
332
333 return isP2PEnabled(video, config, userP2PEnabled)
334 }
335}