Listen to the `google.ima.AdErrorEvent.Type.AD_ERROR` event from the
IMA SDK AdsLoader instead of the `google.ima.AdEvent.Type.AD_ERROR` in
order to properly catch some ad errors that are currently being missed.
Closes#3095
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
When toggling between two text streams quickly(for example en -> fr ->
en), the mediaState's lastInitSegmentReference may not get updated to
'fr' before switching back to 'en'. That way, in initSourceBuffer_(),
the initSegmentReference is considered as fetched and appended, but the
buffer was in fact cleared.
Setting lastInitSegmentReference to null every time we clear the
buffer, and fetch and append the initSegmentReference with the new
update.
b/168253400
Change-Id: Id6378bdadd34f93a2a2f54ac84d82cf39b89716e
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
We should call URL.revokeObjectURL after calling
URL.createObjectURL() to prevent memory leak.
createObjectURL creates a strong reference to the MediaSource object
inside the browser. Setting the src of the video then creates another
reference within the video element. revokeObjectURL will remove the
strong reference to the MediaSource object, and allow it to be
garbage-collected later.
Fixes#2953
Change-Id: If9dc18a69468dfb8a6ebe7f4992bd61c716c2104
When a VTT cue spans a segment boundary, the cue will be duplicated
across two segments.
To avoid displaying duplicate cues, we compare the cues to be
appended with the cues already in the list.
1. We can assume the cues to be appended at once have no duplicates.
Make a copy of the current cues list, and compare the new cues only
with the cues in the current cues list.
If we append m new cues to a list of n cues, we can reduce the times to
compare the cues from m*m*n/2 times to m*n times.
2. We compare the cues deeply by comparing their nested cues and
all the elements. We can compare their start time, end time and payload
first, and only compare their nested cues and all other elements when
their start time, end time and payload are the same.
If cue1 and cue2 both have m nested cues, we may not need
to compare the nested cues instead of comparing m times.
Fixes#3018
Change-Id: I9992f0e1834fd16e8aedaf1895b036bc7ca29190
StreamingEngine takes the following steps to fetch and append a
segment:
1. Fetch and append the init segment, and initializes the source
buffer;
2. Fetch the segment;
3. Append the segment.
When StreamingEngine switches to a new text stream, it:
1. initializes a new text parser
2. If there's a fetchAndAppend_() call in the process, waits until
that is finished
3. Otherwise, clears the buffer, and schedules an update to call
fetchAndAppend_().
If switching the text stream gets called in the middle of a
fetchAndAppend_() process, the stream of the mediaState
can be changed between fetch_() and append_().
The new text parser is intialized, but the new init segment is not
fetched yet, however StreamingEngine tries to append the old segment.
That would cause an error in TextParser.parseMedia().
After a segment is fetched, we can check if the current stream is
switched. If so, the mediaState is waiting to clear buffer. We can
skip append, and schedule a new update for the new stream.
b/168253400
Change-Id: If8eebeb9a8e459baf0ff34748d77020098a9468e
Compare the codecs of two audio/video streams to decide whether they
are duplicate streams.
b/174040424
Change-Id: Ifde2068ddf9088f653280c013a1f3247cb7d45ba
Previously, the client-side ad container was put inside the controls
container, which was cleared when the UI was configured. This meant
that re-configuring the UI made client-side ads go away, basically.
This moves client-side ads to go into their own container, which
is never re-made or uprooted, even when the DOM is recreated, in
order to not break the IMA SDK.
This has the side-effect of fixing a bug where client-side ads were
not always cleared upon loading a new asset, and could show up
unexpectedly in future playbacks.
Fixes#2869Fixes#2943
Change-Id: I3cf67b0b278764c10c6ff2f678316dc9cc85929e
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
With slow network, fetchAndAppend_() may take some time, and the
text stream can get unloaded during the fetching and appending.
Before we schedule a new update of the text stream, we should check
if the mediaState of the text is still valid.
Fixes#2764
Change-Id: I311b0c18fd3f6ce8e167547bc91d4514a3790924
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
We found the issue within our app with the latest Chromecast CAF receiver update (November 22, 2020) that use Shaka 3.0.x. With our live stream containing 90 minutes of buffer, we notice high level of buffering issue with our customer.
It seems that the createUris callback was holding onto a parsing context in each reference.
Closes#3038
Previously, if the ad manager was shut down before the client side
ad manager finished setting up (most commonly due to adblock preventing
the ads metadata from being loaded), it would result in an error. The
client side ad manager assumed that the IMA ad manager would have been
loaded before unloading, and didn't check to see if the object was
null.
This prevents that error, by checking if the object is set before
stopping it.
Change-Id: Ic9e9b206bcd62641c0c2c6257b3eaacb6246e9df
In DASH, a trick mode track can be associated with multiple regular tracks.
This fixes the parser to respect the whitespace-separated list of IDs instead of assuming just one ID.
Resolves#2978
This refactors the user of SegmentIterator to be more of a strict
iterator and avoids the extra work of seek(). This has been moved to
SegmentIndex as a getIteratorForTime() function. This makes iterators
simpler and easier to understand.
This also refactors StreamingEngine to only create the iterator when
needed and to clear it when seeking. This also makes it easier to
understand since you need to get a new position if we switch streams
or seek.
Fixes#2956Closes#2970
Change-Id: If35a5d8aaba01598c526c2d70b9d9d0e305851c3
This is important for integration tests that use the compiled library
since we need to use objects defined in the compiled bundle. The
compiled library may call the renamed versions of methods, so our fakes
won't have the correct methods.
This also adds an immutable mode to SegmentIndex. The TestScheme uses
the same manifest objects for multiple calls to load(). However, when
unloading, the Player will call destroy/release, which will clear the
SegmentIndex. By having an immutable mode, we can reuse the same
manifest objects.
Change-Id: Id95c1df26c3c08b91cbfec7d1f61a551b897417d
Before asking the CDM about its support for a MIME type, convert TS
types as the Transmuxer will. That way, we're asking the CDM about
what it will eventually consume, not what we're streaming.
Fixes#2981
Change-Id: I6539e9a7e4c8afca348367c788e6438fb6e07b08
Some Tizen devices seem to misreport AC-3 support. This works around
the issue by falling back to EC-3, which seems to be supported on the
same devices and be correctly reported in all cases we have observed.
Closes#2989
Change-Id: I80f20ba796df29858728b19f8a9f6c1712c9556d
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
These two issues turned out to be related:
1. No way to select a track without a particular role (#2906)
2. Player should default to role-less audio tracks (#2909)
Before this fix, the Player would default to the first audio track
with a language match, which may have been an audio description track
or commentary track. If the user doesn't have a preference of track
roles, we should default to a role-less track when possible.
There was also no way to explicitly select a role-less track in
selectAudioLanguage. Before this fix, a call without a role would
effect a language-only match, ignoring roles and potentially selecting
a description or commentary track.
Now, not specifying a role (either in initial preferences or in
selectAudioLanguage) will result in a preference for role-less tracks
when possible.
Fixes#2906Fixes#2909
Change-Id: Ie6957eaecd1dcf9b7b65d62afa8ba9d9a5bdefe9
To support encrypted, multi-period live streams, you must initialize
the CDM whenever there is a license server config, without regard for
whether or not there is encryption signalled in a manifest.
If you join the stream during a clear ad, and there isn't enough
rewind allowed to see any encrypted periods at the time you join, the
manifest may not indicate encryption. If we start playback without
setting up decryption, we would fail later when an encrypted period
appeared.
This issue affected releases v3.0.0 - v3.0.5.
Fixes#2979Fixes#2645
Change-Id: Ic7ddcf46843178e6a3ce0b1d663da40dc9f4be8f
In bitmap-based cues, the tts:origin of the region should specify
the position of the background image. Add support for that case.
Closes#2703
Change-Id: I83ebeac939550138f8eef5d0b4547ab54fd6cf6c
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