When the subtitles are turned off, unloadTextStream() on streaming engine is called, but currentTextStream is never set to null. When the captions are turned back on, a check in player.js sees that the current text stream is not null, so it assumes it exists, and is ready to go. Thus captions are never loaded.
Clearing (setting to null) the current stream on unloadTextStream ensures the text stream is properly initialized the next time it is called, and in a state so that captions can resume being parsed.
After further investigation, it seems that the unit tests are written in a way that assumes that the text stream is nulled when unloadTextStream is called. So this fix is definitely something that we assume already happens.
Closes#2671
During video playback, if the user switches the caption stream (e.g. CC1 to CC3 which changes languages), the first caption in the next fragment is missing.
In fragmented MP4s, the end time of a caption is determined by the start time of the next caption. Thus for the last caption in a fragment, the end time cannot be determined until the next fragment is parsed.
Before this fix: the clearing of the caption stream was being called from a chain of function calls originating from clearBuffer_() on the Media source engine. But clearing a buffer and resetting a caption stream are two independent operations. As a result, the caption parser was being reset (its buffer cleared) during video seeks, and during stream switches. This makes sense for video seeks, because the end time of the last caption in the fragment can't be determined if the entire presentation timestamp changes. However for stream switches, resetting the parser doesn't make sense. Clearing the caption parser during a stream switch would actually get rid of the last caption in that fragment (which wasn't emitted since its end time wasn't determined yet), and we would lose the data, causing the problem.
The fix is to reset (and hence clear) the caption parser during seeks, but not during stream switches.
Issue #2648
This corrects/normalizes license headers in misc. files, such as
config files, docs, build tools, tests, and externs. This does not
affect the compiled output, and is only done for consistency.
Issue #2638
Change-Id: I9d8da2de55243b08d7df2b743aac73c6f15e858a
The StreamingEngine tests use various fakes that did not have strong
type info before. The new Closure Compiler won't allow this, and for
good reason. Cleaning up the type info exposed a few ways that we had
left out important things or failed to remove methods that are no
longer on the types we're faking.
We also had some fakes for StreamingEngine tests that were redundant
with strongly-typed fakes that already existed in shaka.test. This
deduplicates them. The fakes for StreamingEngine are now just
instances of the other fakes with specific behavior attached.
Issue #2528
Change-Id: I0da67bea462e855fcfcb1b391fe83027ffa70702
Various issues with the nullability of number types led to various
fixes, including:
- defaulting a nullable number to 0 to avoid propagating a null value
through calculations
- adding an assertion or runtime check that something is not null
- moving an existing null check to before the calculation
- returning early on null during an iteration
- changing a nullable number to non-nullable
- defaulting to NaN instead of null
These issues were caught by a compiler upgrade.
Issue #2528
Change-Id: I86d516c74a42ee3624c33d7513d2d4c76d3ea589
Period-flattening will concatenate Stream objects, so this information
should be available per-Stream instead of at the Variant level.
Issue #1339
Change-Id: I96195fea48cab1e4a349b2ab0b16064a443e928a
This removes periods from the internal manifest structure and cleans
up code and tests accordingly. This leaves us unable to play
multi-period DASH & offline streams until the main period-flattening
algorithm is completed in shaka.util.Periods.
Three test cases have been disabled for the moment.
Multi-period playback will be restored in a smaller, more focused
follow-up commit, with disabled tests re-enabled.
Issue #1339 (flatten periods)
Issue #1698 (rapid period transitions issue)
Issue #856 (audio change causes bitrate change)
Closes#892 (refactor StreamingEngine)
Change-Id: I0cbf3b56bfdb51add15229df323b902f0b2e643a
As part of Period-flattening, I'm trying to remove our dependence on
the "position" field of SegmentReference. With that eliminated, we
can more easily concatenate Arrays of SegmentReferences without
modifying them.
- Make SegmentIndex iterable
- Add specialized seek() and current() methods to SegmentIterator
- Remove position from SegmentReference
- Make positions in SegmentIndex API stable without field in
reference
- Remove brittle hard-coded positions in tests (except SegmentIndex
tests, where they would be hard to avoid in testing methods
separately)
- Use SegmentIterator in StreamingEngine to track the next segment
between switches
Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)
Change-Id: I666cc21249c34ee6cbc138a59109d9f1159fa127
This reverts commit 235e4e11ad.
The effort to remove SegmentReference's position field will be handled
in a different way.
Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)
Change-Id: I62b115137abc89f498b30467e574b0401dcad05d
As part of Period-flattening, I'm trying to reduce our dependence on
the "position" field of SegmentReference. If it can be eliminated, we
can more easily concatenate Arrays of SegmentReferences without
modifying them.
SegmentIndex can now track the last reference you asked for and
iterate through the list of references. This means we don't need the
"position" field of SegmentReference, which means we don't need to
know positions in advance or globally. StreamingEngine will no longer
use position to request segments.
The old methods find(time):position and get(position):SegmentReference
have been replaced with seek(time), current(), and next(), all of
which return a SegmentReference and maintain an internal pointer to
the "current" reference. Care has been taken to maintain that pointer
during the evict() and fit() operations. Recent changes to merge()
made sure that the pointer does not need to change during that
operation.
All test updates are related to the SegmentIndex API change, not
changing expectations or behavior.
Issue #892 (refactor StreamingEngine)
Issue #1339 (period flattening)
Change-Id: I1682dcc2dd625c6e390711538e46d31e6eb6cea8
We fetch the previous segment in Live streams to combat differences
between the manfiest times and the segment times. Now this can be
configured so apps with correct manifests can avoid the extra segment
request.
Also, we'll update the buffering state when a segment appends so we
leave the buffering state sooner.
Issue #2291
Change-Id: Id12c8132dc11739e4c8d42cb1f08e6ae7da1a966
This changes the eslint rule to enforce a strict pattern for the
argument comments. The comment must appear before the argument and
must be /* foo= */. This still ignores line comments.
Change-Id: I3afb01c65e1088eda13facb3aeeaa7595a2f5aee
SegmentReference used to have presentationTimeOffset, which,
subtracted from the period start time, was then _added_ to the
timestamps in the segment by MediaSource.
Now, SegmentReference has a timestampOffset field, which is exactly
what MediaSource's timestampOffset field is set to on the SourceBuffer
before this segment is appended. For DASH, this is periodStart minus
presentationTimeOffset.
This also adds append window start & end times to the
SegmentReference. Now segments can be appended to SourceBuffers
without reference to the period.
Note that start & end times of the SegmentReference in each segment
index are still relative to the period. This will change in a
follow-up.
Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)
Change-Id: I9d54eb2b529ec643c9475b8e9d218c3e2e826a26
This reflects changes in Google's policy on JavaScript license
headers, which should be smaller to avoid increasing the size of the
binary unnecessarily.
This also updates the company name from "Google, Inc" to "Google LLC".
Change-Id: I3f8b9ed3700b6351f43173d50c94d35c333e82b4
Because aborting requires knowledge of the new stream, this process
must be done asynchronously. This makes the abort logic async, and
checks carefully for any stream or operation changes during the
process.
Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)
Change-Id: Ic187676eeca907603efeb0ffa11855b9af2fc5ca
Instead of making many internal methods async to accomodate
createSegmentIndex being called lazily, just call createSegmentIndex
during the update cycle instead. This greatly simplifies things and
allows me to revert some of the changes I made in the earlier commit.
Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)
Change-Id: I72be8e88f0cf8b04b63d3cda129fa38cef727c0f
In StreamingEngine, rather than wait to enable ABR after indexes have
been created for all streams, create each stream's SegmentIndex
on-demand as needed during playback. This means ABR can be enabled
much more quickly, and also eliminates some complexity from
StreamingEngine's startup sequence.
This required several test changes, since many of our tests were
accidentally structured to depend on certain operations either being
synchronous or happening early during startup.
Issue #1339 (flatten periods)
Issue #892 (refactor StreamingEngine)
Change-Id: I4bc1d0cdf9022aad14a008accf0aac37c870a83f
We would incorrectly initialize the embedded captions multiple times
during a Period transition, which caused duplicate cues to be given to
the displayer. We also wouldn't handle the case when switching between
embedded captions and external text during a Period transition. This
fixes both cases and adds tests for them.
This also avoids passing an empty cue list to the displayer.
Fixes#2076
Change-Id: I89add3eb86ad8d93644bba14eabd11f98d57bc5e
This allows us to avoid suppressing the indentation rules and ensures
we have correct indentation. It also makes it harder to make mistakes
since the variables are only accessible within the callback and you
can't accidentally contaminate another object with an incorrect call.
Closes#1692
Change-Id: Ic38b5cd57a2587dfc8c115ba782656c15565b655
To prepare for flattening out the manifest structure to remove
periods, this change moves initSegmentReference and
presentationTimeOffset fields into the SegmentReference object. This
way, the segments on either side of a period transition or HLS
discontinuity can have different offsets or init segments, eventually
allowing us to create a single array of SegmentReferences for
multi-period content.
Issue #1339
Change-Id: Ic7eff0483789644881247ecf8044c5fb6a48f0e6
This replaces find/get callbacks in Stream with a SegmentIndex. With
the exception of DASH's SegmentTemplate+duration, all manifests were
already backed by SegmentIndex. Now, all manifests are backed by
SegmentIndex. This will simplify Period-flattening, in which all
tracks will be represented by a list of segments, some of which come
from different Periods.
The SegmentIndex in Stream will not be created until
createSegmentIndex is called. Prior to this change, the find/get
callbacks could be invoked without createSegmentIndex() in some cases
(excluding DASH's SegmentBase), which some lazy tests took advantage
of. Now that find/get are methods on SegmentIndex, createSegmentIndex
must be called in all cases. The tests have been updated accordingly.
Making SegmentIndex generation async in all cases exposed some issues
with the parser context being modified in-place between one
Representation and the next. So the parser now makes a shallow copy
of the context before it is bound into an async callback.
To facilitate updating the SegmentIndex for SegmentTemplate+duration
content, SegmentIndex now has a method to update its list on a timer.
Once per segment duration, the index will be updated to add and remove
SegmentReferences.
The initial expansion of SegmentTemplate+duration will be limited to a
relatively small number of segments, to avoid excessive CPU or memory
consumption. This defaults to 1000 segments, but is configurable.
Issue #1339
Change-Id: I99c007b1096c3b396d04a729750cd7b743cb899d
This ensures that we get the expected types and that type coercion
doesn't convert between types. This also ensures we are consistent
in how we check for equality of primitives in tests.
Change-Id: I9f3aacdf25ab1afe5e8d6e4b895b5299ee687d54
This error wasn't caught before, but was fixed in a recent CL. This
adds a test to ensure we don't regress later.
Change-Id: I10e72303c39de82bb9a1f7cb4a6b171c46fdbecd
"StreamingEngine switchVariant/switchTextStream will not clear buffers
if streams have not changed" would fail sometimes with an upgrade to
Jasmine 3 (14/500 runs). Further investigation revealed that a race
would cause the presentation time to be accessed before it was set,
which led to a segment position of NaN, and a segment reference with
start and end time of NaN. It is not clear why upgrading Jasmine
caused this race to become more apparent.
This fixes the problem at several levels:
- An invalid segment position in the ManifestGenerator will cause a
failed assertion.
- An uninitialized presentation time in the StreamingEngine unit
tests, which led to the invalid segment position, will cause a
failed assertion.
- The presentation time for the switchVariant test is now initialized
properly.
After the fix, the test passed in 500/500 complete test runs.
Change-Id: I5c4c52a9e2a89edb61f7d99721be3df840bba30d
Rather than only aborting a request if the new request is smaller
(effective when adapting down), abort if the new request will be done
"on time" (effective when adapting up) without causing buffering.
Change-Id: I7572b8bfc566a4f264a5080e4c1bc983f1363ce0
This is a fully automated change. The linter will fail because the
extra indentation caused line-length errors. These won't be fixed
automatically. They are fixed in a follow-up to make this one fully
automated.
Change-Id: I4d8cf9c998985add2bcd24a81c8d65495668c4f3
With the new style rule, we cannot have two statements on the same line.
So we can no longer have an "if" on a single line and we cannot have
an arrow function with a body on the same line as when it is used.
This is mostly a manual change.
Change-Id: I2285202dd5ecbad764308bc725e6d317ff2ee7f0
We use custom indentation for the ManifestGenerator to make the repeated
calls easier to read. This disables the coming linter rule for these
blocks of code. This also goes through and unifies the formatting. The
indentation should be 4 spaces from the left side.
Change-Id: I687e69cea39bded1e9e06bffdcc888970b383fa2
This is an automated change to convert use of "function" functions
to arrow functions. This doesn't change all uses of bind() that
could be converted. This also doesn't remove all "function" functions.
Change-Id: I40ac7d086bcef947a1be083359c8fd1d4499a9c3
A follow-up commit will convert "function" functions to arrow functions.
This caused some errors with the compiler, which this change fixes
beforehand.
Change-Id: Iff85b1e1f56b63a38b09f8db9947ed5daf02ddf4
A coming update to the Google eslint config will require using "const"
over "let". This makes that one change to isolate the big changes.
Change-Id: I7d0974c3ae15c53cc45a6b07bf9f6586e2d34aca
Previously, on seek, if any stream was unbuffered, it was considered an
unbuffered seek and every stream was cleared. This was to account for
the possibility that the streams would end up in different periods, and
therefore cause a hang.
However, this meant that changing the audio stream caused the video
stream to be flushed and reloaded pointlessly.
This changes the code to only clear all buffers if a stream has moved
into a different period; if one hasn't, it clears them on a case-by-case
basis.
Closes#1714
Change-Id: I6385e24266834bfc0c6dd2678facc5559affb941
When the audio and text languages differ, we should display the captions
by default. This also happens if the app calls setTextTrackVisibility
before calling load. What happened is the text media state was being
created, but an update wasn't being scheduled. This meant the text
segments never got appended. This changes when the update gets
schedules. This also removes an unnecessary call to set the initial
state during startup.
Issue #1696Closes#1879
Change-Id: If3a1b9e2889fc0e487da0e7276ca837636bf2e54
When the network becomes slow, we check if stopping the current request
and download the content with lower resolution is faster. If so, abort
the current request and start a new one.
Issue #1051
Change-Id: I588e524469432e362361d1cfbde6cd45c2009959
The init method on streaming engine is responsible for initializing
streaming engine but it also starts the streaming process. In the
greater scheme of things, this is what starts playback.
To help communicate the full effect of what this one method does, this
changes its name to be "start" which helps show that it is starting a
process, not just initializing.
Change-Id: Ieceecce85917d97277782f41fd376fc6f97eaac9
In streaming engine, we would use playhead to get the current
presentation time. Playhead was provided via the player
interface (defined by streaming engine).
Since streaming engine only needed to know what the presentation
time is, this changes the player interface to require a function
to get the presentation time rather than the playhead.
The general theme of this move is to help define the interface
in terms of needs and not the means in which they are fulfilled.
Change-Id: I442d54f08b650f22b9273a191d5a3a57af37b5bf
To make it easier to understand the context of the streams
and periods returned by StreamingEngine, "getActive" is
renamed to "getBuffering".
Change-Id: I99aec589bd4d736b170fa2197e5097ff33c0fc82
Instead of duplicating the default configuration values in each test,
this now uses the default configuration methods.
Change-Id: Ifd2ab349db7903a2acb0d06fed4bd0ccd5050b35