diff options
Diffstat (limited to 'client/src/assets/player/shared/manager-options/manager-options-builder.ts')
-rw-r--r-- | client/src/assets/player/shared/manager-options/manager-options-builder.ts | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/client/src/assets/player/shared/manager-options/manager-options-builder.ts b/client/src/assets/player/shared/manager-options/manager-options-builder.ts new file mode 100644 index 000000000..5dab1f7a9 --- /dev/null +++ b/client/src/assets/player/shared/manager-options/manager-options-builder.ts | |||
@@ -0,0 +1,169 @@ | |||
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 } 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 | 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 | ||
35 | videoViewUrl: commonOptions.videoViewUrl, | ||
36 | videoDuration: commonOptions.videoDuration, | ||
37 | userWatching: commonOptions.userWatching, | ||
38 | subtitle: commonOptions.subtitle, | ||
39 | videoCaptions: commonOptions.videoCaptions, | ||
40 | stopTime: commonOptions.stopTime, | ||
41 | isLive: commonOptions.isLive, | ||
42 | videoUUID: commonOptions.videoUUID | ||
43 | } | ||
44 | } | ||
45 | |||
46 | if (commonOptions.playlist) { | ||
47 | plugins.playlist = commonOptions.playlist | ||
48 | } | ||
49 | |||
50 | if (this.mode === 'p2p-media-loader') { | ||
51 | const hlsOptionsBuilder = new HLSOptionsBuilder(this.options, this.p2pMediaLoaderModule) | ||
52 | |||
53 | Object.assign(plugins, hlsOptionsBuilder.getPluginOptions()) | ||
54 | } else if (this.mode === 'webtorrent') { | ||
55 | const webtorrentOptionsBuilder = new WebTorrentOptionsBuilder(this.options, this.getAutoPlayValue(autoplay, alreadyPlayed)) | ||
56 | |||
57 | Object.assign(plugins, webtorrentOptionsBuilder.getPluginOptions()) | ||
58 | |||
59 | // WebTorrent plugin handles autoplay, because we do some hackish stuff in there | ||
60 | autoplay = false | ||
61 | } | ||
62 | |||
63 | const controlBarOptionsBuilder = new ControlBarOptionsBuilder(this.options, this.mode) | ||
64 | |||
65 | const videojsOptions = { | ||
66 | html5, | ||
67 | |||
68 | // We don't use text track settings for now | ||
69 | textTrackSettings: false as any, // FIXME: typings | ||
70 | controls: commonOptions.controls !== undefined ? commonOptions.controls : true, | ||
71 | loop: commonOptions.loop !== undefined ? commonOptions.loop : false, | ||
72 | |||
73 | muted: commonOptions.muted !== undefined | ||
74 | ? commonOptions.muted | ||
75 | : undefined, // Undefined so the player knows it has to check the local storage | ||
76 | |||
77 | autoplay: this.getAutoPlayValue(autoplay, alreadyPlayed), | ||
78 | |||
79 | poster: commonOptions.poster, | ||
80 | inactivityTimeout: commonOptions.inactivityTimeout, | ||
81 | playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2 ], | ||
82 | |||
83 | plugins, | ||
84 | |||
85 | controlBar: { | ||
86 | children: controlBarOptionsBuilder.getChildrenOptions() as any // FIXME: typings | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if (commonOptions.language && !isDefaultLocale(commonOptions.language)) { | ||
91 | Object.assign(videojsOptions, { language: commonOptions.language }) | ||
92 | } | ||
93 | |||
94 | return videojsOptions | ||
95 | } | ||
96 | |||
97 | private getAutoPlayValue (autoplay: any, alreadyPlayed: boolean) { | ||
98 | if (autoplay !== true) return autoplay | ||
99 | |||
100 | // On first play, disable autoplay to avoid issues | ||
101 | // But if the player already played videos, we can safely autoplay next ones | ||
102 | if (isIOS() || isSafari()) { | ||
103 | return alreadyPlayed ? 'play' : false | ||
104 | } | ||
105 | |||
106 | return 'play' | ||
107 | } | ||
108 | |||
109 | getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) { | ||
110 | const content = () => { | ||
111 | const isLoopEnabled = player.options_['loop'] | ||
112 | |||
113 | const items = [ | ||
114 | { | ||
115 | icon: 'repeat', | ||
116 | label: player.localize('Play in loop') + (isLoopEnabled ? '<span class="vjs-icon-tick-white"></span>' : ''), | ||
117 | listener: function () { | ||
118 | player.options_['loop'] = !isLoopEnabled | ||
119 | } | ||
120 | }, | ||
121 | { | ||
122 | label: player.localize('Copy the video URL'), | ||
123 | listener: function () { | ||
124 | copyToClipboard(buildVideoLink({ shortUUID: commonOptions.videoShortUUID })) | ||
125 | } | ||
126 | }, | ||
127 | { | ||
128 | label: player.localize('Copy the video URL at the current time'), | ||
129 | listener: function (this: videojs.Player) { | ||
130 | const url = buildVideoLink({ shortUUID: commonOptions.videoShortUUID }) | ||
131 | |||
132 | copyToClipboard(decorateVideoLink({ url, startTime: this.currentTime() })) | ||
133 | } | ||
134 | }, | ||
135 | { | ||
136 | icon: 'code', | ||
137 | label: player.localize('Copy embed code'), | ||
138 | listener: () => { | ||
139 | copyToClipboard(buildVideoOrPlaylistEmbed(commonOptions.embedUrl, commonOptions.embedTitle)) | ||
140 | } | ||
141 | } | ||
142 | ] | ||
143 | |||
144 | if (this.mode === 'webtorrent') { | ||
145 | items.push({ | ||
146 | label: player.localize('Copy magnet URI'), | ||
147 | listener: function (this: videojs.Player) { | ||
148 | copyToClipboard(this.webtorrent().getCurrentVideoFile().magnetUri) | ||
149 | } | ||
150 | }) | ||
151 | } | ||
152 | |||
153 | items.push({ | ||
154 | icon: 'info', | ||
155 | label: player.localize('Stats for nerds'), | ||
156 | listener: () => { | ||
157 | player.stats().show() | ||
158 | } | ||
159 | }) | ||
160 | |||
161 | return items.map(i => ({ | ||
162 | ...i, | ||
163 | label: `<span class="vjs-icon-${i.icon || 'link-2'}"></span>` + i.label | ||
164 | })) | ||
165 | } | ||
166 | |||
167 | return { content } | ||
168 | } | ||
169 | } | ||