Commit Graph

1330 Commits

Author SHA1 Message Date
Joey Parrish c0c203cf2d Fix compiler errors found by a newer compiler
Change-Id: I83d81bcdc955331dc7afcc25c45802e77b7b7c02
2019-05-03 18:43:35 +00:00
Sandra Lokshina b0f89441ef Avoid race between UI events and their listeners in UI integration tests
UI events can get in a race with the tests trying to listen to them.
This change creates all the listeners for the UI events first,
before invoking the behavior that should fire them.

Fixes b/131313069
Fixes b/131311532

Change-Id: I43bbeb4d1c6cebe90d92563bec5c62fd84ff259f
2019-05-03 16:10:31 +00:00
Jacob Trimble 9ae237cc3c Fix captions being displayed initially.
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 #1696
Closes #1879

Change-Id: If3a1b9e2889fc0e487da0e7276ca837636bf2e54
2019-05-03 15:58:08 +00:00
Joey Parrish e8a12ed7a5 Fix src= test expectations for Edge & Safari
The test expecatations were not flexible enough to cover differences
in browser implementations.

Issue #816
Issue #997

Change-Id: I918c4d08f5b195046834ee534e84f4b8787487d5
2019-05-02 22:43:32 +00:00
Joey Parrish e246a6cb77 Fix major HLS variant creation bug
The wrong loop index was used, which caused us to create bogus and
non-unique keys for a map, which in turn caused us to skip certain
variants that should have been created.

Fixes #1908

Change-Id: I6475acad16cd76acb81cd562ef033724c7c4ebaf
2019-05-02 22:28:23 +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
Michelle Zhuo 40f9113bb2 Abort requests when network downgrading
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
2019-05-01 20:18:16 +00:00
Theodore Abshire efc2ed3df1 Added new demo page.
This is a complete replacement for the old demo page, made to be more
modern-looking and easier to maintain. It contains new features such as
remembering the URIs you provide for custom assets, and searching through
the default assets by feature.
This demo page is not quite ready for release yet, but it's getting close.

Change-Id: Iad01d1fc02c3cd238d73b9b9e02dbb4301cb6f2a
2019-05-01 19:58:18 +00:00
Joey Parrish c0366cbf14 Replace 'canplaythrough' events with 'canplay'
I recently introduced two uses of the 'canplaythrough' event, but it
was pointed out to me that this implies that content is buffered
enough to avoid ever buffering again until the end.  Instead, we
should simply be using the 'canplay' event, which only implies that we
could start playback.

Change-Id: I3176f8c943ea7bf3f39967a616d9deffd5a4e791
2019-05-01 19:27:05 +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 56a48ec9b9 Fix resolution menu restoration
If the resolution menu sees audio-only content, it should be hidden.
But it should come back as soon as the audio-video content is seen.

This came up during work on #997 and #382

Change-Id: I3297847c905c867bcdd14cf7e525a408890a273a
2019-04-30 12:03:29 -07:00
Joey Parrish 831dfa6168 Consider src= fully loaded only after first frame
This fixes the definition of load() to wait for a frame before
resolving the load() Promise for src= playbacks.  Now methods like
isAudioOnly can be trusted as soon as load() resolves.

This also allows load() to fail for src= playbacks if an error event
fires from the media element.

Issue #816
Issue #997

Change-Id: I0f6120d1334bbebcb78efdbbca65c7981f3ef265
2019-04-30 12:03:01 -07: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
Joey Parrish 91c57e1663 Drop periodreadyforstreaming event
This event was added just for the sake of the UI tests, but the video
element's canplaythrough event works in its place.

Change-Id: I6774fdfdfbd2b197cc93eae743829510b61bb0fa
2019-04-30 17:07:08 +00:00
Sandra Lokshina 7a15c1e94f UI: Dynamic layout construction.
Fixes #1674

Change-Id: I338917bbd43a6ddc837388fdc8beea9e3f7b0778
2019-04-29 21:17:39 +00:00
Joey Parrish 8044961174 Fix src= test failure on Safari
This test was only passing by winning a race before.  Now, it waits on
the appropriate event before testing seekRange.

Fixes b/131604508

Change-Id: I1301719bbccb12895a3402af565bbcf00e88553a
2019-04-29 11:57:10 -07:00
Joey Parrish ea9a7d2b32 Relax restrictions on load state
Allow indirect access to members (such as DRM engine, manifest, etc)
from Player methods as soon as they become available, instead of
waiting until the very end of the load process.

This fixes application access to several methods during the
"manifestparsed" event.  The point of the "manifestparsed" event was
to allow early access to manifest and other metadata before streaming
begins.

This also lays the foundations for improvements in native HLS support
in those same methods, including the ability to get track information.

Issue #382
Issue #997
Fixes b/131604508

Change-Id: Ifee7b06fc2ccdcf5bcdf1c44f2f851d1d7e67fa1
2019-04-29 17:46:12 +00:00
Jacob Trimble fbb558ae36 Ignore duplicate CODECS in HLS.
In HLS, the CODECS attribute may contain duplicate of the same codec
with different profiles.

