Text track handling is not managed by MSE but by ourselves, thus we do
not need to discard text references.
As we do not reset the text engine alongside MSE, text tracks would
simply disappear when crossing a boundary and MSE was reset.
There's devices out there that are not compliant with the MSE spec. Such
as halting MSE when a secondary init segment is appended (webOS 3), or
failing to transition from a plain to encrypted init segment (Tizen
2017). While we initially prefer content workarounds, it's a time
consuming and trial & error process. For some devices it might not be
worth investing time into finding a proper workaround due to low usage.
We're giving people an alternative by resetting MSE when needed
(configurable). dash.js offers somewhat similar behavior
[here](https://github.com/Dash-Industry-Forum/dash.js/blob/a656ec709e7f92f76b392bf196ee9883da7928ce/src/streaming/controllers/StreamController.js#L672),
where MSE is reset before applying an encrypted init segment.
This PR introduces `crossBoundaryStrategy` in `StreamingConfiguration`.
It can be configured as following:
- KEEP - we're keeping MSE active, this is the default and the current
behavior.
- RESET - we'll always reset MSE when it crosses a boundary.
- RESET_TO_ENCRYPTED - we reset MSE when it crosses an encrypted
boundary, and we keep MSE afterwards. Additionally, we're not going to
reset when we're crossing a plain to plain boundary.
Each initSegmentReference now holds an `encrypted` and `boundaryEnd`
value. When configured with a different value than KEEP,
`StreamingEngine` will be instructed to fetch and append segment
references up until the boundary of the currently applied init segment.
We detect whether we're at a boundary in a few ways:
- Listening to the HTML5 MediaElement's `waiting` event, this'll
indicate that we do not have enough buffer to advance. If we're pretty
close to the boundary, we assume we're at the boundary.
- Due to subtle differences in the segment alignments, waiting wasn't
reliable. When close to a boundary, a timer is fired with the assumption
that "we'll reach the boundary at soon". I've set the threshold to 1
second, when playhead is further than the threshold, we'll skip checking
whether an MSE reset is due.
The implementation relies on the added properties in the init segment
reference, and the concept of a "Period" is avoided in StreamingEngine
to ensure it's compatible with HLS too.
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
With reference to #8025, this is a partial proposal to see if this style
of extensible customisation could be favourable to the shaka-player
community:
Proposal for some accessibility options whereby an App builder can
customise subtitle/caption size, with the potential of an App offering
accessibility options for text size.
This style could be used for other text styling attributes in a similar
way, but this is just the first step.
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
`TimelineSegmentIndex` `fitTimeline` doesn't check if `templateInfo` is
null. This means it errors in this case when it tries to access the
`timeline` property. It now exits early if it's null
This helps debugging issues easier by having everything in the same
file. It also allows you to align your implementation with what hls.js
and dash.js do.
My previous change, #8109, didn't go far enough. In a full test run,
some ClearKey tests still crash Firefox in the lab. By removing it from
the support dictionary used to gate DRM tests, we ensure all ClearKey
tests are skipped.
`getAllThumbnails` creates an array of promises when grabbing each
thumbnail. This is because `getThumbnails` might have to create a
segment index, but `getAllThumbnails` already does this. This separates
`getThumbnails` into two functions so `getAllThumbnails` can get the
thumbnails synchronously.
Our automated test lab runs Windows browsers under a headless service.
In this environment, Firefox's ClearKey CDM seems to crash when we
create the CDM in probeSupport().
To avoid this, we check for a debug or uncompiled build running in
Firefox on Windows, and if this combination is found, we skip
createMediaKeys() in probeSupport().
Because the check uses the compile-time constant goog.DEBUG, we avoid
any penalty in a production build.