Commit Graph

582 Commits

Author SHA1 Message Date
Jacob Trimble c81389741f Prefer const over let.
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
2019-05-08 09:22:10 -07:00
Joey Parrish 683d17f57e Hide volume button on mobile
Fixes b/131924038

Change-Id: I4c86cb14c240c8e795e18fdf54e8bee11a3cec61
2019-05-07 22:28:56 +00:00
Joey Parrish 662d6e6533 Un-export IReleaseable
No exported classes implement this, so we do not need to export it.

Change-Id: I9d91e486d598a05f02c3056a5aaa8afae14a32e8
2019-05-07 19:10:46 +00:00
Joey Parrish cbfe4f82a4 Fix warnings found by a newer compiler version
This is only some of the warnings produced.  These were not errors,
but we should fix them anyway so that we can adopt stricter settings
in future.

Change-Id: Ifd12f0e7c69f8f4b3d0d78b11794da2569a06d77
2019-05-06 22:25:12 +00:00
Joey Parrish 685e9d57cf Eliminate free calls of static methods
It is type-safe to alias a class, but not one of its static methods.
Aliasing the method without the class makes it a "free call" to invoke
the aliased method.

A "free call" is when you call a method without the context of its
instance of class.  There were several cases of this with static
methods.

This will be enforced by a future release of the compiler, which I
believe will lead into compiler support for "this" in static ES6
methods.  In ES6, you can use "this" in static methods to refer to the
class and call other static methods.  Closure compiler doesn't support
static "this" yet, but we will start using it as soon as it is
supported.

Change-Id: I4249db8b6dda9231ebba60ee0d4ad734a692c2fe
2019-05-03 18:43:35 +00:00
Joey Parrish d27d8180e0 Only use configured license servers if provided
If the application developer specifies license servers, only those
should be used.  Before this, a manifest-specified license server
for a certain key system could still be used if the application didn't
provide one.

Now, if there are _any_ license servers specified by the app, _no_
license servers will be used from the manifest.  This is important
because it allows the application a clear way to indicate which DRM
systems should be used on platforms with multiple DRM systems.

The new order of preference for drmInfo:
1. Clear Key config, used for debugging, should override everything else.
   (The application can still specify a clearkey license server.)
2. Application-configured servers, if any are present, should override
   anything from the manifest.  Nuance: if key system A is in the manifest
   and key system B is in the player config, only B will be used, not A.
3. Manifest-provided license servers are only used if nothing else is
   specified.

Introduced in #1644 to solve #484
Internal issue b/131264101
Closes #1905

Change-Id: I1a36a70044dc7bcc22681e3e4246d0a43d58e413
2019-05-02 20:30:54 +00:00
Joey Parrish b513a48418 Fix range header regression
Range headers should not be sent when requesting the entire resource.
This fixes compatibility with Microsoft IIS web server.

Introduced in work on issue #1788

Change-Id: I151a2f15d4f5e95531e16d5372ee9a051135f12f
2019-05-01 17:02:53 +00:00
Joey Parrish a121733a11 Add FairPlay EME polyfill and DrmEngine support
This adds a polyfill for Apple's prefixed EME implementation.  This
will be used on all macOS versions prior to 10.14 (Mojave) and on
Safari versions prior to 12.1.

This also adds support for FairPlay license protocol eccentricities
in DrmEngine, so that the proper formatting is used for requests and
responses.

Issue #382

Change-Id: If1274d2f018a475f56c09df97645694f13acbde9
2019-04-30 21:15:11 +00:00
Joey Parrish 8391fe1684 Extend Player track methods to cover native HLS
Track methods are now implemented for native HLS and other src=
playbacks.  This will allow the UI to select text and audio languages.

This change adds best-effort methods to get track information for src=
playbacks, including native HLS on Safari.  In many cases, it relies
on the audioTracks and videoTracks members of HTMLVideoElement which
are only implemented on Safari.  They are in the spec, though, so
there's no harm in using them when they exist.

This is fully parallel to the manifest-based paradigm for MSE-based
playbacks.  Each of these top-level methods in Player has an "if" to
decide which way to supply the requested info, except for the language
methods, which now delegate to the track methods.

With this, Safari's native HLS can supply audio and text language
information to the UI/app, and the UI/app can have some control over
those things through the tracks API.  I believe this is important to
the success of our new iOS support.

Issue #997
Issue #382

Change-Id: Icc44a932927fafedda1b62a9d4c6e2ed3dc7db30
2019-04-30 21:15:00 +00:00
Joey Parrish 0e65a4543e Fix EventManager listenOnce with multiple listeners
When listening to the same event on the same object from two places,
it's important that both listeners get called back.