Closes #1817

Change-Id: I0d59c1ade6c8387a2e6b3ca00c0287e15c943ea3
2019-04-29 16:51:52 +00:00
Sandra Lokshina 3721797cd2 Add abrstatuschanged event.
Add event to notify listeners when abr is being enabled/disabled.
The resolutions menu is listening for variantchanged events to
update itself. It's possible, however, that just enabled abr
will pick the same variant that's currently being played, in
which case, there'll be no variantchanged event. The resolution,
though, still needs to update to reflect the fact that 'Auto'
resolution is selected now and not a specific one.

Adding an event for when the abr state changes helps solve
this.

Fixes b/131099397

Change-Id: I63b218d7423cd0d389dd540c5ed05966e00b861c
2019-04-23 23:55:49 +00:00
Joey Parrish 061350a66d Use mdhd box over mvhd box in StreamGenerator
In our tests, we overwrite timestamps in segments to simulate streams.
In some cases, the init segment contains two different timescales:
one in the mdhd box and one in the mvhd box.  In fact, the mdhd box is
what the browser uses to interpret the tfdt box timestamps.  So the
mdhd box is what we should be reading, not the mvhd box.

This change fixes gaps in the test content generated from the multidrm
clips in our integration tests.  These were not detected before
because the tests in question never played beyond the first segment.
An unintentional change in buffering thresholds (fixed in an earlier
change) allowed us to see these gaps for the first time in our tests.

The buffering threshold change caused a buffering state in the offline
integration tests some small percentage of the time, which caused the
test to never reach its target timestamp.

This fixes the gaps by using the correct timescale to calculate the
timestamps for the tfdt box.  We knew this was an issue in theory as
far back as December 2017, but this was the first time our tests
actually failed because of it.  In most of our content, the two
timescale values match.  In the multidrm content from Axinom, they do
not.

Closes #1206

Change-Id: I863db30a16417a84f8e5df42f4d533b47fa4e7dc
2019-04-22 20:26:53 +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 22d141cd20 Fix PlayRateController stuck in ZERO_RATE state
PlayRateController could get stuck in a state in which playbackRate
would be stuck at 0.  It had to do with the order of modifiers
BUFFERING and ZERO_RATE.  If they occurred in that order (BUFFERING
because of underflow, followed by ZERO_RATE because of a ratechange
event), then ZERO_RATE would stick.

In some cases (~10%) we would see this as a test failure in "Player
plays while changing languages with short Periods".  In the demo app,
it could be easily reproduced by changing resolutions through the UI.

The solution is to remove ZERO_RATE, which doesn't seem to be useful.
Based on the comments in the code, this was to handle seeking in Edge,
where the browser sets playbackRate to 0 during a seek, then restores
it afterward.  If that's the case, just ignore the ratechange event
to 0, and let the browser restore it afterwards.  No need to track
that as far as I can tell.

With ZERO_RATE removed, it doesn't make sense to keep a BUFFERING
constant, so the whole set has been replaced with a boolean.

Broken in Change-Id: Id462cda2c5eb82c3713237341424b91891bd38ea
This bug did not affect any release or beta versions.

Closes #1886
b/130758100

Change-Id: I8c6455c3cdd7c9f353740425fb9337733908b2c9
2019-04-19 17:53:55 +00:00
Sandra Lokshina 48ba5c75c0 Add integration tests for the resolutions menu.
Change-Id: I86e8d675daf48a19b477f8d92e80fc706f189d90
2019-04-18 18:29:37 +00:00
Joey Parrish eff0d47c08 Factor out Tizen workaround
There is a workaround for a Tizen bug which appears in many of our
test suites.  To avoid having to add this to yet more, this change
factors out the workaround such that it applies to all tests.

Change-Id: Ie34c81bfcac94310bf3cd021fd4f2d55905b647a
2019-04-18 09:27:51 -07:00
Joey Parrish 2fa3cf39de Silence errors about deprecated configs
We support these older ones and warn about the deprecation, so do not
also leave the older configs and trigger an error from configure.

Change-Id: I49e25e43ce556ff54ad3c1f1408699ff36c31833
2019-04-17 23:12:35 +00:00
Joey Parrish 3b0ceafdca Deflake offline and player integration tests
This makes some of our integration tests more robust by using
integration test utilities for observing playback status.

b/128923302

Change-Id: Iae5efe55308660bfe1cde9a7f735ee54dbc0b526
2019-04-17 15:26:26 -07:00
Joey Parrish 4343e954aa Fix UI unit test cleanup
The UI unit tests were leaving players undestroyed, which caused
additional failures on Tizen in the src= tests.  This makes some
changes to the UI to allow discovery of the UI through the DOM, which
in turn enables automated (and thorough) cleanup of the UI in our
tests.

b/130554111

Change-Id: I8bfef07f670ce7ec5deafaf19314d7bfd2eb6eed
2019-04-17 21:28:24 +00:00
Joey Parrish 225f31af1f Enable missing offline tests
This file was named incorrectly, and as a consequence, the tests were
not being run.

