The MP4 box header depends on both whether the box is a "full" box
(with version and flags) and whether the box has an extra 64-bit size
field. The MP4 parser was only considering the version and flags, but
not whether the extra size field was present. We already correctly
parsed the 64-bit size field, but computed offsets for other fields
without considering this.
Groundwork for a fix for #2759
Change-Id: I48f16ef073a036954b6f7d25641ccf29828b02c8
It is sometimes useful to load Shaka Player in nodejs, particularly a
debug build, to access some internal part of Shaka Player in a nodejs
script. For example, I am currently working on an MP4 box
transformation for Shaka, but I am doing the R&D in node on the
command line rather than in a browser.
For this setup to work, Shaka should not refer to browser-specific
classes and APIs at load-time. Thankfully, shaka.util.Lazy gives us
an easy way to lazy-load those things so that they are not needed at
load-time at all.
This change uses shaka.util.Lazy to defer a reference to
HTMLMediaElement in shaka.util.MediaReadyState.
Tangentially related to #2759
Change-Id: I376d2a81cb45e7cbc94be0a88deab3abb08001bf
This enables the eslint rule requiring jsdocs on all class
declarations, function declarations, and methods.
Unfortunately, there are two problems with this:
1. We don't use class _declarations_, we use class _expressions_,
which are not covered by this rule. So it does not enforce jsdoc at
the class level.
2. We tend to document a class at the class-level, rather than at the
constructor. But a constructor counts as a method for eslint, so it
requires docs on the constructor. There is no way to configure it to
make an exception for trivial constructors.
So for all trivial (no-argument) constructors, we add empty jsdocs:
/** */
constructor() {
This was quicker and easier than setting up some alternative plugin in
eslint to make an exception for us.
The good news is that this rule caught several undocumented parameters
and places where the jsdoc comment was malformed. So fixing those
also improves the compiler's ability to enforce types.
Change-Id: Icbc46ed690c94e53d354648a883119524f8fca45
We only just gained the ability to test on new Chromium-based Edge
(google/generic-webdriver-server@475ec746), so we did not previously
know which workarounds were specific to legacy Edge. Now all but one
of those workarounds has been limited to legacy Edge only, and will
not be applied to new Chromium-based Edge.
Change-Id: I70b7480ccb61064b796c3d9b41bbe95cabfdf850
Compare the codecs of two audio/video streams to decide whether they
are duplicate streams.
b/174040424
Change-Id: Ifde2068ddf9088f653280c013a1f3247cb7d45ba
If two text streams in two periods have no roles while other text
streams have, combine those with no roles.
Issue #2785
b/172605645
Change-Id: Ie3b98e7941d38f5be90f4eb65d1a3de1c3e394a3
If two audio streams in two periods have no roles while other audio
streams have, combine those with no roles.
Fixes#2785
b/172605645
Change-Id: I8aa4189c3ddc50257e0dbd72cae4840ae1d446f1
With "lowLatencyMode" enabled, "rebufferingGoal" is set to 0.001, and inaccurateManifestTolerance is set to 0 by default. However, in some cases longer rebufferingGoal helps to avoid new rebuffering.
Besides "lowLatencyMode", this code change adds the "autoLowLatencyMode" config. When "lowLatencyMode" config is disabled and "autoLowLatencyMode" config is enabled, and the manifest provides low latency features, we automatically activate the lowLatencyMode.
If "lowLatencyMode" is enabled, "autoLowLatencyMode" has no effect.
Issue #1525
1. Add support for multiple layers of nested cues.
2. Add support for anonymous span.
Closes#2623Closes#2761
Change-Id: I10a253b1a965606fc2db49c3168e92bcf4a95fa1
In v3.0, we changed our plugin interfaces so that all are factories
that return objects. We no longer call those with "new" as we did in
v2.5.
We provided backward compatibility and a deprecation warning to alert
applications to update their usage of those interfaces. However, this
compatibility shim was broken for ES6 classes, which behaved
differently than ES5 constructor functions.
This fixes the shim and adds regression tests. The tests were tricky
because we use Babel to transpile our tests, but we needed raw,
untranspiled code to define a class to test these features. So we use
eval and some associated trickery to get exactly the different kinds
of plugin registrations we intend to support. These tests are skipped
on non-ES6 browsers.
Fixes#2958
Change-Id: Ife8b63c0d89f4ea0aff085d3a4c156c4eb657604
This new method can make a HEAD request to the server to determine the MIME type. The old method (addTextTrack) is now deprecated and will be removed in v4.
UI plugins can already dispatch events on the controls, but it is much
less convenient to do so without this export.
Issue #2923
Change-Id: I46edbe01a67e70e052dbbded333af18d086d36ab
To enable low latency streaming, the configuration of
inaccurateManifestTolerance should be set to 0, and rebufferingGoal
should be set to less than 1 partial segment duration.
Instead of requiring developers to set three configurations, we
default inaccurateManifestTolerance to 0 and rebufferingGoal to 0.01
with low latency mode, unless speicfied.
Issue #1525
Change-Id: I538fa6d84ced26225fe9ebdf5213b370debfa22d
To enable low latency streaming, we need to append chunked data of
ReadableStream by complete MP4 boxes.
Everytime we get chunked data of the ReadableStream, we find the
last complete Mdat box. Append the completed boxes of data, and save
the data of the incomplete box until next time we get the chunked
data.
Issue #1525
Change-Id: I722ff992f397ee2f62bca45db33a0834ef57a270
With the low latency streaming mode, we fetch a segment, and get the
response data through a ReadableStream.
For each segment request, we may get multiple chunked data. We handle
and append the chunked data of the ReadableStream via a callback
function in the StreamingEngine.
Once the whole segment gets handled and appended, we move on to the
next segment.
Issue #1525
Change-Id: I7949c87f4e491c928919c2e9dc4dafbebac22c9b
This pertains to #2648 (although this is a new feature, not a replacement) and #1404. A CEA-708 decoder that follows the CEA-708-E standard, decodes closed caption data from User Data Registered by Rec. ITU-T T.35 SEI messages, and returns them as cues in Shaka's internal cue format. Furthermore, this pull request fixes and cements some of the logic surrounding CEA-608 and CEA-708 tag parsing on the Dash Manifest Parser.
Format:
Similar to the CEA-608 decoder, cues are emitted in Shaka's internal format (lib/text/cue.js). This decoder makes use of nested cues. The top level cue is always a blank cue with no text, and each nested cue inside it contains text, as well as a specific style, or linebreak cues to facilitate line breaks. This also allows for inline style (color, italics, underline) changes.
Details:
- ASCII (G0), Latin-1 (G1), and CEA-708 specific charsets (G2 and G3) all supported.
- Underlines, colors, and Italics supported, set as a property on each nested cue.
- Positioning of text is supported. (Exception: In CEA-708 the default positioning is left, in this decoder it is centered.)
- Positioning of windows not supported, but relevant fields that could be used to support this are extracted and left as a TODO.
Previously, to decode UTF8 content, we used the browser's
decodeUriComponent method. This worked in most situations, but it
would stop and error the moment it found an invalid UTF8 character.
This meant that a single poorly-encoded character inside a text stream
would cause the entire closed captions to fail to display.
In this CL, we switch to using the newer TextDecoder API, which
will instead replace invalid characters with an "unknown character"
code point, and continue parsing. This should make our text parsers
more robust when faced with bad encoding.
Closes#2816
Change-Id: Ibf2887e143d24d15a127bbcf2961539669580eea
The duplicate cues check did not account for nested cues, which could
cause some inputs to be erroneously filtered out. This uses a more
detailed check that includes all properties.
Change-Id: I517be17a8f7377f8840f102d26d515baa327530a
1. Move the config field from ManifestConfiguration to StreamingConfiguration, since StreamingEngine will need it.
2. In manifest parsers, we get the value of lowLatencyMode config from the StreamingConfiguration.
Issue #1525
Change-Id: Iaa961b4e6799ecc1fcf3147b2fb992e86d4b043d
Our period flattening logic used to keep creating new streams and variants
when encountering a certain type of content (same main content and slightly differing
sequence of ads). In time, this led to a performance drain, where more and more time
was spent processing the variants, leading to all kinds of delays.
This is the last change in the series, addressing the way we set stream properties
when concatinating streams.
Fixes#2716.
Fixes#2736.
Change-Id: I98ae692797d19344601d7a0c51d1e343dfe55e01
Data URIs can have additional parameters other than just the MIME type
and encoding. While working on TTML fixes, I was debugging by
inserting data URIs as TTML text tracks. But the data URI encoder I
used was inserting a "charset" parameter into the URI, which was
rejected by Shaka Player.
This fixes the data URI parser to understand these extra parameters.
While researching this fix, I also found that only the base64 encoding
is specified for data URIs. So now only that specific parameter is
supported as an encoding, and the UNKNOWN_DATA_URI_ENCODING error code
has been retired.
Change-Id: I7022529b0931e80a77a1120fc86c25b42e1fb3d9
Playback stalls on Tizen can be corrected by pausing and playing
again. For Tizen and similar platforms, this is superior to the old
way of seeking to unstall playback, because seeking is expensive on
those platforms.
To facilitate pausing and playing again instead of seeking, a
stallSkip value of 0 will trigger the pause/play workaround instead of
the seeking workaround. Further, we will make this the default on
Tizen, WebOS, and Chromecast.
An internal detail which is changing is that GapJumpingController will
now call StallDetector first and inhibit gap jumping when the stall
detector has something to do, rather than the other way around. This
allows the StallDetector to be in charge of deciding what is buffered,
rather than having to pass GapJumpingController's interpretation of
buffered ranges first.
Fixes#2620
Change-Id: I5ad7aad42aa185b2837c830970e54218b4e55a21
1. In low latency mode, the playback start time from live edge is about
3 times partial segment duration, 3s for example. The rebufferingGoal of
2s would result in infinite buffering.
2. In low latency mode, do not allow drift for seeking. Only seek with
the presentation time.
Change-Id: Iee92727bf17dab8b52fae070522a5a2ec1621ffc
This is an MP4 Parser which extracts CEA-708 packets from Fragmented MP4 streams.
The Closed Caption Parser (shaka.media.ClosedCaptionParser) will own this MP4 Parser, and will initialize it and call it as shown. As data comes in, the parser will parse this data, and the caption packets data then be returned in a callback (on708Data), as shown. Here, a theoretical decoder (future pull request, mentioned as a Todo comment) will decode and extract the parsed captions from these packets.
Issue #2648
The period-flattening algorithm is run even on single-period content
if the manifest is dynamic, because we don't know if another period
will be added later.
As a failsafe, we should create one output per input for single-period
content, and we can ensure that no streams are unused by marking an
input stream as the "best match" for an output if they share the same
ID. That way, even if all other characteristics for two inputs are
the same, the input-to-output mapping for single-period content will
always be sane.
That ID-based logic was missing for text streams. This change
corrects that.
Closes#2646
Change-Id: I28c6c63d92bcf710ae0072783911f9e66ed78228
This fixes all the license headers in the main library, which corrects
the appearance of the main license in the compiled output.
It seems that the `!` in the header forces the compiler to keep it in
the output. I believe older compiler releases did this purely based
on `@license`.
Issue #2638
Change-Id: I7f0e918caad10c9af689c9d07672b7fe9be7b2f3
@exportInterface is used by the extern generator, but ignored by the
compiler. @export should be used for shaka.util.FairPlayUtils and
shaka.util.BufferUtils.
Closes#2626 and #2627