Skip to content

Commit 2a063ff

Browse files
authored
chore: Move isBufferedToEnd to Playhead (#8603)
1 parent 3c32f7a commit 2a063ff

File tree

2 files changed

+51
-90
lines changed

2 files changed

+51
-90
lines changed

lib/media/playhead.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ shaka.media.Playhead = class {
7575
* Notify the playhead that the buffered ranges have changed.
7676
*/
7777
notifyOfBufferingChange() {}
78+
79+
/**
80+
* Check if the player has buffered enough content to make it to the end of
81+
* the presentation.
82+
* @return {boolean}
83+
*/
84+
isBufferedToEnd() {}
7885
};
7986

8087

@@ -205,6 +212,25 @@ shaka.media.SrcEqualsPlayhead = class {
205212
/** @override */
206213
notifyOfBufferingChange() {}
207214

215+
/** @override */
216+
isBufferedToEnd() {
217+
goog.asserts.assert(
218+
this.mediaElement_,
219+
'We need a video element to get buffering information');
220+
221+
// If we have buffered to the duration of the content, it means we will have
222+
// enough content to buffer to the end of the presentation.
223+
const bufferEnd =
224+
shaka.media.TimeRangesUtils.bufferEnd(this.mediaElement_.buffered);
225+
226+
// Because Safari's native HLS reports slightly inaccurate values for
227+
// bufferEnd here, we use a fudge factor. Without this, we can end up in a
228+
// buffering state at the end of the stream. See issue #2117.
229+
const fudge = 1; // 1000 ms
230+
return bufferEnd != null &&
231+
bufferEnd >= this.mediaElement_.duration - fudge;
232+
}
233+
208234
/**
209235
* @return {?number} program start time in seconds.
210236
* @private
@@ -416,6 +442,30 @@ shaka.media.MediaSourcePlayhead = class {
416442
this.gapController_.onSegmentAppended();
417443
}
418444

445+
/** @override */
446+
isBufferedToEnd() {
447+
goog.asserts.assert(
448+
this.mediaElement_,
449+
'We need a video element to get buffering information');
450+
goog.asserts.assert(
451+
this.timeline_,
452+
'We need a timeline to get buffering information');
453+
454+
// Live streams are "buffered to the end" when they have buffered to the
455+
// live edge or beyond (into the region covered by the presentation delay).
456+
if (this.timeline_.isLive()) {
457+
const liveEdge = this.timeline_.getSegmentAvailabilityEnd();
458+
const bufferEnd =
459+
shaka.media.TimeRangesUtils.bufferEnd(this.mediaElement_.buffered);
460+
461+
if (bufferEnd != null && bufferEnd >= liveEdge) {
462+
return true;
463+
}
464+
}
465+
466+
return false;
467+
}
468+
419469
/**
420470
* Called on a recurring timer to keep the playhead from falling outside the
421471
* availability window.

lib/player.js

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,19 +4036,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
40364036
this.bufferObserver_,
40374037
'Need a buffering observer to update');
40384038

4039-
let bufferedToEnd;
4040-
switch (this.loadMode_) {
4041-
case shaka.Player.LoadMode.SRC_EQUALS:
4042-
bufferedToEnd = this.isBufferedToEndSrc_();
4043-
break;
4044-
case shaka.Player.LoadMode.MEDIA_SOURCE:
4045-
bufferedToEnd = this.isBufferedToEndMS_();
4046-
break;
4047-
default:
4048-
bufferedToEnd = false;
4049-
break;
4050-
}
4051-
4039+
const bufferedToEnd = this.isEnded() || this.playhead_.isBufferedToEnd();
40524040
const bufferLead = shaka.media.TimeRangesUtils.bufferedAheadOf(
40534041
this.video_.buffered,
40544042
this.video_.currentTime);
@@ -9119,83 +9107,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
91199107
return pairings;
91209108
}
91219109

9122-
/**
9123-
* Assuming the player is playing content with media source, check if the
9124-
* player has buffered enough content to make it to the end of the
9125-
* presentation.
9126-
*
9127-
* @return {boolean}
9128-
* @private
9129-
*/
9130-
isBufferedToEndMS_() {
9131-
goog.asserts.assert(
9132-
this.video_,
9133-
'We need a video element to get buffering information');
9134-
goog.asserts.assert(
9135-
this.mediaSourceEngine_,
9136-
'We need a media source engine to get buffering information');
9137-
goog.asserts.assert(
9138-
this.manifest_,
9139-
'We need a manifest to get buffering information');
9140-
9141-
// This is a strong guarantee that we are buffered to the end, because it
9142-
// means the playhead is already at that end.
9143-
if (this.isEnded()) {
9144-
return true;
9145-
}
9146-
9147-
// This means that MediaSource has buffered the final segment in all
9148-
// SourceBuffers and is no longer accepting additional segments.
9149-
if (this.mediaSourceEngine_.ended()) {
9150-
return true;
9151-
}
9152-
9153-
// Live streams are "buffered to the end" when they have buffered to the
9154-
// live edge or beyond (into the region covered by the presentation delay).
9155-
if (this.manifest_.presentationTimeline.isLive()) {
9156-
const liveEdge =
9157-
this.manifest_.presentationTimeline.getSegmentAvailabilityEnd();
9158-
const bufferEnd =
9159-
shaka.media.TimeRangesUtils.bufferEnd(this.video_.buffered);
9160-
9161-
if (bufferEnd != null && bufferEnd >= liveEdge) {
9162-
return true;
9163-
}
9164-
}
9165-
9166-
return false;
9167-
}
9168-
9169-
/**
9170-
* Assuming the player is playing content with src=, check if the player has
9171-
* buffered enough content to make it to the end of the presentation.
9172-
*
9173-
* @return {boolean}
9174-
* @private
9175-
*/
9176-
isBufferedToEndSrc_() {
9177-
goog.asserts.assert(
9178-
this.video_,
9179-
'We need a video element to get buffering information');
9180-
9181-
// This is a strong guarantee that we are buffered to the end, because it
9182-
// means the playhead is already at that end.
9183-
if (this.isEnded()) {
9184-
return true;
9185-
}
9186-
9187-
// If we have buffered to the duration of the content, it means we will have
9188-
// enough content to buffer to the end of the presentation.
9189-
const bufferEnd =
9190-
shaka.media.TimeRangesUtils.bufferEnd(this.video_.buffered);
9191-
9192-
// Because Safari's native HLS reports slightly inaccurate values for
9193-
// bufferEnd here, we use a fudge factor. Without this, we can end up in a
9194-
// buffering state at the end of the stream. See issue #2117.
9195-
const fudge = 1; // 1000 ms
9196-
return bufferEnd != null && bufferEnd >= this.video_.duration - fudge;
9197-
}
9198-
91999110
/**
92009111
* Create an error for when we purposely interrupt a load operation.
92019112
*

0 commit comments

Comments
 (0)