This fixes EventManager's listenOnce() so that the unlisten() call
within listenOnce() doesn't remove both listeners at once.  Now each
listener will be called before it is removed.

This bug is over two years old!

Change-Id: Id99f3a8e5ab80819921b30e28aa66d8a08b29e86
2019-04-30 18:33:26 +00:00
Sandra Lokshina 7a15c1e94f UI: Dynamic layout construction.
Fixes #1674

Change-Id: I338917bbd43a6ddc837388fdc8beea9e3f7b0778
2019-04-29 21:17:39 +00:00
Michelle Zhuo cb9decbb5f Reject AES-128 HLS content with meaningful error
Currently we check encrypt key tags after we parse the segment, so
playing an AES-128 encrypted content results in error message
'MANIFEST.HLS_COULD_NOT_PARSE_SEGMENT_START_TIME'. We should check the
encrypt key before, and give a more clear error message.
Filtering out the contents encrypted with AES-128, and if there's no
valid content left, we'll show 'CONTENT_UNSUPPORTED_BY_BROWSER'.

Closes #1838

Change-Id: I893f57a939e45f2787144dfe311b779aed26ac34
2019-04-22 18:48:18 +00:00
Joey Parrish cf0700b273 Remove unused MapUtils methods
Change-Id: I95d05e1bcf437d70586b6f0207128e4ba782b125
2019-04-17 22:21:16 +00:00
Joey Parrish 133f161b93 Support all types of single-file playback
Instead of triggering src= based on 'video/mp4' MIME types, ask the
browser what it can support using video.canPlayType().

Querying canPlayType() also allows us to detect src= support for
native HLS in Safari.

The original version of this change also added a complete fallback
system to detect MIME types based on common file extensions and
fetch MIME types via HEAD request when necessary, but the load graph
system does not yet allow us to make async decisions about destination
node.  So this async MIME detection is commented out for now.

Closes #816 (src= single file playback)
Issue #997 (native HLS in Safari)

Change-Id: If1930ca4fd5710481a925d63fb312d9a5b15fec8
2019-04-16 22:59:18 +00:00
Joey Parrish 4854d362f5 Cover iOS in isBrowserSupported and probeSupport
Now iOS is supported for HLS through src=, so isBrowserSupported
needs to reflect that.  This makes MediaSource optional for any
browser with src= playback of HLS.

This also fixes probeSupport() to reflect the capabilities of non-MSE
platforms such as iOS, which is critical for our demo app to be able
to show the correct set of playable assets.

Issue #997
Closes #1857

Change-Id: Ic6e18587db90fff2b097a2038c16cc928e2b9438
2019-04-12 14:31:51 -07:00
Aaron Vaage 31b94e8bd4 Set src= Load Mode
Create the src= load branches for the remaining public methods. This
should ensure that it is now safe to call the public methods when
playing src= content and expect to get the intended return values.

The tests to verify this are in a follow-up CL.

Issue #816
Issue #997

Change-Id: I088b6bbd2489b3960457030846debae07fd86d16
2019-04-10 18:44:35 +00:00
Sandra Lokshina 436e30dc11 Add integration tests for UI captions selection.
Change-Id: I59bd837a3542636c98fa8ecec6d6d0e7dfd64e23
2019-04-08 15:09:36 -07:00
Sandra Lokshina 493d459c47 Add a DOM util.
Change-Id: Ia0941868f20dbb42fa0fe02a639015ac244a65ed
2019-04-05 12:01:59 -07:00
Aaron Vaage 040ecf6978 Create src= node
This CL creates the "loaded with src=" node and its initial
implementation. Adding this node required some changed to the routing
logic as a new destination was created.

We will use src= when given mp4 content or media source is unavailable.
We detect mp4 content via the mimeType in |load| and/or the file
extension. When media source is not available on a platform, we fall
back to using src=. To do this, we check if media source is available
whenever |load| is called, and will route to the src= branch if media
source is not found.

To avoid pre-initializing media source (when it is not available) we
modify the |initializeMediaSource| flag in |attach| and |unload| when
media source is not available.

Doing this showed that we had inconsistent behaviour between |attach|
and |unload|. |attach| would default to initializing media source
whereas |unload| would not. This has been fixed.

Issue #816
Issue #997

