Skip to content

Commit ed5915e

Browse files
authored
fix(HLS): Fix load of LL-HLS when the partial segment is not independent (#5277)
1 parent 70823f9 commit ed5915e

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

lib/hls/hls_parser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,6 +2895,9 @@ shaka.hls.HlsParser = class {
28952895
if (item.name == 'EXT-X-PRELOAD-HINT') {
28962896
partial.markAsPreload();
28972897
}
2898+
if (item.getAttributeValue('INDEPENDENT') != 'YES') {
2899+
partial.markAsNonIndependent();
2900+
}
28982901
partialSegmentRefs.push(partial);
28992902
} // for-loop of hlsSegment.partialSegments
29002903
}

lib/media/segment_reference.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ shaka.media.SegmentReference = class {
265265
/** @type {boolean} */
266266
this.preload = false;
267267

268+
/** @type {boolean} */
269+
this.independent = true;
270+
268271
/** @type {?shaka.extern.HlsAes128Key} */
269272
this.hlsAes128Key = hlsAes128Key;
270273

@@ -407,6 +410,25 @@ shaka.media.SegmentReference = class {
407410
return this.preload;
408411
}
409412

413+
/**
414+
* Mark the reference as non-independent.
415+
*
416+
* @export
417+
*/
418+
markAsNonIndependent() {
419+
this.independent = false;
420+
}
421+
422+
/**
423+
* Returns true if the segment is independent.
424+
*
425+
* @return {boolean}
426+
* @export
427+
*/
428+
isIndependent() {
429+
return this.independent;
430+
}
431+
410432
/**
411433
* Set the segment's thumbnail sprite.
412434
*

lib/media/streaming_engine.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,17 @@ shaka.media.StreamingEngine = class {
12621262
mediaState.stream.segmentIndex.getIteratorForTime(presentationTime);
12631263
ref = mediaState.segmentIterator &&
12641264
mediaState.segmentIterator.next().value;
1265+
// For LL-HLS we need to find the nearest INDEPENDENT segment
1266+
let attempt = 0;
1267+
const maxAttempts = 5;
1268+
while (ref && !ref.isIndependent() && attempt < maxAttempts) {
1269+
const newTime = ref.startTime - 0.1;
1270+
mediaState.segmentIterator =
1271+
mediaState.stream.segmentIndex.getIteratorForTime(newTime);
1272+
ref = mediaState.segmentIterator &&
1273+
mediaState.segmentIterator.next().value;
1274+
attempt++;
1275+
}
12651276
}
12661277
if (ref == null) {
12671278
shaka.log.warning(logPrefix, 'cannot find segment',

test/hls/hls_live_unit.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -634,14 +634,17 @@ describe('HlsParser live', () => {
634634
'#EXT-X-MEDIA-SEQUENCE:0\n',
635635
// ref includes partialRef, partialRef2
636636
// partialRef
637-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=200@0\n',
637+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=200@0,',
638+
'INDEPENDENT=YES\n',
638639
// partialRef2
639-
'#EXT-X-PART:DURATION=2,URI="partial2.mp4",BYTERANGE=230@200\n',
640+
'#EXT-X-PART:DURATION=2,URI="partial2.mp4",BYTERANGE=230@200,',
641+
'INDEPENDENT=YES\n',
640642
'#EXTINF:4,\n',
641643
'main.mp4\n',
642644
// ref2 includes partialRef3, preloadRef
643645
// partialRef3
644-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
646+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0,',
647+
'INDEPENDENT=YES\n',
645648
// preloadRef
646649
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210,',
647650
'BYTERANGE-LENGTH=210\n',
@@ -668,6 +671,7 @@ describe('HlsParser live', () => {
668671
'test:/partial.mp4', 6, 7.5, /* syncTime= */ null,
669672
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ 419);
670673
preloadRef.markAsPreload();
674+
preloadRef.markAsNonIndependent();
671675

672676
// ref2 is not fully published yet, so it doesn't have a segment uri.
673677
const ref2 = makeReference(
@@ -693,7 +697,8 @@ describe('HlsParser live', () => {
693697
'main.mp4\n',
694698
// ref2 includes partialRef, but not preloadRef
695699
// partialRef
696-
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
700+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0,',
701+
'INDEPENDENT=YES\n',
697702
// preloadRef
698703
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
699704
].join('');

test/hls/hls_parser_unit.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,8 +2559,8 @@ describe('HlsParser', () => {
25592559
'#EXTINF:5,\n',
25602560
'main.mp4\n',
25612561
'#EXT-X-PROGRAM-DATE-TIME:2000-01-01T00:00:15.00Z\n',
2562-
'#EXT-X-PART:DURATION=2.5,URI="main.mp4"\n',
2563-
'#EXT-X-PART:DURATION=2.5,URI="main.mp4"\n',
2562+
'#EXT-X-PART:DURATION=2.5,URI="main.mp4",INDEPENDENT=YES\n',
2563+
'#EXT-X-PART:DURATION=2.5,URI="main.mp4",INDEPENDENT=YES\n',
25642564
'#EXTINF:5,\n',
25652565
'main.mp4\n',
25662566
'#EXT-X-PROGRAM-DATE-TIME:2000-01-01T00:00:20.00Z\n',

0 commit comments

Comments
 (0)