Class: shaka.msf.MSFParser

Members

EVENT_TIMELINE_PACKAGING_ :string

The catalog `packaging` value of an event timeline track.
Type:
  • string
Source:

INDEX_RETENTION_SEC_ :number

How many seconds of SegmentReferences to keep in the index behind the newest one. Must exceed how far StreamingEngine can lag the live edge, because it walks the index in order and cannot skip to content whose predecessor has been evicted. Where one reference is one frame this is a large number of references but a small amount of memory.
Type:
  • number
Source:

LIVE_EDGE_TOLERANCE_SEC_ :number

How close to the live edge a seek target has to land to be treated as a return to the live edge rather than as a seek into the DVR window, in seconds. Seeking to "live" lands on the seek range end, which is the newest segment end time; by the time the seek is handled the edge may have moved on, so an exact comparison would read the seek as one into the past and anchor the subscription just behind the edge instead of following it.
Type:
  • number
Source:

MEDIA_TIMELINE_PACKAGING_ :string

The catalog `packaging` value of a media timeline track.
Type:
  • string
Source:

MIN_AVAILABILITY_WINDOW_SEC_ :number

Floor for the live segment-availability window, in seconds. Deriving the window from one object's duration gives tens of milliseconds on a frame-per-object packaging. That is too narrow on two counts: the playhead, which trails the live edge, falls outside its own seek range and is re-seeked continuously; and the trailing track of a pair published a few hundred milliseconds apart is never inside the window at all, so StreamingEngine reports "cannot find segment" for it forever. Bounded from above as well. This window IS the seek range, so it is what the player offers the user as DVR, and it is how far the playhead may drift behind the live edge before being pulled back to it. Neither is wanted on a transport chosen for low latency, and a window of five seconds or more also makes the UI show a seek bar (shaka.ui.SeekBar's minimum seek window), which would advertise DVR on a stream that has none. The quantity it has to cover is the lag between the newest reference and the newest sample actually appended, since that is where the playhead can be. Measured on a live LOC stream, that lag ran 2.0-4.7 s and the playhead sat 1.0-3.8 s behind the live edge; a window of 1.5 s put it outside the range again and it thrashed.
Type:
  • number
Source:

activeStreams_ :Map<string, shaka.msf.MSFParser.StreamState>

The streams that are currently subscribed, by track key. A seek has to find them to re-point their subscriptions, which is why the state that used to live in createSegmentIndex's closure is out here.
Type:
Source:

audioStreams_ :Array<!shaka.extern.Stream>

Type:
Source:

bandwidthSamples_ :Map<string, {bytes: number, readMs: number, group: bigint}>

The in-progress ABR bandwidth sample for each track, keyed by track key. Tracks are accumulated separately because each has its own group sequence.
Type:
  • Map<string, {bytes: number, readMs: number, group: bigint}>
Source:

catalogPromise_ :Promise.PromiseWithResolvers

Type:
  • Promise.PromiseWithResolvers
Source:

catalogReceived_ :boolean

Whether the catalog the presentation is built from has been received. Only the first complete catalog is used; what the catalog track says after it is not applied yet.
Type:
  • boolean
Source:

eventTimelines_ :Array<!shaka.msf.EventTimeline>

The event timelines of the event timeline tracks subscribed to.
Type:
Source:

globalId_ :number

Type:
  • number
Source:

isFirstVideoSegment_ :boolean

Type:
  • boolean
Source:

mediaTimelineDepends_ :Map<string, !Array<string>>

The tracks each media timeline track describes, by the timeline track's name. An event timeline names the timeline track in its `depends`, while the timelines themselves are kept by the media track they describe, so this is what gets from one to the other.
Type:
  • Map<string, !Array<string>>
Source:

mediaTimelines_ :Map<string, !shaka.msf.MediaTimeline>

The media timeline of each track that has one, by catalog track name. A track gets one from a media timeline track that names it in `depends`, from its own `template` field, or from both, in which case the one instance holds both and prefers the explicit records.
Type:
Source:

pendingSubscriptions_ :Map<string, {cancelled: boolean}>

Subscriptions whose SUBSCRIBE_OK has not arrived yet, by track key. A subscription can only be withdrawn once it has an alias, so a track closed before then has to leave a note for the in-flight subscribe to find; without it the subscription is orphaned and the publisher keeps sending objects nobody listens to for the rest of the session.
Type:
  • Map<string, {cancelled: boolean}>
Source:

publishNamespaces_ :Array<Array<string>>

Type:
  • Array<Array<string>>
Source:

receivedFirstSegment_ :Set<shaka.util.ManifestParserUtils.ContentType>

Tracks whether the first segment has been received for each content type. Used to delay locking the presentation timeline until all expected stream types have started producing data.
Type:
Source:

