diff options
Diffstat (limited to 'client/src/assets/player/peertube-videojs-plugin.ts')
-rw-r--r-- | client/src/assets/player/peertube-videojs-plugin.ts | 100 |
1 files changed, 95 insertions, 5 deletions
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index c54d8b5ea..4ba37b7d9 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts | |||
@@ -2,9 +2,24 @@ | |||
2 | 2 | ||
3 | import videojs, { Player } from 'video.js' | 3 | import videojs, { Player } from 'video.js' |
4 | import * as WebTorrent from 'webtorrent' | 4 | import * as WebTorrent from 'webtorrent' |
5 | import { VideoFile } from '../../../../shared' | ||
5 | 6 | ||
6 | import { renderVideo } from './video-renderer' | 7 | import { renderVideo } from './video-renderer' |
7 | import { VideoFile } from '../../../../shared' | 8 | |
9 | // https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts | ||
10 | // Don't import all Angular stuff, just copy the code with shame | ||
11 | const dictionaryBytes: Array<{max: number, type: string}> = [ | ||
12 | { max: 1024, type: 'B' }, | ||
13 | { max: 1048576, type: 'KB' }, | ||
14 | { max: 1073741824, type: 'MB' }, | ||
15 | { max: 1.0995116e12, type: 'GB' } | ||
16 | ] | ||
17 | function bytes (value) { | ||
18 | const format = dictionaryBytes.find(d => value < d.max) || dictionaryBytes[dictionaryBytes.length - 1] | ||
19 | const calc = Math.floor(value / (format.max / 1024)).toString() | ||
20 | |||
21 | return [ calc, format.type ] | ||
22 | } | ||
8 | 23 | ||
9 | // videojs typings don't have some method we need | 24 | // videojs typings don't have some method we need |
10 | const videojsUntyped = videojs as any | 25 | const videojsUntyped = videojs as any |
@@ -62,6 +77,7 @@ const ResolutionMenuButton = videojsUntyped.extend(MenuButton, { | |||
62 | 77 | ||
63 | update: function () { | 78 | update: function () { |
64 | this.label.innerHTML = this.player_.getCurrentResolutionLabel() | 79 | this.label.innerHTML = this.player_.getCurrentResolutionLabel() |
80 | this.hide() | ||
65 | return MenuButton.prototype.update.call(this) | 81 | return MenuButton.prototype.update.call(this) |
66 | }, | 82 | }, |
67 | 83 | ||
@@ -74,8 +90,7 @@ MenuButton.registerComponent('ResolutionMenuButton', ResolutionMenuButton) | |||
74 | const Button = videojsUntyped.getComponent('Button') | 90 | const Button = videojsUntyped.getComponent('Button') |
75 | const PeertubeLinkButton = videojsUntyped.extend(Button, { | 91 | const PeertubeLinkButton = videojsUntyped.extend(Button, { |
76 | constructor: function (player) { | 92 | constructor: function (player) { |
77 | Button.apply(this, arguments) | 93 | Button.call(this, player) |
78 | this.player = player | ||
79 | }, | 94 | }, |
80 | 95 | ||
81 | createEl: function () { | 96 | createEl: function () { |
@@ -90,11 +105,80 @@ const PeertubeLinkButton = videojsUntyped.extend(Button, { | |||
90 | }, | 105 | }, |
91 | 106 | ||
92 | handleClick: function () { | 107 | handleClick: function () { |
93 | this.player.pause() | 108 | this.player_.pause() |
94 | } | 109 | } |
95 | }) | 110 | }) |
96 | Button.registerComponent('PeerTubeLinkButton', PeertubeLinkButton) | 111 | Button.registerComponent('PeerTubeLinkButton', PeertubeLinkButton) |
97 | 112 | ||
113 | const WebTorrentButton = videojsUntyped.extend(Button, { | ||
114 | constructor: function (player) { | ||
115 | Button.call(this, player) | ||
116 | }, | ||
117 | |||
118 | createEl: function () { | ||
119 | const div = document.createElement('div') | ||
120 | const subDiv = document.createElement('div') | ||
121 | div.appendChild(subDiv) | ||
122 | |||
123 | const downloadIcon = document.createElement('span') | ||
124 | downloadIcon.classList.add('icon', 'icon-download') | ||
125 | subDiv.appendChild(downloadIcon) | ||
126 | |||
127 | const downloadSpeedText = document.createElement('span') | ||
128 | downloadSpeedText.classList.add('download-speed-text') | ||
129 | const downloadSpeedNumber = document.createElement('span') | ||
130 | downloadSpeedNumber.classList.add('download-speed-number') | ||
131 | const downloadSpeedUnit = document.createElement('span') | ||
132 | downloadSpeedText.appendChild(downloadSpeedNumber) | ||
133 | downloadSpeedText.appendChild(downloadSpeedUnit) | ||
134 | subDiv.appendChild(downloadSpeedText) | ||
135 | |||
136 | const uploadIcon = document.createElement('span') | ||
137 | uploadIcon.classList.add('icon', 'icon-upload') | ||
138 | subDiv.appendChild(uploadIcon) | ||
139 | |||
140 | const uploadSpeedText = document.createElement('span') | ||
141 | uploadSpeedText.classList.add('upload-speed-text') | ||
142 | const uploadSpeedNumber = document.createElement('span') | ||
143 | uploadSpeedNumber.classList.add('upload-speed-number') | ||
144 | const uploadSpeedUnit = document.createElement('span') | ||
145 | uploadSpeedText.appendChild(uploadSpeedNumber) | ||
146 | uploadSpeedText.appendChild(uploadSpeedUnit) | ||
147 | subDiv.appendChild(uploadSpeedText) | ||
148 | |||
149 | const peersText = document.createElement('span') | ||
150 | peersText.textContent = ' peers' | ||
151 | peersText.classList.add('peers-text') | ||
152 | const peersNumber = document.createElement('span') | ||
153 | peersNumber.classList.add('peers-number') | ||
154 | subDiv.appendChild(peersNumber) | ||
155 | subDiv.appendChild(peersText) | ||
156 | |||
157 | div.className = 'vjs-webtorrent' | ||
158 | // Hide the stats before we get the info | ||
159 | subDiv.className = 'vjs-webtorrent-hidden' | ||
160 | |||
161 | this.player_.on('torrentInfo', (event, data) => { | ||
162 | const downloadSpeed = bytes(data.downloadSpeed) | ||
163 | const uploadSpeed = bytes(data.uploadSpeed) | ||
164 | const numPeers = data.numPeers | ||
165 | |||
166 | downloadSpeedNumber.textContent = downloadSpeed[0] | ||
167 | downloadSpeedUnit.textContent = ' ' + downloadSpeed[1] | ||
168 | |||
169 | uploadSpeedNumber.textContent = uploadSpeed[0] | ||
170 | uploadSpeedUnit.textContent = ' ' + uploadSpeed[1] | ||
171 | |||
172 | peersNumber.textContent = numPeers | ||
173 | |||
174 | subDiv.className = 'vjs-webtorrent-displayed' | ||
175 | }) | ||
176 | |||
177 | return div | ||
178 | } | ||
179 | }) | ||
180 | Button.registerComponent('WebTorrentButton', WebTorrentButton) | ||
181 | |||
98 | type PeertubePluginOptions = { | 182 | type PeertubePluginOptions = { |
99 | videoFiles: VideoFile[] | 183 | videoFiles: VideoFile[] |
100 | playerElement: HTMLVideoElement | 184 | playerElement: HTMLVideoElement |
@@ -223,6 +307,12 @@ const peertubePlugin = function (options: PeertubePluginOptions) { | |||
223 | } | 307 | } |
224 | } | 308 | } |
225 | 309 | ||
310 | const webTorrentButton = new WebTorrentButton(player) | ||
311 | controlBar.webTorrent = controlBar.el().insertBefore(webTorrentButton.el(), controlBar.progressControl.el()) | ||
312 | controlBar.webTorrent.dispose = function () { | ||
313 | this.parentNode.removeChild(this) | ||
314 | } | ||
315 | |||
226 | if (options.autoplay === true) { | 316 | if (options.autoplay === true) { |
227 | player.updateVideoFile() | 317 | player.updateVideoFile() |
228 | } else { | 318 | } else { |
@@ -245,7 +335,7 @@ const peertubePlugin = function (options: PeertubePluginOptions) { | |||
245 | }, 1000) | 335 | }, 1000) |
246 | }) | 336 | }) |
247 | 337 | ||
248 | function handleError (err: Error|string) { | 338 | function handleError (err: Error | string) { |
249 | return player.trigger('customError', { err }) | 339 | return player.trigger('customError', { err }) |
250 | } | 340 | } |
251 | } | 341 | } |