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