textStreams_ :Array<!shaka.extern.Stream>

Type:
Source:

unregisterCatalogCallback_ :?function()

Type:
  • ?function()
Source:

unregisterPublishNamespaceCallback_ :?function()

Type:
  • ?function()
Source:

unregisterTracksCallback_ :Map<string, function()>

Type:
  • Map<string, function()>
Source:

variants_ :Array<!shaka.extern.Variant>

Type:
Source:

videoStreams_ :Array<!shaka.extern.Stream>

Type:
Source:

Methods

isIndexed_(segmentIndexnon-null, time) → {boolean}

Whether a segment index holds a reference covering the given time. SegmentIndex.find() answers a position, and for a time before everything it holds it answers the first position rather than nothing, so its result says where to look, not whether the time is there. Seeking behind the index is exactly the case that distinction decides.
Parameters:
Name Type Description
segmentIndex shaka.media.SegmentIndex
time number
Source:
Returns:
Type
boolean

namespaceTuple(namespace, sessionNamespace) → {Array<string>}

Converts a catalog track's `namespace` string into the Track Namespace tuple that goes on the wire. A Track Namespace is an ordered set of fields (MoQT Section 2.4.1), but the catalog carries it as one string whose fields are joined with "/", as in the MSF example "conference.example.com/conference123/alice". Sending that string as a single field never matches a namespace announced as several. When the string is the session's own namespace written out, the session's tuple is used as is, so a publisher whose single field contains a "/" keeps working. Otherwise the string is split on "/", dropping empty fields because a field must carry at least one byte.
Parameters:
Name Type Description
namespace string
sessionNamespace Array<string>
Source:
Returns:
Type
Array<string>

addSegment_(stream, type, segmentnon-null, initSegmentReference)

Adds a segment produced by a packaging's segmenter to a stream's segment index and advances the presentation timeline to cover it.
Parameters:
Name Type Description
stream shaka.extern.Stream
type shaka.util.ManifestParserUtils.ContentType
segment shaka.extern.MsfSegment
initSegmentReference shaka.media.InitSegmentReference
Source:

banLocation(uri)

Tells the parser that a location should be banned. This is called on retry.
Parameters:
Name Type Description
uri string
Implements:
Source:

configure(config, isPreloadFnopt)

Called by the Player to provide an updated configuration any time the configuration changes. Will be called at least once before start().
Parameters:
Name Type Attributes Description
config shaka.extern.ManifestConfiguration
isPreloadFn function <optional>
Implements:
Source:

createCatalogCallback_(storenon-null) → {shaka.msf.Utils.ObjectCallback}

Builds the callback for the catalog track's Objects, which rebuilds the catalog from them and resolves the catalog promise with the first complete one.
Parameters:
Name Type Description
store shaka.msf.CatalogStore
Source:
Returns:
Type
shaka.msf.Utils.ObjectCallback

createDecodingCallback_(handler, onError) → {shaka.msf.Utils.ObjectCallback}

Wraps a handler for the Objects of a JSON track -- the catalog or a media timeline -- so that each payload reaches it with its MSF_COMPRESSION undone, and in the order the Objects arrived. Order matters: the first Object of a Group is a complete document and the ones after it are updates to it, and a compressed complete document takes longer to decode than the uncompressed update that follows it. An uncompressed payload with nothing waiting ahead of it is handled in the same turn it arrives. Objects with no payload carry an Object status (e.g. an end-of-group marker), not a document, and are skipped.
Parameters:
Name Type Description
handler function(!shaka.msf.Utils.MOQObject, !Uint8Array)
onError function(*) Receives the reason a payload could not be decoded, which is a shaka.util.Error when its compression is not supported. The Object is dropped.
Source:
Returns:
Type
shaka.msf.Utils.ObjectCallback

createVariants_()

Source:

decodePayload_(objnon-null) → {Uint8Array|!Promise<!Uint8Array>}

An Object's payload with its MSF_COMPRESSION undone.
Parameters:
Name Type Description
obj shaka.msf.Utils.MOQObject
Source:
Returns:
Type
Uint8Array | !Promise<!Uint8Array>

getContentProtections_(catalog) → {Map<string, !shaka.extern.DrmInfo>}

Parameters:
Name Type Description
catalog msfCatalog.Catalog
Source:
Returns:
Type
Map<string, !shaka.extern.DrmInfo>

getEventRecordHandler_(eventType) → {?function(shaka.msf.EventTimeline.Record, number)}

What consumes the records of an event timeline of the given type, or null when nothing here does. What a record's `data` means is defined by the type, so this is the one place that knows about any of them.
Parameters:
Name Type Description
eventType string
Source:
Returns:
Type
?function(shaka.msf.EventTimeline.Record, number)

getEventRecordTime_(record, dependsnon-null) → {number}

