-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HLS Interstitials Support #6591
Conversation
e88a6a9
to
8490088
Compare
…outside the primary program time range Addresses comment #6591 (comment) (cherry picked from commit ebe6c08)
Thanks for the repro. I've pushed a fix to the scheduler that corrects an assumption that the previous event before the last primary segment must always be the last interstitial event. ef72aa0 // last primary segment
const timelineStart = primaryPosition;
const integratedStart = integratedTime;
const segmentDuration = primaryDuration - primaryPosition;
integratedTime += segmentDuration;
const playoutStart = playoutDuration;
playoutDuration += segmentDuration;
schedule.push({
- previousEvent: interstitialEvents[interstitialEvents.length - 1],
+ previousEvent: schedule[schedule.length - 1].event || null, That caused a lookup here ( hls.js/src/controller/interstitials-controller.ts Line 1530 in 8490088
|
Checked it out and your change also fixed a bug where subtitle selection would only fetch the text playlist but not the fragments. See (
_loadFragForPlayback was never called. Although I was running the same stream with the interstitial offset exceeding the main timeline duration so I'm not sure how representable the bug was in general. Nonetheless, it's good to know.
Minor: Thought 1: let's say there's an interstitial at 10, Thought 2: |
…grated duration (cherry picked from commit 161bf44d0186a263bc82299fc09e52b913f2d2f8)
…itialsManager.skip()` (cherry picked from commit 928064edb0d802d1e6513bd509e65ef5c584f2e9)
(cherry picked from commit ffa6612c848033ea913c020e0e5355db710ff431)
(cherry picked from commit 1cc169ce64b26aff31929a510b8ff157558c9bb5)
(cherry picked from commit 34ab0ed5016a3c18e330ab136fd731c3d5c95fcc)
…nterstitials Make criteria for "append in place" more flexible (does not require snapping and allows for resume offset matching duration) (cherry picked from commit 856dfb09aeadc99c5f9788ca5e55310fd8fa4d3d)
(cherry picked from commit 446ef3cee40ab0f7337fe12c905905349f24d8f7)
…ce" mode Improve Interstitial logging and log media transfer and "appendInPlace" details Fix media transfer for Interstitials in "appendInPlace" mode, with abutting timing, and snap-in (cherry picked from commit 9911bc4b8f9d59a4843affd7b889b11aab2c0117)
Fix asset player startPosition with append-in-place timelineOffset Fix issues with item and asset lookup using Array.indexOf when object refererenes are replaced by Live updates Fix cue removal by asset players (cherry picked from commit eb44d8699e4fa48becdba377aa4a82ece6d1f6f3)
(cherry picked from commit c61f5e3f6c480212ea79ed68a511208fe8674b99)
(cherry picked from commit 1b843d5517a658cdbd20bbb5eb02a64bb0839291)
Add comments describing each field in `InterstitialsManager` API markdown (cherry picked from commit bcb2db84d1ffba18befd658b284695fb0a69f7d4)
…outside the primary program time range Addresses comment #6591 (comment) (cherry picked from commit ebe6c08)
df287da
to
52cc78e
Compare
This PR will...
Add support for HLS Interstitials parsing, playback, and events.
Design Details
The
InterstitialsController
handles HLS and media input and events for the primary HLS asset. It passes date range data to the scheduler to produce an array of Interstitial events and an array of event and primary items called the schedule.InterstitialsController
has:InterstitialsSchedule
which produces Interstitial events and a schedule of items on level update. TheInterstitialsSchedule
hasInterstitialEvent
objects. Each event contains properties and getters for finding its place on the playback timeline as well as an array of interstitial assetsHLSAssetPlayer
instances call the player queue. EachHLSAssetPlayer
wraps a child instance ofHls
used to preload and stream Interstitial assets.InterstitialsController
adds a loader to the correspondingInterstitialEvent
while loading. The loader is removed and replaced by the asset list response once the request is complete.API Enhancements
Configuration options
interstitialsController
. Setting this to null turns off Interstitial parsing and playback.enableInterstitialPlayback
tofalse
(allowing for custom playout and ad managers)interstitialAssetListLoadPolicy
defines the loading policy of X-ASSET-LIST JSONprimarySessionId
identifies the parent player session that spawned the asset player (read fromhls.sessionId
)assetPlayerId
is used to identify logs from asset playerstimelineOffset
is used to offset MSE appends of Interstitial content (not all Interstitial assets are appended inline at offsets; most require a MediaSource reset)New top-level API on
Hls
instancesbufferedToEnd
getter returns a boolean indicating if EOS has been appended (media is buffered from currentTime to end of stream)bufferingEnabled
getter returns a boolean indicating whether fragment loading has been toggled with pauseBuffering() and resumeBuffering()interstitialsManager
getter returns anInterstitialsManager
(or null). TheInterstitialsManager
is an interface that provides access to Interstitial program and timeline data as well as methods for seeking across items and skipping Interstitial events.latestLevelDetails
getter returns theLevelDetails
of the most up-to-date HLS variant Playlist datasessionId
getter returns the session UUID assigned to theHls
instancesessionId
value is used when assigning a _HLS_primary_id query parameter to interstitial requestsstartLoad()
now includes a second optional argument to skip seeking on start (otherwise, HLS.js seeks following to the first optionalstartPosition
argument on append)hasEnoughToStart
getter returns whether enough is buffered to seek to start position (fix: media buffer is not empty but video element buffer is empty #6571)startPosition
getter returns the resolvedstartPosition
that playback will begin at once media is appendedtransferMedia()
method detaches and returns MediaSource and SourceBuffers non-destructivelyurl
getter returns the URL resolved from loadSource(url)Updated top-level API on
Hls
instancesattachMedia()
enhancements for transferring MediaSource and SourceBuffers betweenHls
instancesrecoverMediaError()
now seeks to the value ofcurrentTime
before the source reset is performed (BaseStreamController always honor config.startPosition when attaching(recovering) #6297)New Events for Interstitials
ASSET_LIST_LOADING
when a request is made for an X-ASSET-LIST JSON objectASSET_LIST_LOADED
when a response is received for an X-ASSET-LIST JSON objectINTERSTITIALS_UPDATED
when Interstitials are added, removed, or the schedule is updated following a variant playlist update or updated asset durations from X-ASSET-LIST JSON or asset playlist and media parsingINTERSTITIALS_BUFFERED_TO_BOUNDARY
when the forward buffer reaches the boundary of the following schedule item (Interstitial event or primary segment)INTERSTITIAL_ASSET_PLAYER_CREATED
when an asset player instance is created to stream an Interstitial asset (will always be before attaching media to the asset player)INTERSTITIAL_STARTED
when streaming of an Interstitial event containing one or more assets has begun (may occur before X-ASSET-LIST JSON is loaded or playback has started)INTERSTITIAL_ENDED
when streaming of an Interstitial event containing one or more assets has ended - before resuming primary or starting the next eventINTERSTITIAL_ASSET_STARTED
when streaming of an Interstitial asset has begun (following the beginning of the event or the end of the last asset)INTERSTITIAL_ASSET_ENDED
when streaming of an Interstitial asset has ended (before the next asset or the event ending)INTERSTITIAL_ASSET_ERROR
when an error occurs starting or streaming an Interstitial asset (this can include non-fatal errors such as stalling and errors that will end streaming of the asset, resulting in the schedule advancing to the next asset or fallback to primary)INTERSTITIALS_PRIMARY_RESUMED
when playback of primary content has begun or resumed from an Interstitial eventBUFFERED_TO_END
when the last audio and video segments in the playlist have been appended (EOS signaled on all SourceBuffers)AUDIO_TRACK_UPDATED
similar to LEVEL_UPDATED fired for any update to audio group playlistsSUBTITLE_TRACK_UPDATED
similar to LEVEL_UPDATED fired for any update to subtitle group playlistsUpdated Events
MEDIA_ATTACHING
,MEDIA_ATTACHED
,MEDIA_DETACHING
, andMEDIA_DETACHED
include additional information (depending on whether media is being transferred)New Errors for Interstitials
NETWORK_ERROR
ASSET_LIST_LOAD_ERROR
network error loading asset listASSET_LIST_LOAD_TIMEOUT
network timeout error loading asset listASSET_LIST_PARSING_ERROR
asset list was not valid JSON or missing required dataINTERSTITIAL_ASSET_ITEM_ERROR
an issue interrupted or prevented asset playback. This will result in skipping the remainder of the asset or falling back to primary content. The eventerror
will contain more details. This type of error differs from theINTERSTITIAL_ASSET_ERROR
events forwarded from asset player errors.Build Constants
__USE_INTERSTITALS__
build const/directive.Known Issues
Should address before release (in order of priority):
video element requires the autoplay or play() to be called on canplaythough after MediaSource reset from detach/attach for most schedule transitions (whenresolved with e1e515a (thanks to @matvp91 for calling this out)appendInPlace
is false).resolved with 5842cc2InterstitialsManager
primary
,playout
andintegrated
durations are non-finite for Live streams. These should be finite for easier mapping of controls.resolved with 0021cfd e84bc30 2c3c372hls.interstitialsManager.skip()
does not skip Interstitial events that do not reset MediaSource (whereInterstitialEvent
appendInPlace
is true)No plan to address before release:
InterstitialEvent
appendInPlace
is true). Note that this only applies to Interstitials that overlap and replace primary segments completely which is not the case for most Interstitials. If you have content where this is a concern, please file an issue.seekTo
that restrict schedule advancement.appendInPlace
mode and allow for single element and timeline playback of breaks independent of the primary player,Asset lists are not being loaded when(decided this is not something we would address as asset-lists should only be loaded when there is clear intent to play the interstitial assets)enableInterstitialPlayback
is set to false. They should be loaded. The schedule needs to reflect the path taken when primary playback is chosen over interstitial playback.Resolves issues:
Checklist