Change-Id: I00599832b49c9079e273e65a4b827fee736479cc
2019-04-01 22:56:39 +00:00
Álvaro Velad Galván 732f86b18a Track time in "pause" state in stats (#1855)
Before, we reported the total seconds spent in the "playing" and "buffering" states, but we did not track the total time spent in the "paused" state.

Now that we can derive the "total time spent in" via `StateHistory`, we can easily fetch the total amount of time spent in the "paused" state (which is tracked in our state history).

This adds a new field to `shaka.extern.Stats` for `pauseTime`, defined as "The total time spent in a paused state in seconds'.
2019-03-29 08:47:11 -07:00
Aaron Vaage 5018251aa1 Derive State Times From State History
We track how much time we spend in different states in the state
history, this means that we can derive the total time rather than
needing to track it separately.

Change-Id: I8ba0f8a7a842b54839cef14c5c42bf3c379549b0
2019-03-28 21:41:07 +00:00
Aaron Vaage 78aa5752fb Generalize State History
This change makes state history track any state by moving the idea of
buffering, playing, etc to the player.

This allowed the stats and state history to drop they connection to the
media element.

Change-Id: Ieed198a09b3ade33e4ee850445b809f251cf2558
2019-03-28 21:40:58 +00:00
Aaron Vaage fd2d61d027 Make Stall Detector Configurable
Make the stall detector configurable via Player.configure. This
should make it easier for developers to work around stall issues
and make it easier for us to find ideal configuration for
different platforms.

This exposes:

- Enabled   : A flag for whether or not the player should
               initialize and use a stall detector.

- Threshold : The number of seconds that must pass without
               progress before firing the stall-event.

 - Skip     : The number of seconds to skip forward after a
              stall-event.

To make enable possible, the stall detector was made optional and
is now passed into the gap jumper. This allows Playhead to evaluate
the config and create the detector as desired.

Issue #1839

Change-Id: Ife1bf34b4cfc7b469f4b0beb312a06d5b5cd81a9
2019-03-20 19:19:03 +00:00
Aaron Vaage 25710b6c33 Refactor Segment Request Creation To Be Shared
In four different places in our code base, we did the same
work to create a segment request. The bulk of the work was
based on setting-up the range header.

This CL creates a common utility that will create the request
for us while keeping networking engine as ignorant to segments
as it was before.

Issue #1788

Change-Id: Ie3dc2a99a34b3925fecbfdaae7b1e178a0b7a3b6
2019-03-12 21:18:27 +00:00
Aaron Vaage 71fb7a03ec Use Timer/DelayedTick instead of setTimeout
This CL limits the use of |setTimeout| by wrapping it in our own timer
class. The timer class makes it easier to track and cancel time-based
events.

To ensure that|setTimeout| is not used outside of our timer classes, the
conformance rules have been updated to only allow |setTimeout| to be
used by our timer classes.

Since |setTimeout| is very similar to |setInterval|, the conformance
rules for |setInternal| rules were updates to reflect more of the logic
behind why we don't want to use |setTimeout| and |setInterval| directly.

Change-Id: Iff5da32a61b515dd2016837fa74a34c04b6c5fd2
2019-03-12 18:52:32 +00:00
Aaron Vaage 7a56dd1bdc Prevent late-timer-invokes
In our tests, it was possible for a timeout to fire after |clearTimeout|
was called. This CL makes sure that cannot happen by adding an "alive"
flag to each timeout.

To ensure that the change was as well defined as possible, this CL
changes how |shaka.util.Timer| is implemented and updates the API to
better communicate what is happening internally.

Change-Id: I57e3899046a762bff3293b9822a7e8f7ac804042
2019-03-12 18:52:32 +00:00
Aaron Vaage 2c33d519ff Remove Destroyer.with
Replace the last use of |Destroyer.with| in the library. The final use
was in Storage, and this CL replaces that last usage with try-finally.

Close #1516

Change-Id: Ic0946a564b66a48b567ffd6d1cfd4b9ec76fc039
2019-03-08 01:28:55 +00:00
Aaron Vaage f8e0dac6fd Limit scope of |findPeriodContainingVariant|
|findPeriodContainingVariant| was only called from player and was only
called once. This CL moves that method into player and renames it to be
|findPeriodWithVariant_|.

By moving it into this class and making it private, we are now
communicating the limited scope of the method.

Change-Id: Icef14105feb4012e760dc5a8f1bdfb6ad9b04151
2019-02-27 17:35:32 +00:00
Aaron Vaage 954f55e569 Inline |findVariantForTrack|
|findVariantForTrack| was only called from one place in the library and
once in a test. There were ways to get the same behaviour without
needing a utility method in a different class.

The CL inlines the behavior in the player and replaces how the test
handles its logic.

Change-Id: I82e3b7933cc6b4da4b8b2d2da07b405900ecba8b
2019-02-27 16:46:58 +00:00
Aaron Vaage 8bacf168db Create common "find period for time" method
We need to find the current period for a given time in two places:
streaming engine and period observer.

This change takes the method used by streaming engine and the method
used by period observer and merges them into a common method in
|shaka.util.Periods|.

Change-Id: I4f681ceaef38bf2118fb4b87fe4961fddd196707
2019-02-27 00:20:40 +00:00
Aaron Vaage 21de7a2999 Inline |findTextStreamForTrack|
|findTextStreamForTrack| is only called from one place in player. This
change inlines that one call so that we don't need to have a utility
function is another file.

Change-Id: I0930aec3429878cf67cfe5a7e4d52982a9f10327
2019-02-26 23:57:42 +00:00
Aaron Vaage b978ae83b5 Refactor Player to Use Walker
This is the initial integration between the walker and the player. In
order to make this simpler, this keeps all of "load" as one transition
and will slowly break it into multiple parts in later CLs.

Tests that focused on verifying the changes in states were moved from
the unit tests to the integration tests.

As of this CL we model the load graph as:

  Detached -> Attached -> Loaded -> Unloading
      ^         ^                       |
      |         |                       |
      +---------+-----------------------+

With this CL we lose:
  - Interrupting manifest load retries when interrupting a load.
  - Interrupting loading.
  - Pre-initializing media source.

We have immediate plans to add back:
  - Interrupting loading.
  - Pre-initializing media source.

We are still designing how to handle:
  - Interrupting manifest load retries when interrupting a load.

Issue #816
Issue #997
Issue #1570

Change-Id: Ie929621f94c2701f7d4e031b7a31dbd1c74a69c6
2019-02-26 23:42:36 +00:00
Álvaro Velad Galván bbbce06593 Fix stalls on WebOS (#1820)
Disable the StallDetector on WebOS, where we often mistake slowness for stalling.

Fix for #1704
2019-02-26 14:41:33 -08:00
Aaron Vaage 71e8c4936d Refactor getAllVariants
Refactored |StreamUtils.getAllVariants| to get variants from a collection
of periods (rather than a manifest). This allows us to avoid needing to
assert that the manifest exists (when we know it will).

Looking long-term, as part of the refactor the method was moved to a
period-focused utility class. The goal of this is to make it easier to
see what methods may go away when we flatten periods.

Change-Id: I50aa97583892361ee4714a7beaf61e4cd95fb6b4
2019-02-26 17:22:15 +00:00
Jacob Trimble 2d99929400 Add option to disable drift fixing.
The drift fixing allows us to play content that has drift by starting
to play at the last segment in the manifest.  But some live content
specifies content in the future, so we can't just start playing at the
last segment in the manifest.

Fixes #1729

Change-Id: I3095a2d28b34ed93346933f561d77335361f1fae
2019-02-15 22:50:16 +00:00
Aaron Vaage cd8db264be Refactor UI Controls to Use Timer
We have a timer class in shaka.util.Timer to make it easier to
work with repeating time-based events.

This CL changes shaka.ui.Controls to make use of shaka.util.Timer.
To ensure that delayed vs immediate invocations of the events did
not conflict with each other, a new method (tick) was added to
shaka.util.Timer.

|tick| works like |start|, but in an immediate synchronous form.

Change-Id: I50f5ac35d72f58bc55fcc9d20811dbc3dd5ba55c
2019-02-11 14:30:41 -08:00
Aaron Vaage 5c74e418ab Refactor findPeriodContainingStream to be in StreamingEngine
The only use of |findPeriodContainingStream| is in StreamingEngine,
so this CL moves the definition of the method into streaming
engine.

Change-Id: Ice7b8e04bca554bcc8ea0a52bf42f3c048d137ac
2019-02-08 21:13:19 +00:00
Aaron Vaage 43afe3a7c8 Refactor Event Manager To "Release" and not "Destroy"
We often use the IDestroyable interface to provide us with a standardized
way to break internal references and tear-down objects, however many
objects don't need this to be async. Once using IDestroyable, everyone
must assume that you must be async.

This change introduces IReleasable, a sibling to IDestryable, which
provides the |release| method. IReleasable is the synchronous version of
IDestroyable.

This change converts EventManager from IDestroyable to IReleasable as
the first of many conversions.

Change-Id: Ic3e90e594abc1c7326eccbe2521eb71676b74a09
2019-01-24 01:11:38 +00:00
Aaron Vaage 827c00257d Use getSelectable* in get*Tracks
A little while ago we added the methods getSelectableVariants and
getSelectableText to create a way to get the variants and text that
could be selected. They are used with |selectAudioLanguage| and
|selectTextLanguage|.

Since we were using them for selecting variants and text, it would be
a good idea to use them when creating variant and text tracks.

A natural fallout of this change, was that the |getVariantTracks| and
|getTextTracks| methods in |StreamUtils| started to look less-and-less
important. Part of this was due to |ActiveStreamMap| storing actual
streams and not ids. So in this change, you will see that the utils have
gone away. This did require a change in |Storage| but splitting this work
across multiple CLs felt unnecessary.

Change-Id: I2d9b5b0d7b70a6b2c2e7fa51d111030cb43aa68c
2019-01-12 00:03:34 +00:00
Aaron Vaage 0fb5805beb Create Stats Class
This change defines a class to make it easier to track and return our
external stats record.

We have an external stats type used to communicate internal details about
what is happening during playback. The code for creating and updating the
stats was all in Player. With our src= work, only some of this data will
be trackable. To help, this change defines an internal stats class that
handles partial updates and then creates the external stats type when
requested.

This CL moves some complexity out of player, allowing the player to
focus on providing meaning while the Stat's object focuses on tracking
and storing it.

Change-Id: I8c19c98fde26c198566f33f6cbfead2826e39053
2019-01-11 01:23:28 +00:00
Aaron Vaage e610c09ee5 Make Chromecast Tests Use Platforms
We have a utility to test what platform we are running on. It looks
like the chromecast tests were not making use of it.

Change-Id: I0eddbf1fe1aa2c1707947a3c268672a3808ec4dc
2018-12-26 18:30:14 +00:00
Aaron Vaage 9e180712f4 Update Timer to ES6
Updated the shaka.util.Timer class to ES6. In this upgrade, the implementation
was slightly changed to make better use of arrow-functions.

Documentation for the class was expanded on to better document how multiple
calls to start would work. To ensure consistency, both "schedule*" methods were
merged into a single "start" method.

Issue #1157

Change-Id: Iae86cae4d9cb751f0985ef20c371c0023c40bd53
2018-12-21 23:39:54 +00:00
Tomáš Tichý e3739c9495 Add safeSeekOffset to StreamingConfiguration (#1726)
Closes #1723
2018-12-14 11:01:50 -08:00
Tyler Daines 3c8241f3c7 Add license url parsing (#1644)
This adds parsing license URLs to the DASH parser so the URL can be embedded in the manifest.

Fixes #484
2018-12-13 10:58:27 -08:00
Aaron Vaage 4167b1658b Isolate Platform Checks
To make it easier to know where we are check what platform something is
(normally a sign of a work-around), this change isolates the logic to
make the check into functions.

Now looking for uses of |shaka.util.Platform| should show when we are
using platform-specific logic.

Change-Id: Ief49837c503e951f7138ec08a83355fe1c46db88
2018-12-11 05:43:52 +00:00
Jacob Trimble 76f78187b6 Add extended error code for failed license request
Issue #1689

Change-Id: I7d3b4eee487395fdb8c121a4b6acc11ec461f0e3
2018-11-28 23:27:51 +00:00
Sandra Lokshina 6b1ca2d229 Initial release of Shaka Player UI
Other contributors:
 - @joeyparrish
 - @michellezhuogg
 - @TheModMaker
 - @theodab
 - @vaage

Change-Id: If6df33d9ab5035d1ead4402004f7de37ee8470f4
2018-11-16 14:40:37 -08:00
Aaron Vaage b84e74e825 Use Language Terminology In Our Code
Now that we have a formal terminology for how we talk about
language and locales, this change updates our code to utilize
our new vocabulary.

For more information on our terminology, see our "Talking About
Languages" document.

While the expression of the behaviour has changed, the final
observable behaviour should not have changed. The goal of the
"rephrasing" was to build our logic based on the concepts discussed
in our "Talking About Languages" document.

Change-Id: I16c405e3d5a4d1e2275c99d5ec0bbdbaaf8373b9
2018-11-15 20:11:20 +00:00
Joey Parrish 1831ce95e2 Loosen the event listener type
This gets us ready for upcoming changes in the Closure Compiler and
its built-in externs.

Change-Id: I1c22a8ea5b99ef39e3cd5b5ed42ef4373ea3007c
2018-11-12 14:37:58 -08:00
Joey Parrish 3b25bc9bf1 Fix compiler complaints about Iterable|Iterator
Instead of Iterable|Iterator, just use Iterable.  Iterators are, after
all, Iterable themselves.

Caught by a newer compiler/linter that we have not been able to fully
adopt yet.

Change-Id: I85c03a9193e6dc0b315b3bf30e70fe7be7c718df
2018-11-09 14:28:49 -08:00