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