aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts9
-rw-r--r--client/src/assets/player/p2p-media-loader/redundancy-url-manager.ts57
-rw-r--r--client/src/assets/player/p2p-media-loader/segment-url-builder.ts20
-rw-r--r--client/src/assets/player/peertube-player-manager.ts7
-rw-r--r--client/src/assets/player/peertube-videojs-typings.ts3
5 files changed, 72 insertions, 24 deletions
diff --git a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
index 8fb7ba2ea..0c8c612ee 100644
--- a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
+++ b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
@@ -3,7 +3,7 @@
3import * as videojs from 'video.js' 3import * as videojs from 'video.js'
4import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo, VideoJSComponentInterface } from '../peertube-videojs-typings' 4import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo, VideoJSComponentInterface } from '../peertube-videojs-typings'
5import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs' 5import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs'
6import { Events } from 'p2p-media-loader-core' 6import { Events, Segment } from 'p2p-media-loader-core'
7import { timeToInt } from '../utils' 7import { timeToInt } from '../utils'
8 8
9// videojs-hlsjs-plugin needs videojs in window 9// videojs-hlsjs-plugin needs videojs in window
@@ -57,7 +57,6 @@ class P2pMediaLoaderPlugin extends Plugin {
57 initVideoJsContribHlsJsPlayer(player) 57 initVideoJsContribHlsJsPlayer(player)
58 58
59 this.startTime = timeToInt(options.startTime) 59 this.startTime = timeToInt(options.startTime)
60 console.log(this.startTime)
61 60
62 player.src({ 61 player.src({
63 type: options.type, 62 type: options.type,
@@ -90,11 +89,13 @@ class P2pMediaLoaderPlugin extends Plugin {
90 this.trigger('resolutionChange', { auto: this.hlsjs.autoLevelEnabled, resolutionId: data.height }) 89 this.trigger('resolutionChange', { auto: this.hlsjs.autoLevelEnabled, resolutionId: data.height })
91 }) 90 })
92 91
93 this.p2pEngine.on(Events.SegmentError, (segment, err) => { 92 this.p2pEngine.on(Events.SegmentError, (segment: Segment, err) => {
94 console.error('Segment error.', segment, err) 93 console.error('Segment error.', segment, err)
94
95 this.options.redundancyUrlManager.removeByOriginUrl(segment.url)
95 }) 96 })
96 97
97 this.statsP2PBytes.numPeers = 1 + this.options.redundancyBaseUrls.length 98 this.statsP2PBytes.numPeers = 1 + this.options.redundancyUrlManager.countBaseUrls()
98 99
99 this.runStats() 100 this.runStats()
100 101
diff --git a/client/src/assets/player/p2p-media-loader/redundancy-url-manager.ts b/client/src/assets/player/p2p-media-loader/redundancy-url-manager.ts
new file mode 100644
index 000000000..7fc2b6ab1
--- /dev/null
+++ b/client/src/assets/player/p2p-media-loader/redundancy-url-manager.ts
@@ -0,0 +1,57 @@
1import { basename, dirname } from 'path'
2
3class RedundancyUrlManager {
4
5 // Remember by what new URL we replaced an origin URL
6 private replacedSegmentUrls: { [originUrl: string]: string } = {}
7
8 constructor (private baseUrls: string[] = []) {
9 // empty
10 }
11
12 removeBySegmentUrl (segmentUrl: string) {
13 console.log('Removing redundancy of segment URL %s.', segmentUrl)
14
15 const baseUrl = dirname(segmentUrl)
16
17 this.baseUrls = this.baseUrls.filter(u => u !== baseUrl && u !== baseUrl + '/')
18 }
19
20 removeByOriginUrl (originUrl: string) {
21 const replaced = this.replacedSegmentUrls[originUrl]
22 if (!replaced) return
23
24 return this.removeBySegmentUrl(replaced)
25 }
26
27 buildUrl (url: string) {
28 delete this.replacedSegmentUrls[url]
29
30 const max = this.baseUrls.length + 1
31 const i = this.getRandomInt(max)
32
33 if (i === max - 1) return url
34
35 const newBaseUrl = this.baseUrls[i]
36 const slashPart = newBaseUrl.endsWith('/') ? '' : '/'
37
38 const newUrl = newBaseUrl + slashPart + basename(url)
39 this.replacedSegmentUrls[url] = newUrl
40
41 return newUrl
42 }
43
44 countBaseUrls () {
45 return this.baseUrls.length
46 }
47
48 private getRandomInt (max: number) {
49 return Math.floor(Math.random() * Math.floor(max))
50 }
51}
52
53// ---------------------------------------------------------------------------
54
55export {
56 RedundancyUrlManager
57}
diff --git a/client/src/assets/player/p2p-media-loader/segment-url-builder.ts b/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
index fb990a19d..039777cea 100644
--- a/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
+++ b/client/src/assets/player/p2p-media-loader/segment-url-builder.ts
@@ -1,17 +1,9 @@
1import { basename } from 'path'
2import { Segment } from 'p2p-media-loader-core' 1import { Segment } from 'p2p-media-loader-core'
2import { RedundancyUrlManager } from './redundancy-url-manager'
3 3
4function segmentUrlBuilderFactory (baseUrls: string[]) { 4function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager) {
5 return function segmentBuilder (segment: Segment) { 5 return function segmentBuilder (segment: Segment) {
6 const max = baseUrls.length + 1 6 return redundancyUrlManager.buildUrl(segment.url)
7 const i = getRandomInt(max)
8
9 if (i === max - 1) return segment.url
10
11 const newBaseUrl = baseUrls[i]
12 const middlePart = newBaseUrl.endsWith('/') ? '' : '/'
13
14 return newBaseUrl + middlePart + basename(segment.url)
15 } 7 }
16} 8}
17 9
@@ -20,9 +12,3 @@ function segmentUrlBuilderFactory (baseUrls: string[]) {
20export { 12export {
21 segmentUrlBuilderFactory 13 segmentUrlBuilderFactory
22} 14}
23
24// ---------------------------------------------------------------------------
25
26function getRandomInt (max: number) {
27 return Math.floor(Math.random() * Math.floor(max))
28}
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts
index 6c8b13087..7be9f8719 100644
--- a/client/src/assets/player/peertube-player-manager.ts
+++ b/client/src/assets/player/peertube-player-manager.ts
@@ -17,6 +17,7 @@ import { buildVideoEmbed, buildVideoLink, copyToClipboard, getRtcConfig } from '
17import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n' 17import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
18import { segmentValidatorFactory } from './p2p-media-loader/segment-validator' 18import { segmentValidatorFactory } from './p2p-media-loader/segment-validator'
19import { segmentUrlBuilderFactory } from './p2p-media-loader/segment-url-builder' 19import { segmentUrlBuilderFactory } from './p2p-media-loader/segment-url-builder'
20import { RedundancyUrlManager } from './p2p-media-loader/redundancy-url-manager'
20 21
21// Change 'Playback Rate' to 'Speed' (smaller for our settings menu) 22// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
22videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed' 23videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed'
@@ -226,8 +227,10 @@ export class PeertubePlayerManager {
226 } 227 }
227 228
228 if (mode === 'p2p-media-loader') { 229 if (mode === 'p2p-media-loader') {
230 const redundancyUrlManager = new RedundancyUrlManager(options.p2pMediaLoader.redundancyBaseUrls)
231
229 const p2pMediaLoader: P2PMediaLoaderPluginOptions = { 232 const p2pMediaLoader: P2PMediaLoaderPluginOptions = {
230 redundancyBaseUrls: options.p2pMediaLoader.redundancyBaseUrls, 233 redundancyUrlManager,
231 type: 'application/x-mpegURL', 234 type: 'application/x-mpegURL',
232 startTime: commonOptions.startTime, 235 startTime: commonOptions.startTime,
233 src: p2pMediaLoaderOptions.playlistUrl 236 src: p2pMediaLoaderOptions.playlistUrl
@@ -242,7 +245,7 @@ export class PeertubePlayerManager {
242 segmentValidator: segmentValidatorFactory(options.p2pMediaLoader.segmentsSha256Url), 245 segmentValidator: segmentValidatorFactory(options.p2pMediaLoader.segmentsSha256Url),
243 rtcConfig: getRtcConfig(), 246 rtcConfig: getRtcConfig(),
244 requiredSegmentsPriority: 5, 247 requiredSegmentsPriority: 5,
245 segmentUrlBuilder: segmentUrlBuilderFactory(options.p2pMediaLoader.redundancyBaseUrls) 248 segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager)
246 }, 249 },
247 segments: { 250 segments: {
248 swarmId: p2pMediaLoaderOptions.playlistUrl 251 swarmId: p2pMediaLoaderOptions.playlistUrl
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts
index a96b0bc8c..b7f2eec94 100644
--- a/client/src/assets/player/peertube-videojs-typings.ts
+++ b/client/src/assets/player/peertube-videojs-typings.ts
@@ -7,6 +7,7 @@ import { PeerTubePlugin } from './peertube-plugin'
7import { WebTorrentPlugin } from './webtorrent/webtorrent-plugin' 7import { WebTorrentPlugin } from './webtorrent/webtorrent-plugin'
8import { P2pMediaLoaderPlugin } from './p2p-media-loader/p2p-media-loader-plugin' 8import { P2pMediaLoaderPlugin } from './p2p-media-loader/p2p-media-loader-plugin'
9import { PlayerMode } from './peertube-player-manager' 9import { PlayerMode } from './peertube-player-manager'
10import { RedundancyUrlManager } from './p2p-media-loader/redundancy-url-manager'
10 11
11declare namespace videojs { 12declare namespace videojs {
12 interface Player { 13 interface Player {
@@ -62,7 +63,7 @@ type WebtorrentPluginOptions = {
62} 63}
63 64
64type P2PMediaLoaderPluginOptions = { 65type P2PMediaLoaderPluginOptions = {
65 redundancyBaseUrls: string[] 66 redundancyUrlManager: RedundancyUrlManager
66 type: string 67 type: string
67 src: string 68 src: string
68 69