Merge branch 'ctrl-number-hotkeys' into 'develop'
[oweals/peertube.git] / client / src / assets / player / peertube-player.ts
1 import { VideoFile } from '../../../../shared/models/videos'
2
3 import 'videojs-hotkeys'
4 import 'videojs-dock'
5 import 'videojs-contextmenu'
6 import 'videojs-contextmenu-ui'
7 import './peertube-link-button'
8 import './resolution-menu-button'
9 import './settings-menu-button'
10 import './webtorrent-info-button'
11 import './peertube-videojs-plugin'
12 import './peertube-load-progress-bar'
13 import './theater-button'
14 import { videojsUntyped } from './peertube-videojs-typings'
15 import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils'
16 import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
17
18 // Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
19 videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed'
20
21 function getVideojsOptions (options: {
22   autoplay: boolean,
23   playerElement: HTMLVideoElement,
24   videoViewUrl: string,
25   videoDuration: number,
26   videoFiles: VideoFile[],
27   enableHotkeys: boolean,
28   inactivityTimeout: number,
29   peertubeLink: boolean,
30   poster: string,
31   startTime: number
32   theaterMode: boolean
33 }) {
34   const videojsOptions = {
35     controls: true,
36     poster: options.poster,
37     autoplay: false,
38     inactivityTimeout: options.inactivityTimeout,
39     playbackRates: [ 0.5, 1, 1.5, 2 ],
40     plugins: {
41       peertube: {
42         autoplay: options.autoplay, // Use peertube plugin autoplay because we get the file by webtorrent
43         videoFiles: options.videoFiles,
44         playerElement: options.playerElement,
45         videoViewUrl: options.videoViewUrl,
46         videoDuration: options.videoDuration,
47         startTime: options.startTime
48       }
49     },
50     controlBar: {
51       children: getControlBarChildren(options)
52     }
53   }
54
55   if (options.enableHotkeys === true) {
56     Object.assign(videojsOptions.plugins, {
57       hotkeys: {
58         enableVolumeScroll: false,
59         enableModifiersForNumbers: false
60       }
61     })
62   }
63
64   return videojsOptions
65 }
66
67 function getControlBarChildren (options: {
68   peertubeLink: boolean
69   theaterMode: boolean
70 }) {
71   const children = {
72     'playToggle': {},
73     'currentTimeDisplay': {},
74     'timeDivider': {},
75     'durationDisplay': {},
76     'liveDisplay': {},
77
78     'flexibleWidthSpacer': {},
79     'progressControl': {
80       children: {
81         'seekBar': {
82           children: {
83             'peerTubeLoadProgressBar': {},
84             'mouseTimeDisplay': {},
85             'playProgressBar': {}
86           }
87         }
88       }
89     },
90
91     'webTorrentButton': {},
92
93     'muteToggle': {},
94     'volumeControl': {},
95
96     'settingsButton': {
97       setup: {
98         maxHeightOffset: 40
99       },
100       entries: [
101         'resolutionMenuButton',
102         'playbackRateMenuButton'
103       ]
104     }
105   }
106
107   if (options.peertubeLink === true) {
108     Object.assign(children, {
109       'peerTubeLinkButton': {}
110     })
111   }
112
113   if (options.theaterMode === true) {
114     Object.assign(children, {
115       'theaterButton': {}
116     })
117   }
118
119   Object.assign(children, {
120     'fullscreenToggle': {}
121   })
122
123   return children
124 }
125
126 function addContextMenu (player: any, videoEmbedUrl: string) {
127   player.contextmenuUI({
128     content: [
129       {
130         label: player.localize('Copy the video URL'),
131         listener: function () {
132           copyToClipboard(buildVideoLink())
133         }
134       },
135       {
136         label: player.localize('Copy the video URL at the current time'),
137         listener: function () {
138           const player = this
139           copyToClipboard(buildVideoLink(player.currentTime()))
140         }
141       },
142       {
143         label: player.localize('Copy embed code'),
144         listener: () => {
145           copyToClipboard(buildVideoEmbed(videoEmbedUrl))
146         }
147       },
148       {
149         label: player.localize('Copy magnet URI'),
150         listener: function () {
151           const player = this
152           copyToClipboard(player.peertube().getCurrentVideoFile().magnetUri)
153         }
154       }
155     ]
156   })
157 }
158
159 function loadLocale (serverUrl: string, videojs: any, locale: string) {
160   const completeLocale = getCompleteLocale(locale)
161
162   if (!is18nLocale(completeLocale) || isDefaultLocale(completeLocale)) return Promise.resolve(undefined)
163
164   return fetch(serverUrl + '/client/locales/' + completeLocale + '/player.json')
165     .then(res => res.json())
166     .then(json => videojs.addLanguage(getShortLocale(completeLocale), json))
167 }
168
169 export {
170   loadLocale,
171   getVideojsOptions,
172   addContextMenu
173 }