@@ -24,8 +24,8 @@ export default class BasePlaylistController
24
24
implements NetworkComponentAPI
25
25
{
26
26
protected hls : Hls ;
27
+ protected canLoad : boolean = false ;
27
28
private timer : number = - 1 ;
28
- private canLoad : boolean = false ;
29
29
30
30
constructor ( hls : Hls , logPrefix : string ) {
31
31
super ( logPrefix , hls . logger ) ;
@@ -170,6 +170,25 @@ export default class BasePlaylistController
170
170
if ( details . live || previousDetails ?. live ) {
171
171
const levelOrTrack = 'levelInfo' in data ? data . levelInfo : data . track ;
172
172
details . reloaded ( previousDetails ) ;
173
+ // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
174
+ if ( previousDetails && details . fragments . length > 0 ) {
175
+ mergeDetails ( previousDetails , details ) ;
176
+ }
177
+ if ( details . requestScheduled === - 1 ) {
178
+ details . requestScheduled = stats . loading . start ;
179
+ }
180
+ const bufferInfo = this . hls . mainForwardBufferInfo ;
181
+ const position = bufferInfo ? bufferInfo . end - bufferInfo . len : 0 ;
182
+ const distanceToLiveEdgeMs = ( details . edge - position ) * 1000 ;
183
+ const reloadInterval = computeReloadInterval (
184
+ details ,
185
+ distanceToLiveEdgeMs ,
186
+ ) ;
187
+ if ( details . requestScheduled + reloadInterval < now ) {
188
+ details . requestScheduled = now ;
189
+ } else {
190
+ details . requestScheduled += reloadInterval ;
191
+ }
173
192
this . log (
174
193
`live playlist ${ index } ${
175
194
details . advanced
@@ -179,10 +198,6 @@ export default class BasePlaylistController
179
198
: 'MISSED'
180
199
} `,
181
200
) ;
182
- // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
183
- if ( previousDetails && details . fragments . length > 0 ) {
184
- mergeDetails ( previousDetails , details ) ;
185
- }
186
201
if ( ! this . canLoad || ! details . live ) {
187
202
return ;
188
203
}
@@ -196,12 +211,16 @@ export default class BasePlaylistController
196
211
const endSn = details . endSN ;
197
212
const lastPartIndex = details . lastPartIndex ;
198
213
const hasParts = lastPartIndex !== - 1 ;
199
- const lastPart = lastPartSn === endSn ;
200
- // When low latency mode is disabled, we'll skip part requests once the last part index is found
201
- const nextSnStartIndex = lowLatencyMode ? 0 : lastPartIndex ;
214
+ const atLastPartOfSegment = lastPartSn === endSn ;
202
215
if ( hasParts ) {
203
- msn = lastPart ? endSn + 1 : lastPartSn ;
204
- part = lastPart ? nextSnStartIndex : lastPartIndex + 1 ;
216
+ // When low latency mode is disabled, request the last part of the next segment
217
+ if ( atLastPartOfSegment ) {
218
+ msn = endSn + 1 ;
219
+ part = lowLatencyMode ? 0 : lastPartIndex ;
220
+ } else {
221
+ msn = lastPartSn ;
222
+ part = lowLatencyMode ? lastPartIndex + 1 : details . maxPartIndex ;
223
+ }
205
224
} else {
206
225
msn = endSn + 1 ;
207
226
}
@@ -258,7 +277,8 @@ export default class BasePlaylistController
258
277
msn ,
259
278
part ,
260
279
) ;
261
- if ( lowLatencyMode || ! lastPart ) {
280
+ if ( lowLatencyMode || ! atLastPartOfSegment ) {
281
+ details . requestScheduled = now ;
262
282
this . loadingPlaylist ( levelOrTrack , deliveryDirectives ) ;
263
283
return ;
264
284
}
@@ -270,25 +290,12 @@ export default class BasePlaylistController
270
290
part ,
271
291
) ;
272
292
}
273
- if ( details . requestScheduled === - 1 ) {
274
- details . requestScheduled = stats . loading . start ;
275
- }
276
293
if ( deliveryDirectives && msn !== undefined && details . canBlockReload ) {
277
- details . requestScheduled -= details . partTarget * 1000 || 1000 ;
278
- }
279
- const bufferInfo = this . hls . mainForwardBufferInfo ;
280
- const position = bufferInfo ? bufferInfo . end - bufferInfo . len : 0 ;
281
- const distanceToLiveEdgeMs = ( details . edge - position ) * 1000 ;
282
- const reloadInterval = computeReloadInterval (
283
- details ,
284
- distanceToLiveEdgeMs ,
285
- ) ;
286
- if ( details . requestScheduled + reloadInterval < now ) {
287
- details . requestScheduled = now ;
288
- } else {
289
- details . requestScheduled += reloadInterval ;
294
+ details . requestScheduled =
295
+ stats . loading . first +
296
+ Math . max ( reloadInterval - elapsed * 2 , reloadInterval / 2 ) ;
290
297
}
291
- this . scheduleLoading ( levelOrTrack , deliveryDirectives ) ;
298
+ this . scheduleLoading ( levelOrTrack , deliveryDirectives , details ) ;
292
299
} else {
293
300
this . clearTimer ( ) ;
294
301
}
@@ -297,8 +304,9 @@ export default class BasePlaylistController
297
304
protected scheduleLoading (
298
305
levelOrTrack : Level | MediaPlaylist ,
299
306
deliveryDirectives ?: HlsUrlParameters ,
307
+ updatedDetails ?: LevelDetails ,
300
308
) {
301
- const details = levelOrTrack . details ;
309
+ const details = updatedDetails || levelOrTrack . details ;
302
310
if ( ! details ) {
303
311
this . loadingPlaylist ( levelOrTrack , deliveryDirectives ) ;
304
312
return ;
@@ -316,22 +324,8 @@ export default class BasePlaylistController
316
324
estimatedTimeUntilUpdate ,
317
325
) } ms`,
318
326
) ;
319
- // this.log(
320
- // `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
321
- // reload in ${estimatedTimeUntilUpdate / 1000}
322
- // round trip ${(stats.loading.end - stats.loading.start) / 1000}
323
- // diff ${
324
- // (reloadInterval -
325
- // (estimatedTimeUntilUpdate +
326
- // stats.loading.end -
327
- // stats.loading.start)) /
328
- // 1000
329
- // }
330
- // reload interval ${reloadInterval / 1000}
331
- // target duration ${details.targetduration}
332
- // distance to edge ${distanceToLiveEdgeMs / 1000}`
333
- // );
334
327
328
+ this . clearTimer ( ) ;
335
329
this . timer = self . setTimeout (
336
330
( ) => this . loadingPlaylist ( levelOrTrack , deliveryDirectives ) ,
337
331
estimatedTimeUntilUpdate ,
@@ -379,6 +373,7 @@ export default class BasePlaylistController
379
373
} else {
380
374
const delay = getRetryDelay ( retryConfig , retryCount ) ;
381
375
// Schedule level/track reload
376
+ this . clearTimer ( ) ;
382
377
this . timer = self . setTimeout ( ( ) => this . loadPlaylist ( ) , delay ) ;
383
378
this . warn (
384
379
`Retrying playlist loading ${ retryCount + 1 } /${
0 commit comments