Skip to content

Commit

Permalink
feat(hls): Add support for EXT-X-GAP (shaka-project#4208)
Browse files Browse the repository at this point in the history
Related to 42eecc8
Closes shaka-project#1308
  • Loading branch information
Álvaro Velad Galván committed May 10, 2022
1 parent df23e43 commit 14e61a7
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
12 changes: 11 additions & 1 deletion lib/hls/hls_parser.js
Expand Up @@ -1902,6 +1902,11 @@ shaka.hls.HlsParser = class {
const pAbsoluteUri = shaka.hls.Utils.constructAbsoluteUri(
absoluteMediaPlaylistUri, pUri);

let partialStatus = shaka.media.SegmentReference.Status.AVAILABLE;
if (item.getAttributeValue('GAP') == 'YES') {
partialStatus = shaka.media.SegmentReference.Status.MISSING;
}

const partial = new shaka.media.SegmentReference(
pStartTime,
pEndTime,
Expand All @@ -1911,7 +1916,12 @@ shaka.hls.HlsParser = class {
initSegmentReference,
/* timestampOffset= */ 0, // This value is ignored in sequence mode.
/* appendWindowStart= */ 0,
/* appendWindowEnd= */ Infinity);
/* appendWindowEnd= */ Infinity,
/* partialReferences= */ [],
/* tilesLayout= */ '',
/* tileDuration= */ null,
/* syncTime= */ null,
partialStatus);
partialSegmentRefs.push(partial);
} // for-loop of hlsSegment.partialSegments
} else {
Expand Down
7 changes: 7 additions & 0 deletions lib/media/streaming_engine.js
Expand Up @@ -1215,6 +1215,13 @@ shaka.media.StreamingEngine = class {
mediaState.performingUpdate = true;

try {
if (reference.getStatus() ==
shaka.media.SegmentReference.Status.MISSING) {
throw new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.NETWORK,
shaka.util.Error.Code.SEGMENT_MISSING);
}
await this.initSourceBuffer_(mediaState, reference);
this.destroyer_.ensureNotDestroyed();
if (this.fatalError_) {
Expand Down
23 changes: 18 additions & 5 deletions lib/player.js
Expand Up @@ -5521,17 +5521,30 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
* @private
*/
tryToRecoverFromError_(error) {
if (error.code !== shaka.util.Error.Code.HTTP_ERROR ||
error.category !== shaka.util.Error.Category.NETWORK) {
if ((error.code != shaka.util.Error.Code.HTTP_ERROR &&
error.code != shaka.util.Error.Code.SEGMENT_MISSING) ||
error.category != shaka.util.Error.Category.NETWORK) {
return false;
}

const maxDisabledTime = this.config_.streaming.maxDisabledTime;
let maxDisabledTime = this.config_.streaming.maxDisabledTime;
if (maxDisabledTime == 0) {
return false;
if (error.code == shaka.util.Error.Code.SEGMENT_MISSING) {
// Spec: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-6.3.3
// The client SHOULD NOT attempt to load Media Segments that have been
// marked with an EXT-X-GAP tag, or to load Partial Segments with a
// GAP=YES attribute. Instead, clients are encouraged to look for
// another Variant Stream of the same Rendition which does not have the
// same gap, and play that instead.
maxDisabledTime = 1;
} else {
return false;
}
}

shaka.log.debug('Recoverable NETWORK HTTP_ERROR, trying to recover...');
if (error.code == shaka.util.Error.Code.HTTP_ERROR) {
shaka.log.debug('Recoverable NETWORK HTTP_ERROR, trying to recover...');
}

// Obtain the active variant and disable it from manifest variants
const activeVariantTrack = this.getVariantTracks().find((t) => t.active);
Expand Down
6 changes: 6 additions & 0 deletions lib/util/error.js
Expand Up @@ -267,6 +267,12 @@ shaka.util.Error.Code = {
*/
'ATTEMPTS_EXHAUSTED': 1010,

/**
* The segment is missing.
* <br> error.data[0] is the URI.
*/
'SEGMENT_MISSING': 1011,


/** The text parser failed to parse a text stream due to an invalid header. */
'INVALID_TEXT_HEADER': 2000,
Expand Down

0 comments on commit 14e61a7

Please sign in to comment.