aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-08-18 09:48:45 +0200
committerChocobozzz <me@florianbigard.com>2023-08-18 09:48:45 +0200
commit8e4fba97b26090e0c77ee9591058cd34ef9d2f55 (patch)
treeaced2d2b805845f81075412ed841221dcb4d7fca
parent276f5fa24f642fea7d7e6fb8812772e471070993 (diff)
downloadPeerTube-8e4fba97b26090e0c77ee9591058cd34ef9d2f55.tar.gz
PeerTube-8e4fba97b26090e0c77ee9591058cd34ef9d2f55.tar.zst
PeerTube-8e4fba97b26090e0c77ee9591058cd34ef9d2f55.zip
Automatically adapt player ratio
-rw-r--r--client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss1
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.scss54
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.ts7
-rw-r--r--client/src/assets/player/peertube-player.ts4
-rw-r--r--client/src/assets/player/shared/metrics/metrics-plugin.ts6
-rw-r--r--client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts8
-rw-r--r--client/src/assets/player/shared/peertube/peertube-plugin.ts21
-rw-r--r--client/src/assets/player/shared/web-video/web-video-plugin.ts8
-rw-r--r--client/src/assets/player/types/peertube-player-options.ts5
-rw-r--r--client/src/assets/player/types/peertube-videojs-typings.ts5
-rw-r--r--client/src/sass/include/_variables.scss1
-rw-r--r--packages/tests/src/api/notifications/notifications-api.ts2
12 files changed, 88 insertions, 34 deletions
diff --git a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
index 0f0ac1979..2d43ffe40 100644
--- a/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
+++ b/client/src/app/+videos/+video-watch/shared/playlist/video-watch-playlist.component.scss
@@ -6,6 +6,7 @@
6.playlist { 6.playlist {
7 position: relative; 7 position: relative;
8 min-width: 200px; 8 min-width: 200px;
9 width: 25vw;
9 max-width: 470px; 10 max-width: 470px;
10 height: 66vh; 11 height: 66vh;
11 background-color: pvar(--mainBackgroundColor); 12 background-color: pvar(--mainBackgroundColor);
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.scss b/client/src/app/+videos/+video-watch/video-watch.component.scss
index d438facd3..e535ecb9c 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/+videos/+video-watch/video-watch.component.scss
@@ -4,15 +4,8 @@
4@use '_bootstrap-variables'; 4@use '_bootstrap-variables';
5@use '_miniature' as *; 5@use '_miniature' as *;
6 6
7$video-height: 66vh; 7$video-default-height: 66vh;
8 8$video-theater-height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
9@function getPlayerHeight ($width) {
10 @return calc(#{$width} / #{$video-watch-player-factor});
11}
12
13@function getPlayerWidth ($height) {
14 @return calc(#{$height} * #{$video-watch-player-factor});
15}
16 9
17@mixin playlist-below-player { 10@mixin playlist-below-player {
18 width: 100% !important; 11 width: 100% !important;
@@ -38,20 +31,16 @@ $video-height: 66vh;
38 31
39.root { 32.root {
40 &.theater-enabled #video-wrapper { 33 &.theater-enabled #video-wrapper {
41 $height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
42
43 flex-direction: column; 34 flex-direction: column;
44 justify-content: center; 35 justify-content: center;
45 36
46 #videojs-wrapper { 37 #videojs-wrapper {
47 width: 100%; 38 width: 100%;
48 height: $height; 39 height: $video-theater-height;
49 } 40 }
50 41
51 ::ng-deep .video-js { 42 ::ng-deep .video-js {
52 height: $height; 43 --player-height: #{$video-theater-height};
53 width: 100%;
54 max-width: initial;
55 } 44 }
56 45
57 my-video-watch-playlist ::ng-deep .playlist { 46 my-video-watch-playlist ::ng-deep .playlist {
@@ -65,10 +54,24 @@ $video-height: 66vh;
65 display: flex; 54 display: flex;
66 justify-content: center; 55 justify-content: center;
67 56
57 #videojs-wrapper {
58 display: flex;
59 justify-content: center;
60 flex-grow: 1;
61 height: $video-default-height;
62 }
63
68 ::ng-deep .video-js { 64 ::ng-deep .video-js {
65 --player-height: #{$video-default-height};
66 --player-portrait-mode: 0;
67 // Default player ratio, redefined by the player to automatically adapt player size
68 --player-ratio: #{math.div(16, 9)};
69
69 width: 100%; 70 width: 100%;
70 max-width: getPlayerWidth($video-height); 71 height: var(--player-height);
71 height: $video-height; 72
73 // Can be recalculated by the player depending on video ratio
74 max-width: calc(var(--player-height) * var(--player-ratio));
72 75
73 // VideoJS create an inner video player 76 // VideoJS create an inner video player
74 video { 77 video {
@@ -78,13 +81,6 @@ $video-height: 66vh;
78 } 81 }
79} 82}
80 83
81#videojs-wrapper {
82 display: flex;
83 justify-content: center;
84 flex-grow: 1;
85 height: $video-height;
86}
87
88.remote-server-down { 84.remote-server-down {
89 color: #fff; 85 color: #fff;
90 display: flex; 86 display: flex;
@@ -253,12 +249,16 @@ my-video-comments {
253 249
254@media screen and (max-width: 600px) { 250@media screen and (max-width: 600px) {
255 #videojs-wrapper { 251 #videojs-wrapper {
256 height: getPlayerHeight(100vw) !important; 252 // Reset height
253 height: initial !important;
257 254
258 .remote-server-down, 255 .remote-server-down,
259 ::ng-deep .video-js { 256 ::ng-deep .video-js {
260 width: 100vw; 257 --player-portrait-mode: 1;
261 height: getPlayerHeight(100vw) !important; 258
259 // Can be recalculated by the player depending on video ratio
260 height: calc(100vw / var(--player-ratio)) !important;
261 max-height: $video-theater-height;
262 } 262 }
263 } 263 }
264 264
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts
index f109427cc..febb3c828 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.component.ts
@@ -623,7 +623,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
623 623
624 peertubeLink: () => false, 624 peertubeLink: () => false,
625 625
626 pluginsManager: this.pluginService.getPluginsManager() 626 pluginsManager: this.pluginService.getPluginsManager(),
627
628 autoPlayerRatio: {
629 cssRatioVariable: '--player-ratio',
630 cssPlayerPortraitModeVariable: '--player-portrait-mode'
631 }
627 } 632 }
628 } 633 }
629 634
diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts
index 4da681a08..111b4645b 100644
--- a/client/src/assets/player/peertube-player.ts
+++ b/client/src/assets/player/peertube-player.ts
@@ -364,7 +364,9 @@ export class PeerTubePlayer {
364 videoUUID: () => this.currentLoadOptions.videoUUID, 364 videoUUID: () => this.currentLoadOptions.videoUUID,
365 subtitle: () => this.currentLoadOptions.subtitle, 365 subtitle: () => this.currentLoadOptions.subtitle,
366 366
367 poster: () => this.currentLoadOptions.poster 367 poster: () => this.currentLoadOptions.poster,
368
369 autoPlayerRatio: this.options.autoPlayerRatio
368 }, 370 },
369 metrics: { 371 metrics: {
370 mode: () => this.currentLoadOptions.mode, 372 mode: () => this.currentLoadOptions.mode,
diff --git a/client/src/assets/player/shared/metrics/metrics-plugin.ts b/client/src/assets/player/shared/metrics/metrics-plugin.ts
index 0ad16338c..a581d7931 100644
--- a/client/src/assets/player/shared/metrics/metrics-plugin.ts
+++ b/client/src/assets/player/shared/metrics/metrics-plugin.ts
@@ -140,10 +140,10 @@ class MetricsPlugin extends Plugin {
140 140
141 private trackBytes () { 141 private trackBytes () {
142 this.player.on('network-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.max(Math.round(data.http.downloaded - (this.lastPlayerNetworkInfo?.http.downloaded || 0)), 0)
144 this.downloadedBytesP2P += Math.round((data.p2p?.downloaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.downloaded || 0)) 144 this.downloadedBytesP2P += Math.max(Math.round((data.p2p?.downloaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.downloaded || 0)), 0)
145 145
146 this.uploadedBytesP2P += Math.round((data.p2p?.uploaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.uploaded || 0)) 146 this.uploadedBytesP2P += Math.max(Math.round((data.p2p?.uploaded || 0) - (this.lastPlayerNetworkInfo?.p2p?.uploaded || 0)), 0)
147 147
148 this.p2pPeers = data.p2p?.peersP2POnly 148 this.p2pPeers = data.p2p?.peersP2POnly
149 this.p2pEnabled = !!data.p2p 149 this.p2pEnabled = !!data.p2p
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 1e47fe486..ee617ce8a 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
@@ -119,6 +119,14 @@ class P2pMediaLoaderPlugin extends Plugin {
119 this.runStats() 119 this.runStats()
120 120
121 this.hlsjs.on(Hlsjs.Events.LEVEL_SWITCHED, () => this.player.trigger('engine-resolution-change')) 121 this.hlsjs.on(Hlsjs.Events.LEVEL_SWITCHED, () => this.player.trigger('engine-resolution-change'))
122
123 this.hlsjs.on(Hlsjs.Events.MANIFEST_PARSED, (_event, data) => {
124 if (Array.isArray(data.levels) && data.levels.length > 1) {
125 const level = data.levels[0]
126
127 this.player.trigger('video-ratio-changed', { ratio: level.width / level.height })
128 }
129 })
122 } 130 }
123 131
124 private runStats () { 132 private runStats () {
diff --git a/client/src/assets/player/shared/peertube/peertube-plugin.ts b/client/src/assets/player/shared/peertube/peertube-plugin.ts
index cf866723c..7aeae2670 100644
--- a/client/src/assets/player/shared/peertube/peertube-plugin.ts
+++ b/client/src/assets/player/shared/peertube/peertube-plugin.ts
@@ -115,6 +115,8 @@ class PeerTubePlugin extends Plugin {
115 this.hideFatalError() 115 this.hideFatalError()
116 }) 116 })
117 }) 117 })
118
119 this.initOnRatioChange()
118 } 120 }
119 121
120 dispose () { 122 dispose () {
@@ -210,6 +212,25 @@ class PeerTubePlugin extends Plugin {
210 this.runUserViewing() 212 this.runUserViewing()
211 } 213 }
212 214
215 private initOnRatioChange () {
216 if (!this.options.autoPlayerRatio) return
217
218 const defaultRatio = getComputedStyle(this.player.el()).getPropertyValue(this.options.autoPlayerRatio.cssRatioVariable)
219
220 this.player.on('video-ratio-changed', (_event, data: { ratio: number }) => {
221 const el = this.player.el() as HTMLElement
222
223 // In portrait screen mode, we allow player with bigger height size than width
224 const portraitMode = getComputedStyle(el).getPropertyValue(this.options.autoPlayerRatio.cssPlayerPortraitModeVariable) === '1'
225
226 const currentRatio = !portraitMode && data.ratio < 1
227 ? defaultRatio
228 : data.ratio
229
230 el.style.setProperty('--player-ratio', currentRatio + '')
231 })
232 }
233
213 // --------------------------------------------------------------------------- 234 // ---------------------------------------------------------------------------
214 235
215 private runUserViewing () { 236 private runUserViewing () {
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 18d911108..8f4db0680 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
@@ -19,6 +19,7 @@ class WebVideoPlugin extends Plugin {
19 19
20 private onErrorHandler: () => void 20 private onErrorHandler: () => void
21 private onPlayHandler: () => void 21 private onPlayHandler: () => void
22 private onLoadedMetadata: () => void
22 23
23 constructor (player: videojs.Player, options?: WebVideoPluginOptions) { 24 constructor (player: videojs.Player, options?: WebVideoPluginOptions) {
24 super(player, options) 25 super(player, options)
@@ -28,6 +29,12 @@ class WebVideoPlugin extends Plugin {
28 29
29 this.updateVideoFile({ videoFile: this.pickAverageVideoFile(), isUserResolutionChange: false }) 30 this.updateVideoFile({ videoFile: this.pickAverageVideoFile(), isUserResolutionChange: false })
30 31
32 this.onLoadedMetadata = () => {
33 player.trigger('video-ratio-changed', { ratio: this.player.videoWidth() / this.player.videoHeight() })
34 }
35
36 player.on('loadedmetadata', this.onLoadedMetadata)
37
31 player.ready(() => { 38 player.ready(() => {
32 this.buildQualities() 39 this.buildQualities()
33 40
@@ -43,6 +50,7 @@ class WebVideoPlugin extends Plugin {
43 dispose () { 50 dispose () {
44 clearInterval(this.networkInfoInterval) 51 clearInterval(this.networkInfoInterval)
45 52
53 if (this.onLoadedMetadata) this.player.off('loadedmetadata', this.onLoadedMetadata)
46 if (this.onErrorHandler) this.player.off('error', this.onErrorHandler) 54 if (this.onErrorHandler) this.player.off('error', this.onErrorHandler)
47 if (this.onPlayHandler) this.player.off('canplay', this.onPlayHandler) 55 if (this.onPlayHandler) this.player.off('canplay', this.onPlayHandler)
48 56
diff --git a/client/src/assets/player/types/peertube-player-options.ts b/client/src/assets/player/types/peertube-player-options.ts
index 352f7d8dd..6fb2f7913 100644
--- a/client/src/assets/player/types/peertube-player-options.ts
+++ b/client/src/assets/player/types/peertube-player-options.ts
@@ -38,6 +38,11 @@ export type PeerTubePlayerContructorOptions = {
38 language: string 38 language: string
39 39
40 pluginsManager: PluginsManager 40 pluginsManager: PluginsManager
41
42 autoPlayerRatio?: {
43 cssRatioVariable: string
44 cssPlayerPortraitModeVariable: string
45 }
41} 46}
42 47
43export type PeerTubePlayerLoadOptions = { 48export type PeerTubePlayerLoadOptions = {
diff --git a/client/src/assets/player/types/peertube-videojs-typings.ts b/client/src/assets/player/types/peertube-videojs-typings.ts
index dae9e14c8..27fbda31d 100644
--- a/client/src/assets/player/types/peertube-videojs-typings.ts
+++ b/client/src/assets/player/types/peertube-videojs-typings.ts
@@ -104,6 +104,11 @@ type VideoJSStoryboard = {
104} 104}
105 105
106type PeerTubePluginOptions = { 106type PeerTubePluginOptions = {
107 autoPlayerRatio: {
108 cssRatioVariable: string
109 cssPlayerPortraitModeVariable: string
110 }
111
107 hasAutoplay: () => videojs.Autoplay 112 hasAutoplay: () => videojs.Autoplay
108 113
109 videoViewUrl: () => string 114 videoViewUrl: () => string
diff --git a/client/src/sass/include/_variables.scss b/client/src/sass/include/_variables.scss
index 43a005774..f414cf185 100644
--- a/client/src/sass/include/_variables.scss
+++ b/client/src/sass/include/_variables.scss
@@ -97,7 +97,6 @@ $activated-action-button-color: #212529;
97$focus-box-shadow-form: 0 0 0 .2rem; 97$focus-box-shadow-form: 0 0 0 .2rem;
98$form-input-font-size: 15px; 98$form-input-font-size: 15px;
99 99
100$video-watch-player-factor: math.div(16, 9);
101$video-watch-info-margin-left: 44px; 100$video-watch-info-margin-left: 44px;
102 101
103$primeng-breakpoint: 960px; 102$primeng-breakpoint: 960px;
diff --git a/packages/tests/src/api/notifications/notifications-api.ts b/packages/tests/src/api/notifications/notifications-api.ts
index 1c7461553..f99b81e94 100644
--- a/packages/tests/src/api/notifications/notifications-api.ts
+++ b/packages/tests/src/api/notifications/notifications-api.ts
@@ -18,7 +18,7 @@ describe('Test notifications API', function () {
18 let emails: object[] = [] 18 let emails: object[] = []
19 19
20 before(async function () { 20 before(async function () {
21 this.timeout(120000) 21 this.timeout(240000)
22 22
23 const res = await prepareNotificationsTest(1) 23 const res = await prepareNotificationsTest(1)
24 emails = res.emails 24 emails = res.emails