diff options
author | Chocobozzz <me@florianbigard.com> | 2022-03-14 14:28:20 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-03-14 14:36:35 +0100 |
commit | 57d6503286b114fee61b5e4725825e2490dcac29 (patch) | |
tree | 2d3d23f697b2986d7e41bb443754394296b66ec3 /client/src/assets/player/shared/manager-options/hls-options-builder.ts | |
parent | 9597920ee3d4ac99803e7107983ddf98a9dfb3c4 (diff) | |
download | PeerTube-57d6503286b114fee61b5e4725825e2490dcac29.tar.gz PeerTube-57d6503286b114fee61b5e4725825e2490dcac29.tar.zst PeerTube-57d6503286b114fee61b5e4725825e2490dcac29.zip |
Reorganize player files
Diffstat (limited to 'client/src/assets/player/shared/manager-options/hls-options-builder.ts')
-rw-r--r-- | client/src/assets/player/shared/manager-options/hls-options-builder.ts | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/client/src/assets/player/shared/manager-options/hls-options-builder.ts b/client/src/assets/player/shared/manager-options/hls-options-builder.ts new file mode 100644 index 000000000..e7f664fd4 --- /dev/null +++ b/client/src/assets/player/shared/manager-options/hls-options-builder.ts | |||
@@ -0,0 +1,192 @@ | |||
1 | import { HybridLoaderSettings } from '@peertube/p2p-media-loader-core' | ||
2 | import { HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs' | ||
3 | import { LiveVideoLatencyMode } from '@shared/models' | ||
4 | import { getAverageBandwidthInStore } from '../../peertube-player-local-storage' | ||
5 | import { P2PMediaLoader, P2PMediaLoaderPluginOptions } from '../../types' | ||
6 | import { PeertubePlayerManagerOptions } from '../../types/manager-options' | ||
7 | import { getRtcConfig } from '../common' | ||
8 | import { RedundancyUrlManager } from '../p2p-media-loader/redundancy-url-manager' | ||
9 | import { segmentUrlBuilderFactory } from '../p2p-media-loader/segment-url-builder' | ||
10 | import { segmentValidatorFactory } from '../p2p-media-loader/segment-validator' | ||
11 | |||
12 | export class HLSOptionsBuilder { | ||
13 | |||
14 | constructor ( | ||
15 | private options: PeertubePlayerManagerOptions, | ||
16 | private p2pMediaLoaderModule?: any | ||
17 | ) { | ||
18 | |||
19 | } | ||
20 | |||
21 | getPluginOptions () { | ||
22 | const commonOptions = this.options.common | ||
23 | |||
24 | const redundancyUrlManager = new RedundancyUrlManager(this.options.p2pMediaLoader.redundancyBaseUrls) | ||
25 | |||
26 | const p2pMediaLoaderConfig = this.getP2PMediaLoaderOptions(redundancyUrlManager) | ||
27 | const loader = new this.p2pMediaLoaderModule.Engine(p2pMediaLoaderConfig).createLoaderClass() as P2PMediaLoader | ||
28 | |||
29 | const p2pMediaLoader: P2PMediaLoaderPluginOptions = { | ||
30 | redundancyUrlManager, | ||
31 | type: 'application/x-mpegURL', | ||
32 | startTime: commonOptions.startTime, | ||
33 | src: this.options.p2pMediaLoader.playlistUrl, | ||
34 | loader | ||
35 | } | ||
36 | |||
37 | const hlsjs = { | ||
38 | levelLabelHandler: (level: { height: number, width: number }) => { | ||
39 | const resolution = Math.min(level.height || 0, level.width || 0) | ||
40 | |||
41 | const file = this.options.p2pMediaLoader.videoFiles.find(f => f.resolution.id === resolution) | ||
42 | // We don't have files for live videos | ||
43 | if (!file) return level.height | ||
44 | |||
45 | let label = file.resolution.label | ||
46 | if (file.fps >= 50) label += file.fps | ||
47 | |||
48 | return label | ||
49 | }, | ||
50 | html5: { | ||
51 | hlsjsConfig: this.getHLSJSOptions(loader) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | return { p2pMediaLoader, hlsjs } | ||
56 | } | ||
57 | |||
58 | // --------------------------------------------------------------------------- | ||
59 | |||
60 | private getP2PMediaLoaderOptions (redundancyUrlManager: RedundancyUrlManager): HlsJsEngineSettings { | ||
61 | let consumeOnly = false | ||
62 | if ((navigator as any)?.connection?.type === 'cellular') { | ||
63 | console.log('We are on a cellular connection: disabling seeding.') | ||
64 | consumeOnly = true | ||
65 | } | ||
66 | |||
67 | const trackerAnnounce = this.options.p2pMediaLoader.trackerAnnounce | ||
68 | .filter(t => t.startsWith('ws')) | ||
69 | |||
70 | const specificLiveOrVODOptions = this.options.common.isLive | ||
71 | ? this.getP2PMediaLoaderLiveOptions() | ||
72 | : this.getP2PMediaLoaderVODOptions() | ||
73 | |||
74 | return { | ||
75 | loader: { | ||
76 | |||
77 | trackerAnnounce, | ||
78 | rtcConfig: getRtcConfig(), | ||
79 | |||
80 | simultaneousHttpDownloads: 1, | ||
81 | httpFailedSegmentTimeout: 1000, | ||
82 | |||
83 | segmentValidator: segmentValidatorFactory(this.options.p2pMediaLoader.segmentsSha256Url, this.options.common.isLive), | ||
84 | segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager, 1), | ||
85 | |||
86 | useP2P: this.options.common.p2pEnabled, | ||
87 | consumeOnly, | ||
88 | |||
89 | ...specificLiveOrVODOptions | ||
90 | }, | ||
91 | segments: { | ||
92 | swarmId: this.options.p2pMediaLoader.playlistUrl, | ||
93 | forwardSegmentCount: specificLiveOrVODOptions.p2pDownloadMaxPriority | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | private getP2PMediaLoaderLiveOptions (): Partial<HybridLoaderSettings> { | ||
99 | const base = { | ||
100 | requiredSegmentsPriority: 1 | ||
101 | } | ||
102 | |||
103 | const latencyMode = this.options.common.liveOptions.latencyMode | ||
104 | |||
105 | switch (latencyMode) { | ||
106 | case LiveVideoLatencyMode.SMALL_LATENCY: | ||
107 | return { | ||
108 | ...base, | ||
109 | |||
110 | useP2P: false, | ||
111 | httpDownloadProbability: 1 | ||
112 | } | ||
113 | |||
114 | case LiveVideoLatencyMode.HIGH_LATENCY: | ||
115 | return base | ||
116 | |||
117 | default: | ||
118 | return base | ||
119 | } | ||
120 | } | ||
121 | |||
122 | private getP2PMediaLoaderVODOptions (): Partial<HybridLoaderSettings> { | ||
123 | return { | ||
124 | requiredSegmentsPriority: 3, | ||
125 | |||
126 | cachedSegmentExpiration: 86400000, | ||
127 | cachedSegmentsCount: 100, | ||
128 | |||
129 | httpDownloadMaxPriority: 9, | ||
130 | httpDownloadProbability: 0.06, | ||
131 | httpDownloadProbabilitySkipIfNoPeers: true, | ||
132 | |||
133 | p2pDownloadMaxPriority: 50 | ||
134 | } | ||
135 | } | ||
136 | |||
137 | // --------------------------------------------------------------------------- | ||
138 | |||
139 | private getHLSJSOptions (loader: P2PMediaLoader) { | ||
140 | const specificLiveOrVODOptions = this.options.common.isLive | ||
141 | ? this.getHLSLiveOptions() | ||
142 | : this.getHLSVODOptions() | ||
143 | |||
144 | const base = { | ||
145 | capLevelToPlayerSize: true, | ||
146 | autoStartLoad: false, | ||
147 | |||
148 | loader, | ||
149 | |||
150 | ...specificLiveOrVODOptions | ||
151 | } | ||
152 | |||
153 | const averageBandwidth = getAverageBandwidthInStore() | ||
154 | if (!averageBandwidth) return base | ||
155 | |||
156 | return { | ||
157 | ...base, | ||
158 | |||
159 | abrEwmaDefaultEstimate: averageBandwidth * 8, // We want bit/s | ||
160 | startLevel: -1, | ||
161 | testBandwidth: false, | ||
162 | debug: false | ||
163 | } | ||
164 | } | ||
165 | |||
166 | private getHLSLiveOptions () { | ||
167 | const latencyMode = this.options.common.liveOptions.latencyMode | ||
168 | |||
169 | switch (latencyMode) { | ||
170 | case LiveVideoLatencyMode.SMALL_LATENCY: | ||
171 | return { | ||
172 | liveSyncDurationCount: 2 | ||
173 | } | ||
174 | |||
175 | case LiveVideoLatencyMode.HIGH_LATENCY: | ||
176 | return { | ||
177 | liveSyncDurationCount: 10 | ||
178 | } | ||
179 | |||
180 | default: | ||
181 | return { | ||
182 | liveSyncDurationCount: 5 | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | private getHLSVODOptions () { | ||
188 | return { | ||
189 | liveSyncDurationCount: 5 | ||
190 | } | ||
191 | } | ||
192 | } | ||