Constructor
new SkipRangeController(playerInterface)
Owns the set of skip ranges -- regions [start, end) whose segments are treated as if they do not exist (never fetched, gap-jumped by the playhead). Player owns the instance so ranges added before load survive until streaming starts; the streaming side decides when each range actually becomes a gap.
Parameters:
| Name | Type | Description |
|---|---|---|
playerInterface |
shaka.media.SkipRangeController.PlayerInterface |
Members
TOLERANCE_SECONDS :number
The tolerance, in seconds, for matching skip-range endpoints against segment
boundaries and for coalescing adjacent ranges. Application-supplied times
(e.g. ad-server times from MediaTailor) miss segment boundaries by fractions
of a second; this absorbs that jitter so a slightly-off boundary still lines
up with the segment grid instead of fetching the whole segment. Shared with
shaka.media.StreamingEngine so both sides agree.
Type:
- number
alignable_ :WeakSet<shaka.media.SkipRangeController.SkipRange>
Type:
playerInterface_ :shaka.media.SkipRangeController.PlayerInterface
Type:
unalignable_ :WeakSet<shaka.media.SkipRangeController.SkipRange>
Type:
Methods
activeRangeAt(time) → {shaka.media.SkipRangeController.SkipRange}
The skip range |time| falls in that is currently *acting* (unbuffered), or
null. Used only by run-ahead math (timeNeededPast): an already-buffered
range must not push the frontier past it, or it stalls at the buffered
edge. The per-segment skip decision instead uses containingActiveRange,
which is buffer-independent -- see there.
Parameters:
| Name | Type | Description |
|---|---|---|
time |
number |
Returns:
add(start, end) → {boolean}
Declares a range [start, end) to be skipped. An empty/reversed interval is
rejected; otherwise the range is always accepted. A new range that
overlaps or touches (within a small tolerance) any existing ranges is
merged with all of them into a single coalesced range -- transitively, so
one add can bridge several existing ranges. The merged set stays disjoint
and sorted by start, so a segment falls in at most one range. The range is
recorded even if it (or the playhead) is currently buffered: the skip is
postponed, acting only once the region can be turned into a real gap (its
span is fully unbuffered) -- the streaming side gates that. Callers apply
any manifest stream-type guard first.
Parameters:
| Name | Type | Description |
|---|---|---|
start |
number | |
end |
number |
Returns:
True if the range was accepted; false only if it was an
empty/reversed interval.
- Type
- boolean
clear()
Drops all skip ranges. Already-buffered holes are left as-is; only ranges
not yet reached are affected (their content then fetches normally).
closestBoundary_(time, segs, boundsOf) → {number}
The segment boundary closest to |time| among |segs|, or null if none is
within tolerance.
Parameters:
| Name | Type | Description |
|---|---|---|
time |
number | |
segs |
shaka.media.SegmentReference | !Array<!shaka.media.SegmentReference> | |
boundsOf |
function(!shaka.media.SegmentReference): !Array<number> | The boundaries of a segment that |time| may snap to. |
Returns:
- Type
- number
containingActiveRange(startTime, endTime) → {shaka.media.SkipRangeController.SkipRange}
The skip range a concrete segment [startTime, endTime) may be carved out
of, or null. Backs the per-segment skip/discard decisions on every stream
and entry point (fetch frontier, append guard, prefetch).
Deliberately buffer-independent: gating on isRegionBuffered is
self-defeating, since the first in-range append flips the range "buffered"
and stops every stream skipping, leaving misaligned partial fills that
gap-jump can't clear (the seek-into-range stall). A range is skippable
only once the reference grid confirms it aligns to segment boundaries on
both ends (markAlignable); until resolved, or if unalignable, this returns
null.
Parameters:
| Name | Type | Description |
|---|---|---|
startTime |
number | |
endTime |
number |
Returns:
forwardRangeAt_(time) → {shaka.media.SkipRangeController.SkipRange}
The range |time| falls in when the skip may apply at all: non-empty set and
forward playback. Shared by activeRangeAt (which then adds the buffered
gate) and containingActiveRange (which does not).
Parameters:
| Name | Type | Description |
|---|---|---|
time |
number |
Returns:
getAll() → {Array<shaka.media.SkipRangeController.SkipRange>}
Returns:
The active skip
ranges.
- Type
- Array<shaka.media.SkipRangeController.SkipRange>
getRangeAt(time) → {shaka.media.SkipRangeController.SkipRange}
The skip range containing |time| (start in [start, end)), or null. Ranges
hold raw request times; comparing each stream's own segment times against
them keeps the decision correct per stream, since audio and video segment
boundaries are not aligned.
Matching is tolerant on both sides of each boundary so a segment time that
misses the raw boundary by float jitter still lines up: a segment starting
within tolerance *below* |region.start| still counts as inside, and one
starting within tolerance of |region.end| is treated as *at* the end (the
first kept segment) rather than inside -- so nothing extra is dropped.
Parameters:
| Name | Type | Description |
|---|---|---|
time |
number |
Returns:
isEmpty() → {boolean}
Returns:
True if there are no skip ranges.
- Type
- boolean
isResolved(region) → {boolean}
Parameters:
| Name | Type | Description |
|---|---|---|
region |
shaka.media.SkipRangeController.SkipRange |
Returns:
Whether the reference grid has resolved this range's
boundary alignment yet (in either alignable_ or unalignable_).
- Type
- boolean
isUnalignable(region) → {boolean}
Parameters:
| Name | Type | Description |
|---|---|---|
region |
shaka.media.SkipRangeController.SkipRange |
Returns:
Whether the range was confirmed not to align to video
segment boundaries (never carved on any stream).
- Type
- boolean
markAlignable_(region, start, end)
Snaps |region|'s endpoints to the aligned boundaries (so merge/split stay
aligned) and marks it skippable.
Parameters:
| Name | Type | Description |
|---|---|---|
region |
shaka.media.SkipRangeController.SkipRange | |
start |
number | |
end |
number |
markUnalignable_(region)
Marks |region| unskippable and warns once (visible by default) that the
app's range could not be honored.
Parameters:
| Name | Type | Description |
|---|---|---|
region |
shaka.media.SkipRangeController.SkipRange |
mayBeSkipped(startTime, endTime) → {boolean}
Whether a segment may still be dropped by a skip range, so prefetch should
defer. True while its containing range is alignable or unresolved (may
yet be carved); false once the range is confirmed unalignable (it will be
kept).
Parameters:
| Name | Type | Description |
|---|---|---|
startTime |
number | |
endTime |
number |
Returns:
- Type
- boolean
remove(start, end)
Subtracts the interval [start, end) from the stored ranges, so its content
is fetched normally again the next time the region is reached. This is
interval subtraction, not an exact-match delete: removing a sub-interval of
a range trims it, and removing from its middle splits it in two. Endpoints
within a small tolerance of a stored range's own boundary snap to it, so a
slightly-off remove doesn't leave a sliver behind (and can fully restore a
range an equally-slightly-off remove would otherwise miss). If streaming
already committed a hole, the playhead still crosses it as an ordinary gap;
re-fetching happens when the region is next reached.
Parameters:
| Name | Type | Description |
|---|---|---|
start |
number | |
end |
number |
resolveAlignment(region, startSegs, endSegs)
Records whether |region| aligns to video segment boundaries on both ends,
given the video segments covering its start and end (from the streaming
side, which owns the indices). It aligns when a segment starts at
region.start AND a segment boundary lands at region.end (the end segment
starts or ends there). Aligned ranges snap to those boundaries and become
skippable; misaligned ranges are never skipped and warn once. Runs once
per range.
A boundary matches an endpoint when it lies within tolerance on either
side; the closest wins, since the window can span more than one boundary.
Callers pass the candidate segments (a lone segment is accepted as
shorthand).
Parameters:
| Name | Type | Description |
|---|---|---|
region |
shaka.media.SkipRangeController.SkipRange | |
startSegs |
shaka.media.SegmentReference | !Array<!shaka.media.SegmentReference> | Segments that may carry a boundary matching region.start. |
endSegs |
shaka.media.SegmentReference | !Array<!shaka.media.SegmentReference> | Segments that may carry a boundary matching region.end. |
timeNeededPast(time) → {number}
Advances |time| past the acting skip range it falls in (else returns it
unchanged), so run-ahead math treats the gap as absent. An inert range is
left in place, or the frontier would stall at the buffered edge.
Parameters:
| Name | Type | Description |
|---|---|---|
time |
number |
Returns:
- Type
- number
Type Definitions
PlayerInterface
Player interface. All members no-op / report a neutral value before load (no streaming engine yet), so ranges added early are simply queued. requestUpdate schedules an immediate streaming update. getPlaybackRate is the current playback rate (negative in reverse). isRegionBuffered reports whether any part of [start, end) is buffered for any content type currently streaming.
Type:
- {requestUpdate: function(): void, getPlaybackRate: function(): number, isRegionBuffered: function(number, number): boolean}
SkipRange
A skip range, as the raw application-supplied request times. Each stream
compares its own segment times against these, so misaligned audio/video
boundaries are handled correctly per stream.
Type:
- {start: number, end: number}