Skip to content

Commit

Permalink
fix: Fix temporarily disable streams on network error (shaka-project#…
Browse files Browse the repository at this point in the history
  • Loading branch information
zangue committed Apr 18, 2023
1 parent 2ae9095 commit fdc5cb1
Show file tree
Hide file tree
Showing 10 changed files with 770 additions and 335 deletions.
45 changes: 41 additions & 4 deletions lib/media/streaming_engine.js
Expand Up @@ -981,7 +981,7 @@ shaka.media.StreamingEngine = class {
mediaState.hasError = false;
}
} catch (error) {
await this.handleStreamingError_(error);
await this.handleStreamingError_(mediaState, error);
return;
}

Expand Down Expand Up @@ -1479,7 +1479,7 @@ shaka.media.StreamingEngine = class {
mediaState.hasError = true;

error.severity = shaka.util.Error.Severity.CRITICAL;
await this.handleStreamingError_(error);
await this.handleStreamingError_(mediaState, error);
}
}
}
Expand Down Expand Up @@ -2283,17 +2283,31 @@ shaka.media.StreamingEngine = class {
* Handle streaming errors by delaying, then notifying the application by
* error callback and by streaming failure callback.
*
* @param {shaka.media.StreamingEngine.MediaState_} mediaState
* @param {!shaka.util.Error} error
* @return {!Promise}
* @private
*/
async handleStreamingError_(error) {
async handleStreamingError_(mediaState, error) {
// If we invoke the callback right away, the application could trigger a
// rapid retry cycle that could be very unkind to the server. Instead,
// use the backoff system to delay and backoff the error handling.
await this.failureCallbackBackoff_.attempt();
this.destroyer_.ensureNotDestroyed();

const maxDisabledTime = this.getDisabledTime_(error);
// Try to recover from network errors
if (error.category === shaka.util.Error.Category.NETWORK &&
maxDisabledTime > 0) {
error.handled = this.playerInterface_.disableStream(
mediaState.stream, maxDisabledTime);

// Decrease the error severity to recoverable
if (error.handled) {
error.severity = shaka.util.Error.Severity.RECOVERABLE;
}
}

// First fire an error event.
this.playerInterface_.onError(error);

Expand All @@ -2304,6 +2318,25 @@ shaka.media.StreamingEngine = class {
}
}

/**
* @param {!shaka.util.Error} error
* @private
*/
getDisabledTime_(error) {
if (this.config_.maxDisabledTime === 0 &&
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.
return 1;
}

return this.config_.maxDisabledTime;
}

/**
* @param {shaka.media.StreamingEngine.MediaState_} mediaState
* @return {string} A log prefix of the form ($CONTENT_TYPE:$STREAM_ID), e.g.,
Expand All @@ -2330,7 +2363,8 @@ shaka.media.StreamingEngine = class {
* onInitSegmentAppended: function(!number,!shaka.media.InitSegmentReference),
* beforeAppendSegment: function(
* shaka.util.ManifestParserUtils.ContentType,!BufferSource):Promise,
* onMetadata: !function(!Array.<shaka.extern.ID3Metadata>, number, ?number)
* onMetadata: !function(!Array.<shaka.extern.ID3Metadata>, number, ?number),
* disableStream: function(!shaka.extern.Stream, number):boolean
* }}
*
* @property {function():number} getPresentationTime
Expand Down Expand Up @@ -2363,6 +2397,9 @@ shaka.media.StreamingEngine = class {
* @property
* {!function(!Array.<shaka.extern.ID3Metadata>, number, ?number)} onMetadata
* Called when an ID3 is found in a EMSG.
* @property {function(!shaka.extern.Stream, number):boolean} disableStream
* Called to temporarily disable a stream i.e. disabling all variant
* containing said stream.
*/
shaka.media.StreamingEngine.PlayerInterface;

Expand Down

0 comments on commit fdc5cb1

Please sign in to comment.