@zenvor/hls.js 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +472 -0
- package/dist/hls-demo.js +26995 -0
- package/dist/hls-demo.js.map +1 -0
- package/dist/hls.d.mts +4204 -0
- package/dist/hls.d.ts +4204 -0
- package/dist/hls.js +40050 -0
- package/dist/hls.js.d.ts +4204 -0
- package/dist/hls.js.map +1 -0
- package/dist/hls.light.js +27145 -0
- package/dist/hls.light.js.map +1 -0
- package/dist/hls.light.min.js +2 -0
- package/dist/hls.light.min.js.map +1 -0
- package/dist/hls.light.mjs +26392 -0
- package/dist/hls.light.mjs.map +1 -0
- package/dist/hls.min.js +2 -0
- package/dist/hls.min.js.map +1 -0
- package/dist/hls.mjs +38956 -0
- package/dist/hls.mjs.map +1 -0
- package/dist/hls.worker.js +2 -0
- package/dist/hls.worker.js.map +1 -0
- package/package.json +143 -0
- package/src/config.ts +794 -0
- package/src/controller/abr-controller.ts +1019 -0
- package/src/controller/algo-data-controller.ts +794 -0
- package/src/controller/audio-stream-controller.ts +1099 -0
- package/src/controller/audio-track-controller.ts +454 -0
- package/src/controller/base-playlist-controller.ts +438 -0
- package/src/controller/base-stream-controller.ts +2526 -0
- package/src/controller/buffer-controller.ts +2015 -0
- package/src/controller/buffer-operation-queue.ts +159 -0
- package/src/controller/cap-level-controller.ts +367 -0
- package/src/controller/cmcd-controller.ts +422 -0
- package/src/controller/content-steering-controller.ts +622 -0
- package/src/controller/eme-controller.ts +1617 -0
- package/src/controller/error-controller.ts +627 -0
- package/src/controller/fps-controller.ts +146 -0
- package/src/controller/fragment-finders.ts +256 -0
- package/src/controller/fragment-tracker.ts +567 -0
- package/src/controller/gap-controller.ts +719 -0
- package/src/controller/id3-track-controller.ts +488 -0
- package/src/controller/interstitial-player.ts +302 -0
- package/src/controller/interstitials-controller.ts +2895 -0
- package/src/controller/interstitials-schedule.ts +698 -0
- package/src/controller/latency-controller.ts +294 -0
- package/src/controller/level-controller.ts +776 -0
- package/src/controller/stream-controller.ts +1597 -0
- package/src/controller/subtitle-stream-controller.ts +508 -0
- package/src/controller/subtitle-track-controller.ts +617 -0
- package/src/controller/timeline-controller.ts +677 -0
- package/src/crypt/aes-crypto.ts +36 -0
- package/src/crypt/aes-decryptor.ts +339 -0
- package/src/crypt/decrypter-aes-mode.ts +4 -0
- package/src/crypt/decrypter.ts +225 -0
- package/src/crypt/fast-aes-key.ts +39 -0
- package/src/define-plugin.d.ts +17 -0
- package/src/demux/audio/aacdemuxer.ts +126 -0
- package/src/demux/audio/ac3-demuxer.ts +170 -0
- package/src/demux/audio/adts.ts +249 -0
- package/src/demux/audio/base-audio-demuxer.ts +205 -0
- package/src/demux/audio/dolby.ts +21 -0
- package/src/demux/audio/mp3demuxer.ts +85 -0
- package/src/demux/audio/mpegaudio.ts +177 -0
- package/src/demux/chunk-cache.ts +42 -0
- package/src/demux/dummy-demuxed-track.ts +13 -0
- package/src/demux/inject-worker.ts +75 -0
- package/src/demux/mp4demuxer.ts +234 -0
- package/src/demux/sample-aes.ts +198 -0
- package/src/demux/transmuxer-interface.ts +449 -0
- package/src/demux/transmuxer-worker.ts +221 -0
- package/src/demux/transmuxer.ts +560 -0
- package/src/demux/tsdemuxer.ts +1256 -0
- package/src/demux/video/avc-video-parser.ts +401 -0
- package/src/demux/video/base-video-parser.ts +198 -0
- package/src/demux/video/exp-golomb.ts +153 -0
- package/src/demux/video/hevc-video-parser.ts +736 -0
- package/src/empty-es.js +5 -0
- package/src/empty.js +3 -0
- package/src/errors.ts +107 -0
- package/src/events.ts +548 -0
- package/src/exports-default.ts +3 -0
- package/src/exports-named.ts +81 -0
- package/src/hls.ts +1613 -0
- package/src/is-supported.ts +54 -0
- package/src/loader/date-range.ts +207 -0
- package/src/loader/fragment-loader.ts +403 -0
- package/src/loader/fragment.ts +487 -0
- package/src/loader/interstitial-asset-list.ts +162 -0
- package/src/loader/interstitial-event.ts +337 -0
- package/src/loader/key-loader.ts +439 -0
- package/src/loader/level-details.ts +203 -0
- package/src/loader/level-key.ts +259 -0
- package/src/loader/load-stats.ts +17 -0
- package/src/loader/m3u8-parser.ts +1072 -0
- package/src/loader/playlist-loader.ts +839 -0
- package/src/polyfills/number.ts +15 -0
- package/src/remux/aac-helper.ts +81 -0
- package/src/remux/mp4-generator.ts +1380 -0
- package/src/remux/mp4-remuxer.ts +1261 -0
- package/src/remux/passthrough-remuxer.ts +434 -0
- package/src/task-loop.ts +130 -0
- package/src/types/algo.ts +44 -0
- package/src/types/buffer.ts +105 -0
- package/src/types/component-api.ts +20 -0
- package/src/types/demuxer.ts +208 -0
- package/src/types/events.ts +574 -0
- package/src/types/fragment-tracker.ts +23 -0
- package/src/types/level.ts +268 -0
- package/src/types/loader.ts +198 -0
- package/src/types/media-playlist.ts +92 -0
- package/src/types/network-details.ts +3 -0
- package/src/types/remuxer.ts +104 -0
- package/src/types/track.ts +12 -0
- package/src/types/transmuxer.ts +46 -0
- package/src/types/tuples.ts +6 -0
- package/src/types/vtt.ts +11 -0
- package/src/utils/arrays.ts +22 -0
- package/src/utils/attr-list.ts +192 -0
- package/src/utils/binary-search.ts +46 -0
- package/src/utils/buffer-helper.ts +173 -0
- package/src/utils/cea-608-parser.ts +1413 -0
- package/src/utils/chunker.ts +41 -0
- package/src/utils/codecs.ts +314 -0
- package/src/utils/cues.ts +96 -0
- package/src/utils/discontinuities.ts +174 -0
- package/src/utils/encryption-methods-util.ts +21 -0
- package/src/utils/error-helper.ts +95 -0
- package/src/utils/event-listener-helper.ts +16 -0
- package/src/utils/ewma-bandwidth-estimator.ts +97 -0
- package/src/utils/ewma.ts +43 -0
- package/src/utils/fetch-loader.ts +331 -0
- package/src/utils/global.ts +2 -0
- package/src/utils/hash.ts +10 -0
- package/src/utils/hdr.ts +67 -0
- package/src/utils/hex.ts +32 -0
- package/src/utils/imsc1-ttml-parser.ts +261 -0
- package/src/utils/keysystem-util.ts +45 -0
- package/src/utils/level-helper.ts +629 -0
- package/src/utils/logger.ts +120 -0
- package/src/utils/media-option-attributes.ts +49 -0
- package/src/utils/mediacapabilities-helper.ts +301 -0
- package/src/utils/mediakeys-helper.ts +210 -0
- package/src/utils/mediasource-helper.ts +37 -0
- package/src/utils/mp4-tools.ts +1473 -0
- package/src/utils/number.ts +3 -0
- package/src/utils/numeric-encoding-utils.ts +26 -0
- package/src/utils/output-filter.ts +46 -0
- package/src/utils/rendition-helper.ts +505 -0
- package/src/utils/safe-json-stringify.ts +22 -0
- package/src/utils/texttrack-utils.ts +164 -0
- package/src/utils/time-ranges.ts +17 -0
- package/src/utils/timescale-conversion.ts +46 -0
- package/src/utils/utf8-utils.ts +18 -0
- package/src/utils/variable-substitution.ts +105 -0
- package/src/utils/vttcue.ts +384 -0
- package/src/utils/vttparser.ts +497 -0
- package/src/utils/webvtt-parser.ts +166 -0
- package/src/utils/xhr-loader.ts +337 -0
- package/src/version.ts +1 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,794 @@
|
|
|
1
|
+
import AbrController from './controller/abr-controller';
|
|
2
|
+
import AudioStreamController from './controller/audio-stream-controller';
|
|
3
|
+
import AudioTrackController from './controller/audio-track-controller';
|
|
4
|
+
import BufferController from './controller/buffer-controller';
|
|
5
|
+
import CapLevelController from './controller/cap-level-controller';
|
|
6
|
+
import CMCDController from './controller/cmcd-controller';
|
|
7
|
+
import ContentSteeringController from './controller/content-steering-controller';
|
|
8
|
+
import EMEController from './controller/eme-controller';
|
|
9
|
+
import ErrorController from './controller/error-controller';
|
|
10
|
+
import FPSController from './controller/fps-controller';
|
|
11
|
+
import InterstitialsController from './controller/interstitials-controller';
|
|
12
|
+
import { SubtitleStreamController } from './controller/subtitle-stream-controller';
|
|
13
|
+
import SubtitleTrackController from './controller/subtitle-track-controller';
|
|
14
|
+
import { TimelineController } from './controller/timeline-controller';
|
|
15
|
+
import Cues from './utils/cues';
|
|
16
|
+
import FetchLoader, { fetchSupported } from './utils/fetch-loader';
|
|
17
|
+
import { requestMediaKeySystemAccess } from './utils/mediakeys-helper';
|
|
18
|
+
import { clamp } from './utils/number';
|
|
19
|
+
import { stringify } from './utils/safe-json-stringify';
|
|
20
|
+
import XhrLoader from './utils/xhr-loader';
|
|
21
|
+
import type { MediaKeySessionContext } from './controller/eme-controller';
|
|
22
|
+
import type Hls from './hls';
|
|
23
|
+
import type {
|
|
24
|
+
FragmentLoaderContext,
|
|
25
|
+
Loader,
|
|
26
|
+
LoaderContext,
|
|
27
|
+
LoaderResponse,
|
|
28
|
+
PlaylistLoaderContext,
|
|
29
|
+
} from './types/loader';
|
|
30
|
+
import type {
|
|
31
|
+
AudioSelectionOption,
|
|
32
|
+
SubtitleSelectionOption,
|
|
33
|
+
VideoSelectionOption,
|
|
34
|
+
} from './types/media-playlist';
|
|
35
|
+
import type { CuesInterface } from './utils/cues';
|
|
36
|
+
import type { ILogger } from './utils/logger';
|
|
37
|
+
import type { KeySystems, MediaKeyFunc } from './utils/mediakeys-helper';
|
|
38
|
+
|
|
39
|
+
export type ABRControllerConfig = {
|
|
40
|
+
abrEwmaFastLive: number;
|
|
41
|
+
abrEwmaSlowLive: number;
|
|
42
|
+
abrEwmaFastVoD: number;
|
|
43
|
+
abrEwmaSlowVoD: number;
|
|
44
|
+
/**
|
|
45
|
+
* Default bandwidth estimate in bits/s prior to collecting fragment bandwidth samples
|
|
46
|
+
*/
|
|
47
|
+
abrEwmaDefaultEstimate: number;
|
|
48
|
+
abrEwmaDefaultEstimateMax: number;
|
|
49
|
+
abrBandWidthFactor: number;
|
|
50
|
+
abrBandWidthUpFactor: number;
|
|
51
|
+
abrMaxWithRealBitrate: boolean;
|
|
52
|
+
abrSwitchInterval: number;
|
|
53
|
+
maxStarvationDelay: number;
|
|
54
|
+
maxLoadingDelay: number;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type BufferControllerConfig = {
|
|
58
|
+
appendErrorMaxRetry: number;
|
|
59
|
+
appendTimeout: number;
|
|
60
|
+
backBufferLength: number;
|
|
61
|
+
frontBufferFlushThreshold: number;
|
|
62
|
+
liveDurationInfinity: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* @deprecated use backBufferLength
|
|
65
|
+
*/
|
|
66
|
+
liveBackBufferLength: number | null;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type CapLevelControllerConfig = {
|
|
70
|
+
capLevelToPlayerSize: boolean;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type CMCDControllerConfig = {
|
|
74
|
+
sessionId?: string;
|
|
75
|
+
contentId?: string;
|
|
76
|
+
useHeaders?: boolean;
|
|
77
|
+
includeKeys?: string[];
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export type DRMSystemOptions = {
|
|
81
|
+
audioRobustness?: string;
|
|
82
|
+
videoRobustness?: string;
|
|
83
|
+
audioEncryptionScheme?: string | null;
|
|
84
|
+
videoEncryptionScheme?: string | null;
|
|
85
|
+
persistentState?: MediaKeysRequirement;
|
|
86
|
+
distinctiveIdentifier?: MediaKeysRequirement;
|
|
87
|
+
sessionTypes?: string[];
|
|
88
|
+
sessionType?: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type DRMSystemConfiguration = {
|
|
92
|
+
licenseUrl: string;
|
|
93
|
+
serverCertificateUrl?: string;
|
|
94
|
+
generateRequest?: (
|
|
95
|
+
this: Hls,
|
|
96
|
+
initDataType: string,
|
|
97
|
+
initData: ArrayBuffer | null,
|
|
98
|
+
keyContext: MediaKeySessionContext,
|
|
99
|
+
) =>
|
|
100
|
+
| { initDataType: string; initData: ArrayBuffer | null }
|
|
101
|
+
| undefined
|
|
102
|
+
| never;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export type DRMSystemsConfiguration = Partial<
|
|
106
|
+
Record<KeySystems, DRMSystemConfiguration>
|
|
107
|
+
>;
|
|
108
|
+
|
|
109
|
+
export type EMEControllerConfig = {
|
|
110
|
+
licenseXhrSetup?: (
|
|
111
|
+
this: Hls,
|
|
112
|
+
xhr: XMLHttpRequest,
|
|
113
|
+
url: string,
|
|
114
|
+
keyContext: MediaKeySessionContext,
|
|
115
|
+
licenseChallenge: Uint8Array,
|
|
116
|
+
) => void | Uint8Array | Promise<Uint8Array | void>;
|
|
117
|
+
licenseResponseCallback?: (
|
|
118
|
+
this: Hls,
|
|
119
|
+
xhr: XMLHttpRequest,
|
|
120
|
+
url: string,
|
|
121
|
+
keyContext: MediaKeySessionContext,
|
|
122
|
+
) => ArrayBuffer;
|
|
123
|
+
emeEnabled: boolean;
|
|
124
|
+
widevineLicenseUrl?: string;
|
|
125
|
+
drmSystems: DRMSystemsConfiguration | undefined;
|
|
126
|
+
drmSystemOptions: DRMSystemOptions | undefined;
|
|
127
|
+
requestMediaKeySystemAccessFunc: MediaKeyFunc | null;
|
|
128
|
+
requireKeySystemAccessOnStart: boolean;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export interface FragmentLoaderConstructor {
|
|
132
|
+
new (confg: HlsConfig): Loader<FragmentLoaderContext>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @deprecated use fragLoadPolicy.default
|
|
137
|
+
*/
|
|
138
|
+
export type FragmentLoaderConfig = {
|
|
139
|
+
fragLoadingTimeOut: number;
|
|
140
|
+
fragLoadingMaxRetry: number;
|
|
141
|
+
fragLoadingRetryDelay: number;
|
|
142
|
+
fragLoadingMaxRetryTimeout: number;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export type FPSControllerConfig = {
|
|
146
|
+
capLevelOnFPSDrop: boolean;
|
|
147
|
+
fpsDroppedMonitoringPeriod: number;
|
|
148
|
+
fpsDroppedMonitoringThreshold: number;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export type LevelControllerConfig = {
|
|
152
|
+
startLevel?: number;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export type MP4RemuxerConfig = {
|
|
156
|
+
stretchShortVideoTrack: boolean;
|
|
157
|
+
maxAudioFramesDrift: number;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export interface PlaylistLoaderConstructor {
|
|
161
|
+
new (confg: HlsConfig): Loader<PlaylistLoaderContext>;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @deprecated use manifestLoadPolicy.default and playlistLoadPolicy.default
|
|
166
|
+
*/
|
|
167
|
+
export type PlaylistLoaderConfig = {
|
|
168
|
+
manifestLoadingTimeOut: number;
|
|
169
|
+
manifestLoadingMaxRetry: number;
|
|
170
|
+
manifestLoadingRetryDelay: number;
|
|
171
|
+
manifestLoadingMaxRetryTimeout: number;
|
|
172
|
+
|
|
173
|
+
levelLoadingTimeOut: number;
|
|
174
|
+
levelLoadingMaxRetry: number;
|
|
175
|
+
levelLoadingRetryDelay: number;
|
|
176
|
+
levelLoadingMaxRetryTimeout: number;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export type HlsLoadPolicies = {
|
|
180
|
+
fragLoadPolicy: LoadPolicy;
|
|
181
|
+
keyLoadPolicy: LoadPolicy;
|
|
182
|
+
certLoadPolicy: LoadPolicy;
|
|
183
|
+
playlistLoadPolicy: LoadPolicy;
|
|
184
|
+
manifestLoadPolicy: LoadPolicy;
|
|
185
|
+
steeringManifestLoadPolicy: LoadPolicy;
|
|
186
|
+
interstitialAssetListLoadPolicy: LoadPolicy;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export type LoadPolicy = {
|
|
190
|
+
default: LoaderConfig;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export type LoaderConfig = {
|
|
194
|
+
maxTimeToFirstByteMs: number; // Max time to first byte
|
|
195
|
+
maxLoadTimeMs: number; // Max time for load completion
|
|
196
|
+
timeoutRetry: RetryConfig | null;
|
|
197
|
+
errorRetry: RetryConfig | null;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export type RetryConfig = {
|
|
201
|
+
maxNumRetry: number; // Maximum number of retries
|
|
202
|
+
retryDelayMs: number; // Retry delay = 2^retryCount * retryDelayMs (exponential) or retryCount * retryDelayMs (linear)
|
|
203
|
+
maxRetryDelayMs: number; // Maximum delay between retries
|
|
204
|
+
backoff?: 'exponential' | 'linear'; // used to determine retry backoff duration (see retryDelayMs)
|
|
205
|
+
shouldRetry?: (
|
|
206
|
+
retryConfig: RetryConfig | null | undefined,
|
|
207
|
+
retryCount: number,
|
|
208
|
+
isTimeout: boolean,
|
|
209
|
+
loaderResponse: LoaderResponse | undefined,
|
|
210
|
+
retry: boolean,
|
|
211
|
+
) => boolean;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export type StreamControllerConfig = {
|
|
215
|
+
autoStartLoad: boolean;
|
|
216
|
+
startPosition: number;
|
|
217
|
+
defaultAudioCodec?: string;
|
|
218
|
+
initialLiveManifestSize: number;
|
|
219
|
+
maxBufferLength: number;
|
|
220
|
+
maxBufferSize: number;
|
|
221
|
+
maxBufferHole: number;
|
|
222
|
+
maxFragLookUpTolerance: number;
|
|
223
|
+
maxMaxBufferLength: number;
|
|
224
|
+
startFragPrefetch: boolean;
|
|
225
|
+
testBandwidth: boolean;
|
|
226
|
+
liveSyncMode?: 'edge' | 'buffered';
|
|
227
|
+
startOnSegmentBoundary: boolean;
|
|
228
|
+
nextAudioTrackBufferFlushForwardOffset: number;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export type GapControllerConfig = {
|
|
232
|
+
detectStallWithCurrentTimeMs: number;
|
|
233
|
+
highBufferWatchdogPeriod: number;
|
|
234
|
+
nudgeOffset: number;
|
|
235
|
+
nudgeMaxRetry: number;
|
|
236
|
+
nudgeOnVideoHole: boolean;
|
|
237
|
+
skipBufferHolePadding: number;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export type SelectionPreferences = {
|
|
241
|
+
videoPreference?: VideoSelectionOption;
|
|
242
|
+
audioPreference?: AudioSelectionOption;
|
|
243
|
+
subtitlePreference?: SubtitleSelectionOption;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export type LatencyControllerConfig = {
|
|
247
|
+
liveSyncDurationCount: number;
|
|
248
|
+
liveMaxLatencyDurationCount: number;
|
|
249
|
+
liveSyncDuration?: number;
|
|
250
|
+
liveMaxLatencyDuration?: number;
|
|
251
|
+
maxLiveSyncPlaybackRate: number;
|
|
252
|
+
liveSyncOnStallIncrease: number;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export type PlaylistControllerConfig = {
|
|
256
|
+
liveMaxUnchangedPlaylistRefresh: number;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export type MetadataControllerConfig = {
|
|
260
|
+
enableDateRangeMetadataCues: boolean;
|
|
261
|
+
enableEmsgMetadataCues: boolean;
|
|
262
|
+
enableEmsgKLVMetadata: boolean;
|
|
263
|
+
enableID3MetadataCues: boolean;
|
|
264
|
+
emsgKLVSchemaUri?: string;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export type TimelineControllerConfig = {
|
|
268
|
+
cueHandler: CuesInterface;
|
|
269
|
+
enableWebVTT: boolean;
|
|
270
|
+
enableIMSC1: boolean;
|
|
271
|
+
enableCEA708Captions: boolean;
|
|
272
|
+
captionsTextTrack1Label: string;
|
|
273
|
+
captionsTextTrack1LanguageCode: string;
|
|
274
|
+
captionsTextTrack2Label: string;
|
|
275
|
+
captionsTextTrack2LanguageCode: string;
|
|
276
|
+
captionsTextTrack3Label: string;
|
|
277
|
+
captionsTextTrack3LanguageCode: string;
|
|
278
|
+
captionsTextTrack4Label: string;
|
|
279
|
+
captionsTextTrack4LanguageCode: string;
|
|
280
|
+
renderTextTracksNatively: boolean;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export type TSDemuxerConfig = {
|
|
284
|
+
forceKeyFrameOnDiscontinuity: boolean;
|
|
285
|
+
handleMpegTsVideoIntegrityErrors: 'process' | 'skip';
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export type HlsConfig = {
|
|
289
|
+
debug: boolean | ILogger;
|
|
290
|
+
enableWorker: boolean;
|
|
291
|
+
workerPath: null | string;
|
|
292
|
+
enableSoftwareAES: boolean;
|
|
293
|
+
minAutoBitrate: number;
|
|
294
|
+
ignoreDevicePixelRatio: boolean;
|
|
295
|
+
maxDevicePixelRatio: number;
|
|
296
|
+
preferManagedMediaSource: boolean;
|
|
297
|
+
preserveManualLevelOnError: boolean;
|
|
298
|
+
timelineOffset?: number;
|
|
299
|
+
ignorePlaylistParsingErrors: boolean;
|
|
300
|
+
algoDataEnabled: boolean;
|
|
301
|
+
algoSegmentPattern: RegExp | string;
|
|
302
|
+
algoPreloadCount: number;
|
|
303
|
+
algoCacheSize: number;
|
|
304
|
+
algoFrameRate?: number;
|
|
305
|
+
loader: { new (confg: HlsConfig): Loader<LoaderContext> };
|
|
306
|
+
fLoader?: FragmentLoaderConstructor;
|
|
307
|
+
pLoader?: PlaylistLoaderConstructor;
|
|
308
|
+
fetchSetup?: (
|
|
309
|
+
context: LoaderContext,
|
|
310
|
+
initParams: any,
|
|
311
|
+
) => Promise<Request> | Request;
|
|
312
|
+
xhrSetup?: (xhr: XMLHttpRequest, url: string) => Promise<void> | void;
|
|
313
|
+
|
|
314
|
+
// Alt Audio
|
|
315
|
+
audioStreamController?: typeof AudioStreamController;
|
|
316
|
+
audioTrackController?: typeof AudioTrackController;
|
|
317
|
+
// Subtitle
|
|
318
|
+
subtitleStreamController?: typeof SubtitleStreamController;
|
|
319
|
+
subtitleTrackController?: typeof SubtitleTrackController;
|
|
320
|
+
timelineController?: typeof TimelineController;
|
|
321
|
+
// EME
|
|
322
|
+
emeController?: typeof EMEController;
|
|
323
|
+
// CMCD
|
|
324
|
+
cmcd?: CMCDControllerConfig;
|
|
325
|
+
cmcdController?: typeof CMCDController;
|
|
326
|
+
// Content Steering
|
|
327
|
+
contentSteeringController?: typeof ContentSteeringController;
|
|
328
|
+
// Interstitial Controller (setting to null disables Interstitials parsing and playback)
|
|
329
|
+
interstitialsController?: typeof InterstitialsController;
|
|
330
|
+
// Option to disable internal playback handling of Interstitials (set to false to disable Interstitials playback without disabling parsing and schedule events)
|
|
331
|
+
enableInterstitialPlayback: boolean;
|
|
332
|
+
// Option to disable appending Interstitials inline on same timeline and MediaSource as Primary media
|
|
333
|
+
interstitialAppendInPlace: boolean;
|
|
334
|
+
// How many seconds past the end of a live playlist to preload Interstitial assets
|
|
335
|
+
interstitialLiveLookAhead: number;
|
|
336
|
+
// An optional `Hls` instance ID prefixed to debug logs
|
|
337
|
+
assetPlayerId?: string;
|
|
338
|
+
// MediaCapabilies API for level, track, and switch filtering
|
|
339
|
+
useMediaCapabilities: boolean;
|
|
340
|
+
|
|
341
|
+
abrController: typeof AbrController;
|
|
342
|
+
bufferController: typeof BufferController;
|
|
343
|
+
capLevelController: typeof CapLevelController;
|
|
344
|
+
errorController: typeof ErrorController;
|
|
345
|
+
fpsController: typeof FPSController;
|
|
346
|
+
progressive: boolean;
|
|
347
|
+
lowLatencyMode: boolean;
|
|
348
|
+
primarySessionId?: string;
|
|
349
|
+
} & ABRControllerConfig &
|
|
350
|
+
BufferControllerConfig &
|
|
351
|
+
CapLevelControllerConfig &
|
|
352
|
+
EMEControllerConfig &
|
|
353
|
+
FPSControllerConfig &
|
|
354
|
+
GapControllerConfig &
|
|
355
|
+
LevelControllerConfig &
|
|
356
|
+
MP4RemuxerConfig &
|
|
357
|
+
StreamControllerConfig &
|
|
358
|
+
SelectionPreferences &
|
|
359
|
+
LatencyControllerConfig &
|
|
360
|
+
MetadataControllerConfig &
|
|
361
|
+
TimelineControllerConfig &
|
|
362
|
+
TSDemuxerConfig &
|
|
363
|
+
HlsLoadPolicies &
|
|
364
|
+
PlaylistControllerConfig &
|
|
365
|
+
FragmentLoaderConfig &
|
|
366
|
+
PlaylistLoaderConfig;
|
|
367
|
+
|
|
368
|
+
const defaultLoadPolicy: LoaderConfig = {
|
|
369
|
+
maxTimeToFirstByteMs: 8000,
|
|
370
|
+
maxLoadTimeMs: 20000,
|
|
371
|
+
timeoutRetry: null,
|
|
372
|
+
errorRetry: null,
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* @ignore
|
|
377
|
+
* If possible, keep hlsDefaultConfig shallow
|
|
378
|
+
* It is cloned whenever a new Hls instance is created, by keeping the config
|
|
379
|
+
* shallow the properties are cloned, and we don't end up manipulating the default
|
|
380
|
+
*/
|
|
381
|
+
export const hlsDefaultConfig: HlsConfig = {
|
|
382
|
+
autoStartLoad: true, // used by stream-controller
|
|
383
|
+
startPosition: -1, // used by stream-controller
|
|
384
|
+
defaultAudioCodec: undefined, // used by stream-controller
|
|
385
|
+
debug: false, // used by logger
|
|
386
|
+
capLevelOnFPSDrop: false, // used by fps-controller
|
|
387
|
+
capLevelToPlayerSize: false, // used by cap-level-controller
|
|
388
|
+
ignoreDevicePixelRatio: false, // used by cap-level-controller
|
|
389
|
+
maxDevicePixelRatio: Number.POSITIVE_INFINITY, // used by cap-level-controller
|
|
390
|
+
preferManagedMediaSource: true,
|
|
391
|
+
initialLiveManifestSize: 1, // used by stream-controller
|
|
392
|
+
maxBufferLength: 30, // used by stream-controller
|
|
393
|
+
backBufferLength: Infinity, // used by buffer-controller
|
|
394
|
+
frontBufferFlushThreshold: Infinity,
|
|
395
|
+
startOnSegmentBoundary: false, // used by stream-controller
|
|
396
|
+
nextAudioTrackBufferFlushForwardOffset: 0.25, // used by stream-controller
|
|
397
|
+
maxBufferSize: 60 * 1000 * 1000, // used by stream-controller
|
|
398
|
+
maxFragLookUpTolerance: 0.25, // used by stream-controller
|
|
399
|
+
maxBufferHole: 0.1, // used by stream-controller and gap-controller
|
|
400
|
+
detectStallWithCurrentTimeMs: 1250, // used by gap-controller
|
|
401
|
+
highBufferWatchdogPeriod: 2, // used by gap-controller
|
|
402
|
+
nudgeOffset: 0.1, // used by gap-controller
|
|
403
|
+
nudgeMaxRetry: 3, // used by gap-controller
|
|
404
|
+
nudgeOnVideoHole: true, // used by gap-controller
|
|
405
|
+
skipBufferHolePadding: 0.1, // used by gap-controller
|
|
406
|
+
liveSyncMode: 'edge', // used by stream-controller
|
|
407
|
+
liveSyncDurationCount: 3, // used by latency-controller
|
|
408
|
+
liveSyncOnStallIncrease: 1, // used by latency-controller
|
|
409
|
+
liveMaxLatencyDurationCount: Infinity, // used by latency-controller
|
|
410
|
+
liveMaxUnchangedPlaylistRefresh: Infinity, // used by base-playlist-controller
|
|
411
|
+
liveSyncDuration: undefined, // used by latency-controller
|
|
412
|
+
liveMaxLatencyDuration: undefined, // used by latency-controller
|
|
413
|
+
maxLiveSyncPlaybackRate: 1, // used by latency-controller
|
|
414
|
+
liveDurationInfinity: false, // used by buffer-controller
|
|
415
|
+
/**
|
|
416
|
+
* @deprecated use backBufferLength
|
|
417
|
+
*/
|
|
418
|
+
liveBackBufferLength: null, // used by buffer-controller
|
|
419
|
+
maxMaxBufferLength: 600, // used by stream-controller
|
|
420
|
+
enableWorker: true, // used by transmuxer
|
|
421
|
+
workerPath: null, // used by transmuxer
|
|
422
|
+
enableSoftwareAES: true, // used by decrypter
|
|
423
|
+
startLevel: undefined, // used by level-controller
|
|
424
|
+
startFragPrefetch: false, // used by stream-controller
|
|
425
|
+
fpsDroppedMonitoringPeriod: 5000, // used by fps-controller
|
|
426
|
+
fpsDroppedMonitoringThreshold: 0.2, // used by fps-controller
|
|
427
|
+
appendErrorMaxRetry: 3, // used by buffer-controller
|
|
428
|
+
appendTimeout: Infinity, // used by buffer-controller
|
|
429
|
+
ignorePlaylistParsingErrors: false,
|
|
430
|
+
algoDataEnabled: false,
|
|
431
|
+
// 中文注释:算法分片统一包含 _dat.ts(查询参数已在解析阶段剔除)
|
|
432
|
+
algoSegmentPattern: /_dat\.ts$/i,
|
|
433
|
+
algoPreloadCount: 2,
|
|
434
|
+
algoCacheSize: 10,
|
|
435
|
+
algoFrameRate: undefined,
|
|
436
|
+
loader: XhrLoader,
|
|
437
|
+
// loader: FetchLoader,
|
|
438
|
+
fLoader: undefined, // used by fragment-loader
|
|
439
|
+
pLoader: undefined, // used by playlist-loader
|
|
440
|
+
xhrSetup: undefined, // used by xhr-loader
|
|
441
|
+
licenseXhrSetup: undefined, // used by eme-controller
|
|
442
|
+
licenseResponseCallback: undefined, // used by eme-controller
|
|
443
|
+
abrController: AbrController,
|
|
444
|
+
bufferController: BufferController,
|
|
445
|
+
capLevelController: CapLevelController,
|
|
446
|
+
errorController: ErrorController,
|
|
447
|
+
fpsController: FPSController,
|
|
448
|
+
stretchShortVideoTrack: false, // used by mp4-remuxer
|
|
449
|
+
maxAudioFramesDrift: 1, // used by mp4-remuxer
|
|
450
|
+
forceKeyFrameOnDiscontinuity: true, // used by ts-demuxer
|
|
451
|
+
handleMpegTsVideoIntegrityErrors: 'process', // used by ts-demuxer
|
|
452
|
+
abrEwmaFastLive: 3, // used by abr-controller
|
|
453
|
+
abrEwmaSlowLive: 9, // used by abr-controller
|
|
454
|
+
abrEwmaFastVoD: 3, // used by abr-controller
|
|
455
|
+
abrEwmaSlowVoD: 9, // used by abr-controller
|
|
456
|
+
abrEwmaDefaultEstimate: 5e5, // 500 kbps // used by abr-controller
|
|
457
|
+
abrEwmaDefaultEstimateMax: 5e6, // 5 mbps
|
|
458
|
+
abrBandWidthFactor: 0.95, // used by abr-controller
|
|
459
|
+
abrBandWidthUpFactor: 0.7, // used by abr-controller
|
|
460
|
+
abrMaxWithRealBitrate: false, // used by abr-controller
|
|
461
|
+
abrSwitchInterval: 0, // used by level-controller
|
|
462
|
+
maxStarvationDelay: 4, // used by abr-controller
|
|
463
|
+
maxLoadingDelay: 4, // used by abr-controller
|
|
464
|
+
minAutoBitrate: 0, // used by hls
|
|
465
|
+
emeEnabled: false, // used by eme-controller
|
|
466
|
+
widevineLicenseUrl: undefined, // used by eme-controller
|
|
467
|
+
drmSystems: {}, // used by eme-controller
|
|
468
|
+
drmSystemOptions: {}, // used by eme-controller
|
|
469
|
+
requestMediaKeySystemAccessFunc: __USE_EME_DRM__
|
|
470
|
+
? requestMediaKeySystemAccess
|
|
471
|
+
: null, // used by eme-controller
|
|
472
|
+
requireKeySystemAccessOnStart: false, // used by eme-controller
|
|
473
|
+
testBandwidth: true,
|
|
474
|
+
progressive: false,
|
|
475
|
+
lowLatencyMode: true,
|
|
476
|
+
cmcd: undefined,
|
|
477
|
+
enableDateRangeMetadataCues: true,
|
|
478
|
+
enableEmsgMetadataCues: true,
|
|
479
|
+
enableEmsgKLVMetadata: false,
|
|
480
|
+
enableID3MetadataCues: true,
|
|
481
|
+
emsgKLVSchemaUri: undefined, // Defaults to 'urn:misb:KLV:bin:1910.1' in demuxer for backwards compatibility
|
|
482
|
+
enableInterstitialPlayback: __USE_INTERSTITIALS__,
|
|
483
|
+
interstitialAppendInPlace: true,
|
|
484
|
+
interstitialLiveLookAhead: 10,
|
|
485
|
+
useMediaCapabilities: __USE_MEDIA_CAPABILITIES__,
|
|
486
|
+
preserveManualLevelOnError: false,
|
|
487
|
+
|
|
488
|
+
certLoadPolicy: {
|
|
489
|
+
default: defaultLoadPolicy,
|
|
490
|
+
},
|
|
491
|
+
keyLoadPolicy: {
|
|
492
|
+
default: {
|
|
493
|
+
maxTimeToFirstByteMs: 8000,
|
|
494
|
+
maxLoadTimeMs: 20000,
|
|
495
|
+
timeoutRetry: {
|
|
496
|
+
maxNumRetry: 1,
|
|
497
|
+
retryDelayMs: 1000,
|
|
498
|
+
maxRetryDelayMs: 20000,
|
|
499
|
+
backoff: 'linear',
|
|
500
|
+
},
|
|
501
|
+
errorRetry: {
|
|
502
|
+
maxNumRetry: 8,
|
|
503
|
+
retryDelayMs: 1000,
|
|
504
|
+
maxRetryDelayMs: 20000,
|
|
505
|
+
backoff: 'linear',
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
manifestLoadPolicy: {
|
|
510
|
+
default: {
|
|
511
|
+
maxTimeToFirstByteMs: Infinity,
|
|
512
|
+
maxLoadTimeMs: 20000,
|
|
513
|
+
timeoutRetry: {
|
|
514
|
+
maxNumRetry: 2,
|
|
515
|
+
retryDelayMs: 0,
|
|
516
|
+
maxRetryDelayMs: 0,
|
|
517
|
+
},
|
|
518
|
+
errorRetry: {
|
|
519
|
+
maxNumRetry: 1,
|
|
520
|
+
retryDelayMs: 1000,
|
|
521
|
+
maxRetryDelayMs: 8000,
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
playlistLoadPolicy: {
|
|
526
|
+
default: {
|
|
527
|
+
maxTimeToFirstByteMs: 10000,
|
|
528
|
+
maxLoadTimeMs: 20000,
|
|
529
|
+
timeoutRetry: {
|
|
530
|
+
maxNumRetry: 2,
|
|
531
|
+
retryDelayMs: 0,
|
|
532
|
+
maxRetryDelayMs: 0,
|
|
533
|
+
},
|
|
534
|
+
errorRetry: {
|
|
535
|
+
maxNumRetry: 2,
|
|
536
|
+
retryDelayMs: 1000,
|
|
537
|
+
maxRetryDelayMs: 8000,
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
fragLoadPolicy: {
|
|
542
|
+
default: {
|
|
543
|
+
maxTimeToFirstByteMs: 10000,
|
|
544
|
+
maxLoadTimeMs: 120000,
|
|
545
|
+
timeoutRetry: {
|
|
546
|
+
maxNumRetry: 4,
|
|
547
|
+
retryDelayMs: 0,
|
|
548
|
+
maxRetryDelayMs: 0,
|
|
549
|
+
},
|
|
550
|
+
errorRetry: {
|
|
551
|
+
maxNumRetry: 6,
|
|
552
|
+
retryDelayMs: 1000,
|
|
553
|
+
maxRetryDelayMs: 8000,
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
steeringManifestLoadPolicy: {
|
|
558
|
+
default: __USE_CONTENT_STEERING__
|
|
559
|
+
? {
|
|
560
|
+
maxTimeToFirstByteMs: 10000,
|
|
561
|
+
maxLoadTimeMs: 20000,
|
|
562
|
+
timeoutRetry: {
|
|
563
|
+
maxNumRetry: 2,
|
|
564
|
+
retryDelayMs: 0,
|
|
565
|
+
maxRetryDelayMs: 0,
|
|
566
|
+
},
|
|
567
|
+
errorRetry: {
|
|
568
|
+
maxNumRetry: 1,
|
|
569
|
+
retryDelayMs: 1000,
|
|
570
|
+
maxRetryDelayMs: 8000,
|
|
571
|
+
},
|
|
572
|
+
}
|
|
573
|
+
: defaultLoadPolicy,
|
|
574
|
+
},
|
|
575
|
+
interstitialAssetListLoadPolicy: {
|
|
576
|
+
default: __USE_INTERSTITIALS__
|
|
577
|
+
? {
|
|
578
|
+
maxTimeToFirstByteMs: 10000,
|
|
579
|
+
maxLoadTimeMs: 30000,
|
|
580
|
+
timeoutRetry: {
|
|
581
|
+
maxNumRetry: 0,
|
|
582
|
+
retryDelayMs: 0,
|
|
583
|
+
maxRetryDelayMs: 0,
|
|
584
|
+
},
|
|
585
|
+
errorRetry: {
|
|
586
|
+
maxNumRetry: 0,
|
|
587
|
+
retryDelayMs: 1000,
|
|
588
|
+
maxRetryDelayMs: 8000,
|
|
589
|
+
},
|
|
590
|
+
}
|
|
591
|
+
: defaultLoadPolicy,
|
|
592
|
+
},
|
|
593
|
+
|
|
594
|
+
// These default settings are deprecated in favor of the above policies
|
|
595
|
+
// and are maintained for backwards compatibility
|
|
596
|
+
manifestLoadingTimeOut: 10000,
|
|
597
|
+
manifestLoadingMaxRetry: 1,
|
|
598
|
+
manifestLoadingRetryDelay: 1000,
|
|
599
|
+
manifestLoadingMaxRetryTimeout: 64000,
|
|
600
|
+
levelLoadingTimeOut: 10000,
|
|
601
|
+
levelLoadingMaxRetry: 4,
|
|
602
|
+
levelLoadingRetryDelay: 1000,
|
|
603
|
+
levelLoadingMaxRetryTimeout: 64000,
|
|
604
|
+
fragLoadingTimeOut: 20000,
|
|
605
|
+
fragLoadingMaxRetry: 6,
|
|
606
|
+
fragLoadingRetryDelay: 1000,
|
|
607
|
+
fragLoadingMaxRetryTimeout: 64000,
|
|
608
|
+
|
|
609
|
+
// Dynamic Modules
|
|
610
|
+
...timelineConfig(),
|
|
611
|
+
subtitleStreamController: __USE_SUBTITLES__
|
|
612
|
+
? SubtitleStreamController
|
|
613
|
+
: undefined,
|
|
614
|
+
subtitleTrackController: __USE_SUBTITLES__
|
|
615
|
+
? SubtitleTrackController
|
|
616
|
+
: undefined,
|
|
617
|
+
timelineController: __USE_SUBTITLES__ ? TimelineController : undefined,
|
|
618
|
+
audioStreamController: __USE_ALT_AUDIO__ ? AudioStreamController : undefined,
|
|
619
|
+
audioTrackController: __USE_ALT_AUDIO__ ? AudioTrackController : undefined,
|
|
620
|
+
emeController: __USE_EME_DRM__ ? EMEController : undefined,
|
|
621
|
+
cmcdController: __USE_CMCD__ ? CMCDController : undefined,
|
|
622
|
+
contentSteeringController: __USE_CONTENT_STEERING__
|
|
623
|
+
? ContentSteeringController
|
|
624
|
+
: undefined,
|
|
625
|
+
interstitialsController: __USE_INTERSTITIALS__
|
|
626
|
+
? InterstitialsController
|
|
627
|
+
: undefined,
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
function timelineConfig(): TimelineControllerConfig {
|
|
631
|
+
return {
|
|
632
|
+
cueHandler: Cues, // used by timeline-controller
|
|
633
|
+
enableWebVTT: __USE_SUBTITLES__, // used by timeline-controller
|
|
634
|
+
enableIMSC1: __USE_SUBTITLES__, // used by timeline-controller
|
|
635
|
+
enableCEA708Captions: __USE_SUBTITLES__, // used by timeline-controller
|
|
636
|
+
captionsTextTrack1Label: 'English', // used by timeline-controller
|
|
637
|
+
captionsTextTrack1LanguageCode: 'en', // used by timeline-controller
|
|
638
|
+
captionsTextTrack2Label: 'Spanish', // used by timeline-controller
|
|
639
|
+
captionsTextTrack2LanguageCode: 'es', // used by timeline-controller
|
|
640
|
+
captionsTextTrack3Label: 'Unknown CC', // used by timeline-controller
|
|
641
|
+
captionsTextTrack3LanguageCode: '', // used by timeline-controller
|
|
642
|
+
captionsTextTrack4Label: 'Unknown CC', // used by timeline-controller
|
|
643
|
+
captionsTextTrack4LanguageCode: '', // used by timeline-controller
|
|
644
|
+
renderTextTracksNatively: true,
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* @ignore
|
|
650
|
+
*/
|
|
651
|
+
export function mergeConfig(
|
|
652
|
+
defaultConfig: HlsConfig,
|
|
653
|
+
userConfig: Partial<HlsConfig>,
|
|
654
|
+
logger: ILogger,
|
|
655
|
+
): HlsConfig {
|
|
656
|
+
if (
|
|
657
|
+
(userConfig.liveSyncDurationCount ||
|
|
658
|
+
userConfig.liveMaxLatencyDurationCount) &&
|
|
659
|
+
(userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)
|
|
660
|
+
) {
|
|
661
|
+
throw new Error(
|
|
662
|
+
"Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration",
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (
|
|
667
|
+
userConfig.liveMaxLatencyDurationCount !== undefined &&
|
|
668
|
+
(userConfig.liveSyncDurationCount === undefined ||
|
|
669
|
+
userConfig.liveMaxLatencyDurationCount <=
|
|
670
|
+
userConfig.liveSyncDurationCount)
|
|
671
|
+
) {
|
|
672
|
+
throw new Error(
|
|
673
|
+
'Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"',
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (
|
|
678
|
+
userConfig.liveMaxLatencyDuration !== undefined &&
|
|
679
|
+
(userConfig.liveSyncDuration === undefined ||
|
|
680
|
+
userConfig.liveMaxLatencyDuration <= userConfig.liveSyncDuration)
|
|
681
|
+
) {
|
|
682
|
+
throw new Error(
|
|
683
|
+
'Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"',
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (userConfig.liveMaxUnchangedPlaylistRefresh !== undefined) {
|
|
688
|
+
const liveMaxUnchangedPlaylistRefresh =
|
|
689
|
+
userConfig.liveMaxUnchangedPlaylistRefresh;
|
|
690
|
+
const clampedValue = clamp(liveMaxUnchangedPlaylistRefresh, 2, Infinity);
|
|
691
|
+
|
|
692
|
+
if (clampedValue !== liveMaxUnchangedPlaylistRefresh) {
|
|
693
|
+
logger.warn(
|
|
694
|
+
`hls.js config: "liveMaxUnchangedPlaylistRefresh" clamped from ${liveMaxUnchangedPlaylistRefresh} to ${clampedValue}.`,
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
userConfig.liveMaxUnchangedPlaylistRefresh = clampedValue;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
const defaultsCopy = deepCpy(defaultConfig);
|
|
701
|
+
|
|
702
|
+
// Backwards compatibility with deprecated config values
|
|
703
|
+
const deprecatedSettingTypes = ['manifest', 'level', 'frag'];
|
|
704
|
+
const deprecatedSettings = [
|
|
705
|
+
'TimeOut',
|
|
706
|
+
'MaxRetry',
|
|
707
|
+
'RetryDelay',
|
|
708
|
+
'MaxRetryTimeout',
|
|
709
|
+
];
|
|
710
|
+
deprecatedSettingTypes.forEach((type) => {
|
|
711
|
+
const policyName = `${type === 'level' ? 'playlist' : type}LoadPolicy`;
|
|
712
|
+
const policyNotSet = userConfig[policyName] === undefined;
|
|
713
|
+
const report: string[] = [];
|
|
714
|
+
deprecatedSettings.forEach((setting) => {
|
|
715
|
+
const deprecatedSetting = `${type}Loading${setting}`;
|
|
716
|
+
const value = userConfig[deprecatedSetting];
|
|
717
|
+
if (value !== undefined && policyNotSet) {
|
|
718
|
+
report.push(deprecatedSetting);
|
|
719
|
+
const settings: LoaderConfig = defaultsCopy[policyName].default;
|
|
720
|
+
userConfig[policyName] = { default: settings };
|
|
721
|
+
switch (setting) {
|
|
722
|
+
case 'TimeOut':
|
|
723
|
+
settings.maxLoadTimeMs = value;
|
|
724
|
+
settings.maxTimeToFirstByteMs = value;
|
|
725
|
+
break;
|
|
726
|
+
case 'MaxRetry':
|
|
727
|
+
settings.errorRetry!.maxNumRetry = value;
|
|
728
|
+
settings.timeoutRetry!.maxNumRetry = value;
|
|
729
|
+
break;
|
|
730
|
+
case 'RetryDelay':
|
|
731
|
+
settings.errorRetry!.retryDelayMs = value;
|
|
732
|
+
settings.timeoutRetry!.retryDelayMs = value;
|
|
733
|
+
break;
|
|
734
|
+
case 'MaxRetryTimeout':
|
|
735
|
+
settings.errorRetry!.maxRetryDelayMs = value;
|
|
736
|
+
settings.timeoutRetry!.maxRetryDelayMs = value;
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
if (report.length) {
|
|
742
|
+
logger.warn(
|
|
743
|
+
`hls.js config: "${report.join(
|
|
744
|
+
'", "',
|
|
745
|
+
)}" setting(s) are deprecated, use "${policyName}": ${stringify(
|
|
746
|
+
userConfig[policyName],
|
|
747
|
+
)}`,
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
return {
|
|
753
|
+
...defaultsCopy,
|
|
754
|
+
...userConfig,
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
function deepCpy(obj: any): any {
|
|
759
|
+
if (obj && typeof obj === 'object') {
|
|
760
|
+
if (obj instanceof RegExp) {
|
|
761
|
+
return new RegExp(obj.source, obj.flags);
|
|
762
|
+
}
|
|
763
|
+
if (Array.isArray(obj)) {
|
|
764
|
+
return obj.map(deepCpy);
|
|
765
|
+
}
|
|
766
|
+
return Object.keys(obj).reduce((result, key) => {
|
|
767
|
+
result[key] = deepCpy(obj[key]);
|
|
768
|
+
return result;
|
|
769
|
+
}, {});
|
|
770
|
+
}
|
|
771
|
+
return obj;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* @ignore
|
|
776
|
+
*/
|
|
777
|
+
export function enableStreamingMode(config: HlsConfig, logger: ILogger) {
|
|
778
|
+
const currentLoader = config.loader;
|
|
779
|
+
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
|
|
780
|
+
// If a developer has configured their own loader, respect that choice
|
|
781
|
+
logger.log(
|
|
782
|
+
'[config]: Custom loader detected, cannot enable progressive streaming',
|
|
783
|
+
);
|
|
784
|
+
config.progressive = false;
|
|
785
|
+
} else {
|
|
786
|
+
const canStreamProgressively = fetchSupported();
|
|
787
|
+
if (canStreamProgressively) {
|
|
788
|
+
config.loader = FetchLoader;
|
|
789
|
+
config.progressive = true;
|
|
790
|
+
config.enableSoftwareAES = true;
|
|
791
|
+
logger.log('[config]: Progressive streaming enabled, using FetchLoader');
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|