Change-Id: Iaded01e57660110740fe39610947d84ae570c58a
2019-04-17 09:48:44 -07: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 322876dbb6 Fix src= tests
The integration tests for src= failed almost universally on Tizen, but
a few failed on other platforms, as well.  The issue was the fixed
delays in those tests.  This replaces those fixed delays with an
event-based utility that solved the same problem in other Player
integration tests.

Issue #816
Issue #997

Change-Id: Ib43cbb139ef77be1219e60d1fd5009aa403cc4cb
2019-04-16 20:43:41 +00:00
Joey Parrish a9bb876fbb Drop unused extern
Change-Id: I4e8dc3ce5103e57ce4f908d47c7b47c1a836dd78
2019-04-16 16:24:03 +00:00
Álvaro Velad Galván 65e9957647 Make manifest redirections sticky for updates (#1880)
Closes #1367
2019-04-15 12:15:44 -07:00
Aaron Vaage 39179c7836 Define Player Api src= Tests
Define an initial set of tests to ensure that the public player api
behaves correctly when the player has loaded content with src=.

Issue #816
Issue #997

Change-Id: Ie40bc926d1e56d37318f0ba7711903cdf8e6aa3e
2019-04-11 15:50:19 +00:00
Aaron Vaage 40212ec43e Move Trick Play Out of Video Wrapper
This change moves the trick play logic out of the video wrapper so that
it will be more available to the src= code. By doing this, I hope that
we can make it clearer how we are working with the playback rate and
ensure a tighter integration with it.

Issue #816
Issue #997

Change-Id: Id462cda2c5eb82c3713237341424b91891bd38ea
2019-04-11 15:50:11 +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
Sandra Lokshina 3a2be7fe0a Add UI integration tests for the language menu.
Change-Id: Idbd3b2da9b7a0277798ecb344961aef153ad39f2
2019-04-05 16:44:13 +00: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
Aaron Vaage 4e910bc5ab Poll Current Time In Offline Tests
Before we would just wait X seconds and hope that playback would reach a
certain point. In some cases this would mean waiting 10 seconds.

In this change, those tests are changed to poll the media element's
current time. To allow context-specific timeouts, we include a timeout
time with each call. This equates to "we expect to see playback pass
time=X within Y real seconds".

Change-Id: I8293c7dd5fdccf2c1d910fb48e037c93a25e3199
2019-04-01 22:10:29 +00:00
Aaron Vaage 0298bc1137 Remove Unused Access Suppression Tag
There was an access suppression tag in the offline tests, however there
was not accesses to suppress. Removing the tag did not yield any
compiler errors or runtime errors.

Change-Id: I4a6d4a5611791427d752b1fd2157e9aa7ae35ec1
2019-04-01 16:19:31 +00:00
Michelle Zhuo 59966e2bb8 Show picture-in-picture btn only when the content has video
1. When playing an audio-only asset, the Picture-in-Picture button on
the UI shows up. Pressing the button, however, results in an error.
We should only display the Picture-in-Picture button when the content
has video.
2. When it's in the picture-in-picture mode and an audio only content is
loaded, both the main window and the picture-in-picture window get
stuck.
We should exit the picture-in-picture window when the audio only content
is loaded.

Closes #1849

Change-Id: I37bc82677108828a05ba26ad8aa081b90e137548
2019-03-29 15:36:24 -07:00
Aaron Vaage 2d9c6d62a6 Make Buffering Observer the Authority on "Is Buffering"
Previously there was a boolean that held the "is buffering" state,
however with the buffering observer directly assessable, we can just ask
it if we have enough content.

Change-Id: Ic5adb2b54fc7a7f6d732520ac257bf4ca1407287
2019-03-29 19:43:33 +00:00
Aaron Vaage 1284dd484b Make Buffering Observer A Top-Level Component
Before the buffering observer was a playhead observer, but with
supporting src=, changing how we interact with the buffering observer
was made easier if it was handled as a top-level component.

This meant moving it off the playhead observer interface and create its
own timer in player.

Coming off the playehead observer interface, the buffering observer did
not need to use callbacks, which made it easier to use. This will also
allow us to use it as the single source of "is buffering" in a later
change.

Change-Id: I8cad9bfde3309de7c2b8301b90aa8c40b6e4d247
2019-03-29 19:43:31 +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 1776ea6e55 Rename StreamingEngine.init to StreamingEngine.start
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
2019-03-29 00:25:56 +00: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 d9acac7f58 Return to Attach After Error
If the player sees an error and we are attached to a media element, we
should return to the attach state because we assume that the media
element is still usable after an error.

If we keep throwing away the media element, it means that after each
error, an app would need to re-attach to the media element. This will
break backwards-compatibility.

This CL restores backwards-compatibility by resetting the walker to be
at the attached-state if it has a media element.

Issue #816
Issue #997
Close #1843

Change-Id: Idaa70d9fcc01cd9af06ff8967812a4051f8c6e53
2019-03-21 15:58:39 +00:00