Where an event timeline record falls on the presentation timeline, in seconds, or null when it cannot be placed yet. A media time is a presentation time already (MSF 7.1.1). A Location or a wallclock time has to go through the media timeline of a track the record's track depends on.
Parameters:
Name Type Description
record shaka.msf.EventTimeline.Record
depends Array<string> The event timeline track's `depends`.
Source:
Returns:
Type
number

getMediaTimelinesFor_(dependsnon-null) → {Array<!shaka.msf.MediaTimeline>}

The media timelines a track that depends on the given tracks can use. `depends` names either media timeline tracks, as in the MSF catalog examples, whose timelines are kept by the media tracks they in turn depend on, or media tracks that carry a template. MSF only requires `depends` of an event timeline whose records refer to a media timeline, so an empty one falls back to every timeline the presentation has, in catalog order.
Parameters:
Name Type Description
depends Array<string>
Source:
Returns:
Type
Array<!shaka.msf.MediaTimeline>

getOrCreateTimeline_(trackName) → {shaka.msf.MediaTimeline}

Parameters:
Name Type Description
trackName string
Source:
Returns:
Type
shaka.msf.MediaTimeline

getTimelineWindowStart_() → {number}

The earliest presentation time the player can seek to and actually be served, or null when there is no such point and the window should stay at the live edge. Every subscribed track has to be able to reach it, so this is the latest of their starts and is null as soon as one of them has no timeline: a seek range is a promise that all of the media is there, and half of it is a stall rather than a seek.
Source:
Returns:
Type
number

isPreloadFn_()

Source:

listenForAnnouncements_()

Listen for announcements from the server
Source:

onExpirationUpdated(sessionId, expiration)

Tells the parser that the expiration time of an EME session has changed. Implementing this is optional.
Parameters:
Name Type Description
sessionId string
expiration number
Implements:
Source:

onInitialVariantChosen(variant)

Tells the parser that the initial variant has been chosen.
Parameters:
Name Type Description
variant shaka.extern.Variant
Implements:
Source:

onScte35Record_(eventType, record, time)

Reports a record of an SCTE-35 event timeline to the player (draft-wilaw-moq-scte35-event-timeline).
Parameters:
Name Type Description
eventType string
record shaka.msf.EventTimeline.Record
time number
Source:

onSeeking_()

Re-points the subscriptions after a seek to content that has been published but not received. A MoQT subscription is a position in a track, not a URL to fetch, so this is what a seek costs here: the subscription is withdrawn and asked for again from the Location the media timeline gives for the target, and the segment index starts over from there. Seeking within what has already arrived costs nothing and is left alone.
Source:

processCatalog_(catalog) → {Promise}

Parameters:
Name Type Description
catalog msfCatalog.Catalog
Source:
Returns:
Type
Promise

processEventTimelineTrack_(track)

Subscribes to an event timeline track whose `eventType` this player consumes, and hands each of its records to the consumer once it can be placed on the presentation timeline.
Parameters:
Name Type Description
track msfCatalog.Track
Source:

processMediaTimelineTrack_(track)

Subscribes to a media timeline track and feeds what it publishes to the timelines of the tracks it describes.
Parameters:
Name Type Description
track msfCatalog.Track
Source:

processTrack_(track, contentProtectionsnon-null, initDataListnon-null)

Parameters:
Name Type Description
track msfCatalog.Track
contentProtections Map<string, !shaka.extern.DrmInfo>
initDataList Map<string, string>
Source:

recordBandwidthSample_(trackKey, location, byteLength, readMs)

Feed the ABR bandwidth estimator. MoQ delivers media as many small per-object (often per-frame) chunks, which are individually too small for the bandwidth estimator to draw a useful throughput sample from. A group is the natural aggregation unit, so accumulate a group's objects and report one sample once the group is complete, which we detect by the object's group changing. The time reported is the sum of the per-object active read durations, not wall clock. A push stream delivers at (roughly) the encoded rate, so wall-clock timing would only ever measure the current variant's bitrate and ABR could never learn there is spare capacity. When the link has headroom the objects sit ready in the transport buffer and read almost instantly, so the active read time reflects the true link speed and lets ABR climb to a variant the connection can actually sustain.
Parameters:
Name Type Description
trackKey string
location shaka.msf.Utils.Location
byteLength number
readMs number Active time spent reading this object from the stream.
Source:

resubscribe_(state, startLocationnullable)

Starts a subscription that nothing waits on, reporting its failure to the player instead of leaving it to reject unheard.
Parameters:
Name Type Attributes Description
state shaka.msf.MSFParser.StreamState
startLocation shaka.msf.Utils.Location <nullable>
Source:

setMediaElement(mediaElement)

Set media element.
Parameters:
Name Type Description
mediaElement HTMLMediaElement
Implements:
Source:

start(uri, playerInterface) → {Promise<shaka.extern.Manifest>}

Initialize and start the parser. When |start| resolves, it should return the initial version of the manifest. |start| will only be called once. If |stop| is called while |start| is pending, |start| should reject.
Parameters:
Name Type Description
uri string The URI of the manifest.
playerInterface shaka.extern.ManifestParser.PlayerInterface The player interface contains the callbacks and members that the parser can use to communicate with the player and outside world.
Implements:
Source:
Returns:
Type
Promise<shaka.extern.Manifest>

startSubscription_(state, startLocationnullable) → {Promise}

Subscribes a stream's track and turns the Objects it delivers into segments, from the live edge or from a given Location.
Parameters:
Name Type Attributes Description
state shaka.msf.MSFParser.StreamState
startLocation shaka.msf.Utils.Location <nullable>
Where to start, or null for the live edge.
Source:
Returns:
Resolves once the subscription has produced its first segment, and rejects with MSF_SUBSCRIBE_FAILED if the publisher refuses to serve the track from the live edge.
Type
Promise

stop() → {Promise}

Tell the parser that it must stop and free all internal resources as soon as possible. Only once all internal resources are stopped and freed will the promise resolve. Once stopped a parser will not be started again. The parser should support having |stop| called multiple times and the promise should always resolve.
Implements:
Source:
Returns:
Type
Promise

stopSubscription_(state)

Withdraws a stream's subscription, leaving its segment index alone.
Parameters:
Name Type Description
state shaka.msf.MSFParser.StreamState
Source:

subscribeToCatalog_(namespace) → {Promise}

Subscribe to the catalog in the given namespace. MSF requires a SUBSCRIBE that also retrieves the current Group from its first Object: that Object is the latest complete catalog, and the subscription alone would only deliver what is published after it, which may be nothing at all.
Parameters:
Name Type Description
namespace Array<string>
Source:
Returns:
Type
Promise

subscribeToOptionalJsonTrack_(track, trackKey, description, handler)

Subscribes to a track of JSON documents the presentation can do without, such as a media or event timeline, and hands each payload to the handler with its MSF_COMPRESSION undone and in the order the Objects arrived. An Object that fails to decompress is dropped. A compression we cannot undo at all is a different matter: MSF forbids reading the track and says to unsubscribe, and since the track is optional, playback carries on without it.
Parameters:
Name Type Description
track msfCatalog.Track
trackKey string
description string What the track is, for the log.
handler function(!shaka.msf.Utils.MOQObject, !Uint8Array)
Source:

subscribeToTrack(track, trackKey, callback, startLocationopt, nullable) → {Promise<?Error>}

Parameters:
Name Type Attributes Description
track msfCatalog.Track
trackKey string
callback shaka.msf.Utils.ObjectCallback
startLocation shaka.msf.Utils.Location <optional>
<nullable>
Where delivery should begin, or null to start at the live edge. A start at the live edge joins the current Group from its first Object, which is where media can start decoding and where a timeline track restates itself in full, rather than starting mid-group or waiting for the next Group.
Source:
Returns:
Why the publisher refused the subscription, or null when it did not: either the track is subscribed, or it was closed before the answer came and nothing is wanted any more. A publisher can refuse a request, and one that starts at a Location is the likeliest to be refused: the Group asked for may be older than anything the publisher still holds, whatever its media timeline said.
Type
Promise<?Error>

update()

Tells the parser to do a manual manifest update. Implementing this is optional. This is only called when 'emsg' boxes are present.
Implements:
Source:

updateAvailabilityWindow_()

Sizes the segment availability window, which is what the player offers as the seek range. Without a media timeline the window is a floor around the live edge and the presentation has no DVR, because nothing says where to subscribe from to get anything older. With one, the window reaches back to the oldest point the timeline still describes.
Source:

Type Definitions

StreamState

What the parser keeps for a stream that is currently subscribed. It is everything a subscription needs to be started again from somewhere else, which is what a seek does.
Type:
Properties:
Name Type Attributes Description
stream shaka.extern.Stream The stream this track feeds.
type shaka.util.ManifestParserUtils.ContentType The stream's content type.
track msfCatalog.Track The catalog track, which is what a subscription is addressed with.
trackKey string The namespace-qualified track name, used as the subscription key.
packaging shaka.extern.MsfPackaging The packaging that makes segments out of this track's Objects.
description shaka.extern.MsfTrackDescription What the packaging derived from the catalog, held for the initialization segment reference every segment carries.
startLocation shaka.msf.Utils.Location <nullable>
Where the current subscription was asked to start, or null when it follows the live edge.
generation number Counts the subscriptions this stream has had, so that Objects still in flight from a previous one can be told apart and dropped.
Source: