diff options
author | Chocobozzz <me@florianbigard.com> | 2023-07-21 11:42:52 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-07-21 11:42:52 +0200 |
commit | c6867725fb8e3dfbc2018a37ed5a963103587cb6 (patch) | |
tree | 92e00e551c95553c6090e26a7502593e72bdcfd7 /client/src/assets | |
parent | b63c607b92fd3ec62e370b73e398062bcf317738 (diff) | |
download | PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.tar.gz PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.tar.zst PeerTube-c6867725fb8e3dfbc2018a37ed5a963103587cb6.zip |
Add p2p info to metrics
Diffstat (limited to 'client/src/assets')
8 files changed, 64 insertions, 61 deletions
diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts index ebb79247a..69ca1a566 100644 --- a/client/src/assets/player/peertube-player.ts +++ b/client/src/assets/player/peertube-player.ts | |||
@@ -203,7 +203,7 @@ export class PeerTubePlayer { | |||
203 | 203 | ||
204 | this.player.one('error', () => handleError()) | 204 | this.player.one('error', () => handleError()) |
205 | 205 | ||
206 | this.player.on('p2p-info', (_, data: PlayerNetworkInfo) => { | 206 | this.player.on('network-info', (_, data: PlayerNetworkInfo) => { |
207 | if (data.source !== 'p2p-media-loader' || isNaN(data.bandwidthEstimate)) return | 207 | if (data.source !== 'p2p-media-loader' || isNaN(data.bandwidthEstimate)) return |
208 | 208 | ||
209 | saveAverageBandwidth(data.bandwidthEstimate) | 209 | saveAverageBandwidth(data.bandwidthEstimate) |
diff --git a/client/src/assets/player/shared/control-bar/p2p-info-button.ts b/client/src/assets/player/shared/control-bar/p2p-info-button.ts index 4177b3280..d2d2b6c99 100644 --- a/client/src/assets/player/shared/control-bar/p2p-info-button.ts +++ b/client/src/assets/player/shared/control-bar/p2p-info-button.ts | |||
@@ -39,15 +39,14 @@ class P2PInfoButton extends Button { | |||
39 | subDivP2P.appendChild(peersText) | 39 | subDivP2P.appendChild(peersText) |
40 | 40 | ||
41 | const subDivHttp = videojs.dom.createEl('div', { className: 'vjs-peertube-hidden' }) as HTMLElement | 41 | const subDivHttp = videojs.dom.createEl('div', { className: 'vjs-peertube-hidden' }) as HTMLElement |
42 | const subDivHttpText = videojs.dom.createEl('span', { | 42 | const subDivHttpText = videojs.dom.createEl('span', { className: 'http-fallback' }) |
43 | className: 'http-fallback', | ||
44 | textContent: 'HTTP' | ||
45 | }) | ||
46 | 43 | ||
47 | subDivHttp.appendChild(subDivHttpText) | 44 | subDivHttp.appendChild(subDivHttpText) |
48 | div.appendChild(subDivHttp) | 45 | div.appendChild(subDivHttp) |
49 | 46 | ||
50 | this.player_.on('p2p-info', (_event: any, data: PlayerNetworkInfo) => { | 47 | this.player_.on('network-info', (_event: any, data: PlayerNetworkInfo) => { |
48 | if (!data.p2p) return | ||
49 | |||
51 | subDivP2P.className = 'vjs-peertube-displayed' | 50 | subDivP2P.className = 'vjs-peertube-displayed' |
52 | subDivHttp.className = 'vjs-peertube-hidden' | 51 | subDivHttp.className = 'vjs-peertube-hidden' |
53 | 52 | ||
@@ -58,7 +57,7 @@ class P2PInfoButton extends Button { | |||
58 | const uploadSpeed = bytes(p2pStats.uploadSpeed) | 57 | const uploadSpeed = bytes(p2pStats.uploadSpeed) |
59 | const totalDownloaded = bytes(p2pStats.downloaded + httpStats.downloaded) | 58 | const totalDownloaded = bytes(p2pStats.downloaded + httpStats.downloaded) |
60 | const totalUploaded = bytes(p2pStats.uploaded) | 59 | const totalUploaded = bytes(p2pStats.uploaded) |
61 | const numPeers = p2pStats.numPeers | 60 | const numPeers = p2pStats.peersWithWebSeed |
62 | 61 | ||
63 | subDivP2P.title = this.player().localize('Total downloaded: ') + totalDownloaded.join(' ') + '\n' | 62 | subDivP2P.title = this.player().localize('Total downloaded: ') + totalDownloaded.join(' ') + '\n' |
64 | 63 | ||
@@ -85,8 +84,13 @@ class P2PInfoButton extends Button { | |||
85 | subDivP2P.className = 'vjs-peertube-displayed' | 84 | subDivP2P.className = 'vjs-peertube-displayed' |
86 | }) | 85 | }) |
87 | 86 | ||
88 | this.player_.on('http-info', (_event, data: PlayerNetworkInfo) => { | 87 | this.player_.on('network-info', (_event, data: PlayerNetworkInfo) => { |
89 | // We are in HTTP fallback | 88 | if (data.p2p) return |
89 | |||
90 | if (data.source === 'web-video') subDivHttpText.textContent = 'HTTP' | ||
91 | else if (data.source === 'p2p-media-loader') subDivHttpText.textContent = 'HLS' | ||
92 | |||
93 | // We are in HTTP mode | ||
90 | subDivHttp.className = 'vjs-peertube-displayed' | 94 | subDivHttp.className = 'vjs-peertube-displayed' |
91 | subDivP2P.className = 'vjs-peertube-hidden' | 95 | subDivP2P.className = 'vjs-peertube-hidden' |
92 | 96 | ||
diff --git a/client/src/assets/player/shared/metrics/metrics-plugin.ts b/client/src/assets/player/shared/metrics/metrics-plugin.ts index 20d37d636..06ca0c2f2 100644 --- a/client/src/assets/player/shared/metrics/metrics-plugin.ts +++ b/client/src/assets/player/shared/metrics/metrics-plugin.ts | |||
@@ -19,7 +19,7 @@ class MetricsPlugin extends Plugin { | |||
19 | private errors = 0 | 19 | private errors = 0 |
20 | 20 | ||
21 | private p2pEnabled: boolean | 21 | private p2pEnabled: boolean |
22 | private totalPeers = 0 | 22 | private p2pPeers = 0 |
23 | 23 | ||
24 | private lastPlayerNetworkInfo: PlayerNetworkInfo | 24 | private lastPlayerNetworkInfo: PlayerNetworkInfo |
25 | 25 | ||
@@ -111,12 +111,12 @@ class MetricsPlugin extends Plugin { | |||
111 | 111 | ||
112 | errors: this.errors, | 112 | errors: this.errors, |
113 | 113 | ||
114 | downloadedBytesP2P: this.downloadedBytesP2P, | ||
115 | downloadedBytesHTTP: this.downloadedBytesHTTP, | 114 | downloadedBytesHTTP: this.downloadedBytesHTTP, |
116 | 115 | ||
116 | downloadedBytesP2P: this.downloadedBytesP2P, | ||
117 | uploadedBytesP2P: this.uploadedBytesP2P, | 117 | uploadedBytesP2P: this.uploadedBytesP2P, |
118 | 118 | ||
119 | totalPeers: this.totalPeers, | 119 | p2pPeers: this.p2pPeers, |
120 | p2pEnabled: this.p2pEnabled, | 120 | p2pEnabled: this.p2pEnabled, |
121 | 121 | ||
122 | videoId: this.options_.videoUUID() | 122 | videoId: this.options_.videoUUID() |
@@ -139,23 +139,14 @@ class MetricsPlugin extends Plugin { | |||
139 | } | 139 | } |
140 | 140 | ||
141 | private trackBytes () { | 141 | private trackBytes () { |
142 | this.player.on('p2p-info', (_event, data: PlayerNetworkInfo) => { | 142 | this.player.on('network-info', (_event, data: PlayerNetworkInfo) => { |
143 | this.downloadedBytesHTTP += Math.round(data.http.downloaded - (this.lastPlayerNetworkInfo?.http.downloaded || 0)) | 143 | this.downloadedBytesHTTP += Math.round(data.http.downloaded - (this.lastPlayerNetworkInfo?.http.downloaded || 0)) |
144 | this.downloadedBytesP2P += Math.round(data.p2p.downloaded - (this.lastPlayerNetworkInfo?.p2p.downloaded || 0)) | 144 | this.downloadedBytesP2P += Math.round((data.p2p?.downloaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.downloaded || 0)) |
145 | |||
146 | this.uploadedBytesP2P += Math.round(data.p2p.uploaded - (this.lastPlayerNetworkInfo?.p2p.uploaded || 0)) | ||
147 | |||
148 | this.totalPeers = data.p2p.numPeers | ||
149 | this.p2pEnabled = true | ||
150 | 145 | ||
151 | this.lastPlayerNetworkInfo = data | 146 | this.uploadedBytesP2P += Math.round((data.p2p?.uploaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.uploaded || 0)) |
152 | }) | ||
153 | |||
154 | this.player.on('http-info', (_event, data: PlayerNetworkInfo) => { | ||
155 | this.downloadedBytesHTTP += Math.round(data.http.downloaded - (this.lastPlayerNetworkInfo?.http.downloaded || 0)) | ||
156 | 147 | ||
157 | this.totalPeers = 0 | 148 | this.p2pPeers = data.p2p?.peersP2POnly |
158 | this.p2pEnabled = false | 149 | this.p2pEnabled = !!data.p2p |
159 | 150 | ||
160 | this.lastPlayerNetworkInfo = data | 151 | this.lastPlayerNetworkInfo = data |
161 | }) | 152 | }) |
diff --git a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts index fe967a730..8c376cd21 100644 --- a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts +++ b/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts | |||
@@ -16,7 +16,8 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
16 | private statsP2PBytes = { | 16 | private statsP2PBytes = { |
17 | pendingDownload: [] as number[], | 17 | pendingDownload: [] as number[], |
18 | pendingUpload: [] as number[], | 18 | pendingUpload: [] as number[], |
19 | numPeers: 0, | 19 | peersWithWebSeed: 0, |
20 | peersP2POnly: 0, | ||
20 | totalDownload: 0, | 21 | totalDownload: 0, |
21 | totalUpload: 0 | 22 | totalUpload: 0 |
22 | } | 23 | } |
@@ -113,7 +114,7 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
113 | this.options.redundancyUrlManager.removeBySegmentUrl(segment.requestUrl) | 114 | this.options.redundancyUrlManager.removeBySegmentUrl(segment.requestUrl) |
114 | }) | 115 | }) |
115 | 116 | ||
116 | this.statsP2PBytes.numPeers = 1 + this.options.redundancyUrlManager.countBaseUrls() | 117 | this.statsP2PBytes.peersWithWebSeed = 1 + this.options.redundancyUrlManager.countBaseUrls() |
117 | 118 | ||
118 | this.runStats() | 119 | this.runStats() |
119 | 120 | ||
@@ -138,8 +139,14 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
138 | this.statsP2PBytes.totalUpload += bytes | 139 | this.statsP2PBytes.totalUpload += bytes |
139 | }) | 140 | }) |
140 | 141 | ||
141 | this.p2pEngine.on(Events.PeerConnect, () => this.statsP2PBytes.numPeers++) | 142 | this.p2pEngine.on(Events.PeerConnect, () => { |
142 | this.p2pEngine.on(Events.PeerClose, () => this.statsP2PBytes.numPeers--) | 143 | this.statsP2PBytes.peersWithWebSeed++ |
144 | this.statsP2PBytes.peersP2POnly++ | ||
145 | }) | ||
146 | this.p2pEngine.on(Events.PeerClose, () => { | ||
147 | this.statsP2PBytes.peersWithWebSeed-- | ||
148 | this.statsP2PBytes.peersP2POnly-- | ||
149 | }) | ||
143 | 150 | ||
144 | this.networkInfoInterval = setInterval(() => { | 151 | this.networkInfoInterval = setInterval(() => { |
145 | const p2pDownloadSpeed = this.arraySum(this.statsP2PBytes.pendingDownload) | 152 | const p2pDownloadSpeed = this.arraySum(this.statsP2PBytes.pendingDownload) |
@@ -151,20 +158,23 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
151 | this.statsP2PBytes.pendingUpload = [] | 158 | this.statsP2PBytes.pendingUpload = [] |
152 | this.statsHTTPBytes.pendingDownload = [] | 159 | this.statsHTTPBytes.pendingDownload = [] |
153 | 160 | ||
154 | return this.player.trigger('p2p-info', { | 161 | return this.player.trigger('network-info', { |
155 | source: 'p2p-media-loader', | 162 | source: 'p2p-media-loader', |
163 | bandwidthEstimate: (this.hlsjs as any).bandwidthEstimate / 8, | ||
156 | http: { | 164 | http: { |
157 | downloadSpeed: httpDownloadSpeed, | 165 | downloadSpeed: httpDownloadSpeed, |
158 | downloaded: this.statsHTTPBytes.totalDownload | 166 | downloaded: this.statsHTTPBytes.totalDownload |
159 | }, | 167 | }, |
160 | p2p: { | 168 | p2p: this.options.p2pEnabled |
161 | downloadSpeed: p2pDownloadSpeed, | 169 | ? { |
162 | uploadSpeed: p2pUploadSpeed, | 170 | downloadSpeed: p2pDownloadSpeed, |
163 | numPeers: this.statsP2PBytes.numPeers, | 171 | uploadSpeed: p2pUploadSpeed, |
164 | downloaded: this.statsP2PBytes.totalDownload, | 172 | peersWithWebSeed: this.statsP2PBytes.peersWithWebSeed, |
165 | uploaded: this.statsP2PBytes.totalUpload | 173 | peersP2POnly: this.statsP2PBytes.peersP2POnly, |
166 | }, | 174 | downloaded: this.statsP2PBytes.totalDownload, |
167 | bandwidthEstimate: (this.hlsjs as any).bandwidthEstimate / 8 | 175 | uploaded: this.statsP2PBytes.totalUpload |
176 | } | ||
177 | : undefined | ||
168 | } as PlayerNetworkInfo) | 178 | } as PlayerNetworkInfo) |
169 | }, 1000) | 179 | }, 1000) |
170 | } | 180 | } |
diff --git a/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts b/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts index 1658f776c..fd632d90d 100644 --- a/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts +++ b/client/src/assets/player/shared/player-options-builder/hls-options-builder.ts | |||
@@ -44,6 +44,8 @@ export class HLSOptionsBuilder { | |||
44 | requiresUserAuth: this.options.requiresUserAuth, | 44 | requiresUserAuth: this.options.requiresUserAuth, |
45 | videoFileToken: this.options.videoFileToken, | 45 | videoFileToken: this.options.videoFileToken, |
46 | 46 | ||
47 | p2pEnabled: this.options.p2pEnabled, | ||
48 | |||
47 | redundancyUrlManager, | 49 | redundancyUrlManager, |
48 | type: 'application/x-mpegURL', | 50 | type: 'application/x-mpegURL', |
49 | src: this.options.hls.playlistUrl, | 51 | src: this.options.hls.playlistUrl, |
diff --git a/client/src/assets/player/shared/stats/stats-card.ts b/client/src/assets/player/shared/stats/stats-card.ts index 077c900e5..13334d91a 100644 --- a/client/src/assets/player/shared/stats/stats-card.ts +++ b/client/src/assets/player/shared/stats/stats-card.ts | |||
@@ -63,8 +63,7 @@ class StatsCard extends Component { | |||
63 | 63 | ||
64 | private liveLatency: InfoElement | 64 | private liveLatency: InfoElement |
65 | 65 | ||
66 | private onP2PInfoHandler: (_event: any, data: EventPlayerNetworkInfo) => void | 66 | private onNetworkInfoHandler: (_event: any, data: EventPlayerNetworkInfo) => void |
67 | private onHTTPInfoHandler: (_event: any, data: EventPlayerNetworkInfo) => void | ||
68 | 67 | ||
69 | createEl () { | 68 | createEl () { |
70 | this.containerEl = videojs.dom.createEl('div', { | 69 | this.containerEl = videojs.dom.createEl('div', { |
@@ -89,33 +88,26 @@ class StatsCard extends Component { | |||
89 | 88 | ||
90 | this.populateInfoBlocks() | 89 | this.populateInfoBlocks() |
91 | 90 | ||
92 | this.onP2PInfoHandler = (_event, data) => { | 91 | this.onNetworkInfoHandler = (_event, data) => { |
93 | this.mode = data.source | 92 | this.mode = data.source |
94 | 93 | ||
95 | const p2pStats = data.p2p | 94 | const p2pStats = data.p2p |
96 | const httpStats = data.http | 95 | const httpStats = data.http |
97 | 96 | ||
98 | this.playerNetworkInfo.downloadSpeed = bytes(p2pStats.downloadSpeed + httpStats.downloadSpeed).join(' ') | 97 | this.playerNetworkInfo.downloadSpeed = bytes((p2pStats?.downloadSpeed || 0) + (httpStats.downloadSpeed || 0)).join(' ') |
99 | this.playerNetworkInfo.uploadSpeed = bytes(p2pStats.uploadSpeed).join(' ') | 98 | this.playerNetworkInfo.uploadSpeed = bytes(p2pStats?.uploadSpeed || 0).join(' ') |
100 | this.playerNetworkInfo.totalDownloaded = bytes(p2pStats.downloaded + httpStats.downloaded).join(' ') | 99 | this.playerNetworkInfo.totalDownloaded = bytes((p2pStats?.downloaded || 0) + httpStats.downloaded).join(' ') |
101 | this.playerNetworkInfo.totalUploaded = bytes(p2pStats.uploaded).join(' ') | 100 | this.playerNetworkInfo.totalUploaded = bytes(p2pStats?.uploaded || 0).join(' ') |
102 | this.playerNetworkInfo.numPeers = p2pStats.numPeers | 101 | this.playerNetworkInfo.numPeers = p2pStats?.peersWithWebSeed |
103 | this.playerNetworkInfo.averageBandwidth = bytes(data.bandwidthEstimate).join(' ') + '/s' | ||
104 | 102 | ||
105 | if (data.source === 'p2p-media-loader') { | 103 | if (data.source === 'p2p-media-loader') { |
104 | this.playerNetworkInfo.averageBandwidth = bytes(data.bandwidthEstimate).join(' ') + '/s' | ||
106 | this.playerNetworkInfo.downloadedFromServer = bytes(httpStats.downloaded).join(' ') | 105 | this.playerNetworkInfo.downloadedFromServer = bytes(httpStats.downloaded).join(' ') |
107 | this.playerNetworkInfo.downloadedFromPeers = bytes(p2pStats.downloaded).join(' ') | 106 | this.playerNetworkInfo.downloadedFromPeers = bytes(p2pStats?.downloaded || 0).join(' ') |
108 | } | 107 | } |
109 | } | 108 | } |
110 | 109 | ||
111 | this.onHTTPInfoHandler = (_event, data) => { | 110 | this.player().on('network-info', this.onNetworkInfoHandler) |
112 | this.mode = data.source | ||
113 | |||
114 | this.playerNetworkInfo.totalDownloaded = bytes(data.http.downloaded).join(' ') | ||
115 | } | ||
116 | |||
117 | this.player().on('p2p-info', this.onP2PInfoHandler) | ||
118 | this.player().on('http-info', this.onHTTPInfoHandler) | ||
119 | 111 | ||
120 | return this.containerEl | 112 | return this.containerEl |
121 | } | 113 | } |
@@ -123,8 +115,7 @@ class StatsCard extends Component { | |||
123 | dispose () { | 115 | dispose () { |
124 | if (this.updateInterval) clearInterval(this.updateInterval) | 116 | if (this.updateInterval) clearInterval(this.updateInterval) |
125 | 117 | ||
126 | this.player().off('p2p-info', this.onP2PInfoHandler) | 118 | this.player().off('network-info', this.onNetworkInfoHandler) |
127 | this.player().off('http-info', this.onHTTPInfoHandler) | ||
128 | 119 | ||
129 | super.dispose() | 120 | super.dispose() |
130 | } | 121 | } |
diff --git a/client/src/assets/player/shared/web-video/web-video-plugin.ts b/client/src/assets/player/shared/web-video/web-video-plugin.ts index 930b5045a..d09b5a724 100644 --- a/client/src/assets/player/shared/web-video/web-video-plugin.ts +++ b/client/src/assets/player/shared/web-video/web-video-plugin.ts | |||
@@ -175,7 +175,7 @@ class WebVideoPlugin extends Plugin { | |||
175 | 175 | ||
176 | private setupNetworkInfoInterval () { | 176 | private setupNetworkInfoInterval () { |
177 | this.networkInfoInterval = setInterval(() => { | 177 | this.networkInfoInterval = setInterval(() => { |
178 | return this.player.trigger('http-info', { | 178 | return this.player.trigger('network-info', { |
179 | source: 'web-video', | 179 | source: 'web-video', |
180 | http: { | 180 | http: { |
181 | downloaded: this.player.bufferedPercent() * this.currentVideoFile.size | 181 | downloaded: this.player.bufferedPercent() * this.currentVideoFile.size |
diff --git a/client/src/assets/player/types/peertube-videojs-typings.ts b/client/src/assets/player/types/peertube-videojs-typings.ts index adaa43d77..73b38d0d3 100644 --- a/client/src/assets/player/types/peertube-videojs-typings.ts +++ b/client/src/assets/player/types/peertube-videojs-typings.ts | |||
@@ -184,6 +184,8 @@ type P2PMediaLoaderPluginOptions = { | |||
184 | type: string | 184 | type: string |
185 | src: string | 185 | src: string |
186 | 186 | ||
187 | p2pEnabled: boolean | ||
188 | |||
187 | loader: P2PMediaLoader | 189 | loader: P2PMediaLoader |
188 | segmentValidator: SegmentValidator | 190 | segmentValidator: SegmentValidator |
189 | 191 | ||
@@ -240,9 +242,12 @@ type PlayerNetworkInfo = { | |||
240 | p2p?: { | 242 | p2p?: { |
241 | downloadSpeed: number | 243 | downloadSpeed: number |
242 | uploadSpeed: number | 244 | uploadSpeed: number |
245 | |||
243 | downloaded: number | 246 | downloaded: number |
244 | uploaded: number | 247 | uploaded: number |
245 | numPeers: number | 248 | |
249 | peersWithWebSeed: number | ||
250 | peersP2POnly: number | ||
246 | } | 251 | } |
247 | 252 | ||
248 | // In bytes | 253 | // In bytes |