Commit Graph

127 Commits

Author SHA1 Message Date
Muhammad Haris d383047de1 fix(CEA): Fix missing captions when switching streams (#2672)
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
2020-06-23 16:40:35 -07:00
Sandra Lokshina 00942069d7 Fire a shaka.Player.Metadata event on detecting ID3 metadata.
Issue #2592.

Change-Id: Ia2a98668a5971071adfa0ee4d987337ea9c10c59
2020-06-22 18:18:36 +00:00
Joey Parrish f539147d48 fix: Correct license headers in compiled output
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
2020-06-09 16:05:09 -07:00
Sandra Lokshina 1fc19510ec Hook up ID3 tag parsing information from mux.js
Issue #2592.

Change-Id: I0b17977b88cf37189d7611254ce14171ba52c54f
2020-06-04 17:12:06 +00:00
Joey Parrish 11f3347a48 Fix static method aliases
We used to alias static utility methods by assigning the method itself
to a local variable.  This is not allowed by the new Closure Compiler
release that we are adopting, and for good reason.

The old compiler did not understand the use of "this" in static
methods, but the new one does.  And it turns out that when we start
using "this" in static methods (see #2532), aliasing the method itself
can break everything.

When you refer to "this" in a static method, it refers to the class.
This is really useful in utility classes that have private static
methods they use to perform common tasks.  However, just as it ruins
the value of "this" to alias an instance method, the same is true of
an ES6 class's static method.

The fix is to always alias the class instead of the method.  The new
compiler will simply not let us get away with the old way any more, so
regressions after this are unlikely.

Issue #2528 (compiler upgrade)
Issue #2532 (static "this")

Change-Id: Id800d466e639c7cbcf4aa6fbb05114c772a2229f
2020-04-30 19:28:53 +00:00
Joey Parrish 07335d79f6 Fix missing or bad type info
In many places, the implicit type info was insufficient.  For example,
document.createElement returns Element, but the actual return is
always a subclass of Element.  In many cases, we need the compiler to
know that a specific subclass is in use, so that it can correctly
check our use of subclass-specific properties.  Another common pattern
is confusion between Node and Element (which is a subclass of Node).

Almost all of the changes in the demo and UI are Element-related.

In some places, we referred to HTMLMediaElement, used in the Player
API, instead of the more specific HTMLVideoElement in use in our demo.
Since the demo uses video-specific properties, we must use the more
specific type.

Another case is the use of document.createEvent, which returns Event
according to the compiler, but in reality always returns a subclass,
like CustomEvent.

In one case in NetworkingEngine, correcting the type of an
AbortableOperation led to the discovery that we had been incorrectly
accessing a private method of that type.

In goog.Uri, there were several instances of "*" for a type, which the
newer compiler won't accept.  These have all been corrected.

Finally, in some places, we had the wrong nullability on a type.

These were all caught by a compiler upgrade.

Issue #2528

Change-Id: I7f2d070e3da32fe9ff5f444315649f3cbdb5a4a5
2020-04-28 16:51:20 -07:00
Jacob Trimble 78c13fe5cb Add additional logs for buffering and state change.
Issue #2291

Change-Id: Iffb80f9ae1844d2fe5a441bd810faa328f66e357
2020-02-12 23:00:21 +00:00
Álvaro Velad Galván 956eaf315d Add AV1 check and more file extensions for src mode (#2280) 2019-12-05 14:24:15 -08:00
Joey Parrish 64896d70b0 Use shorter license header
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
2019-11-22 18:18:36 +00:00
Jacob Trimble 450d8a60c4 Fix check for captions in appendBuffer.
An empty list is still truthy, so the if statement should check for a
non-empty list instead.  This ensures we don't try to append captions
when we play audio-only content.

Fixes #2187

Change-Id: I589a5508878ab28ad1ac69211f331ea829fa8b28
2019-10-28 20:52:09 +00:00
Jacob Trimble 50938a02a4 Remove throws directives.
These are intermittently used and cannot be verified.  Most of our
methods can throw a shaka.util.Error, so having it doesn't really add
anything.  Plus, if we change a function to throw, we'd need to update
all their callers to ensure they have an accurate description of what
they throw; otherwise we can't trust the directive.

Change-Id: I520bd0fc4c33443e967bf5b103ca5aa9e3274884
2019-08-28 17:00:04 +00:00
Jacob Trimble 17684c6c35 Refactor "try" blocks in MediaSourceEngine.
- Avoid nested try block in enqueueBlockingOperation_.
- Simplify running next operation.
  - Ensure QuotaExceeded error is handled correctly.
- Use "throw" instead of Promise.reject.

Change-Id: I0d9d95290baafedd6bbadc158ba826836c9f7d10
2019-08-28 16:54:36 +00:00
Jacob Trimble 596c80a949 Refactor handling of ArrayBuffer.
This changes the network API to use BufferSource instead of ArrayBuffer,
which allows plugins to return a "view" on a buffer instead of the
whole buffer.  This also adds some utilities for changing between
views and buffers.

Lastly this forbids the use of the "buffer" property of TypedArrays
since it doesn't work with partial "views".  This audits and fixes the
usages of the "buffer" property to ensure correct usage.

It should be noted that both MSE and EME accept a BufferSource as input,
so we don't need to convert a "view" into an ArrayBuffer before passing
to it.

Change-Id: Iaa417773f8ce5304424e43c7372ce10ebf540d2a
2019-08-20 20:17:33 +00:00
Jacob Trimble 32e7665fc1 Updated workaround in MediaSourceEngine.
Chrome has fixed their behavior involving endOfStream(), but both Tizen
and IE11 have the same broken behavior.  Unfortunately these platforms
will likely never be fixed, so we need to keep this forever.

Fixes #1357

Change-Id: Id540170f8c8cb6e0ddf3a30bde5035016fa61df1
2019-08-16 18:35:38 +00:00
Sandra Lokshina 639005b124 Don't call mediaSource.endOfStream() more than once.
MediaSource throws if endOfStream() is called when
its readyState is equal to 'ended.' This happens if
endOfStream() has already been called.
This change ensures that we don't try to call endOfStream
on the MediaSource that has already marked as 'ended.'

Closes #2050.

Change-Id: I2672b297f0ebb7fd67afcf72ee52df6d5bacf761
2019-07-23 13:01:54 -07:00
Jacob Trimble 5c35108cb8 Avoid integer for loops.
Issue #1518

Change-Id: I3ba3cb6a439264e823022b2a64e7cdbd265494c7
2019-07-09 17:11:49 +00:00
Jacob Trimble f6d0f15fa6 Refactor handling of destroy().
This changes several classes to use the Destroyer class to handle
destroy().  This also changes the behavior to not ignore destruction
and instead throw a new error.  This is more clear for callers and
ensures we propagate errors.

Change-Id: I756c085639558509c22e5c43d69ddf4acd28d46f
2019-06-19 20:39:20 +00:00
Jacob Trimble 52522c7dca Fix cases where errors weren't propagated.
This propagates errors in several places and fixes waiting for some
async calls.

Change-Id: Idf4519b473538c1fa00bfe63e634194610ba29f2
2019-06-19 20:35:30 +00:00
Jacob Trimble 1d33b748d8 Fix recent MediaSourceEngine test failure.
A recent refactoring caused a test failure on Chrome due to a Promise
getting rejected without a "catch" block and getting an unexpected
rejection error.  This adds the expectation first so we don't get that
error.

This also removes the empty "catch" blocks since we use async/await,
which introduces another Promise, so the "catch" block won't suppress
the unhandled rejections like we want.

Change-Id: Ib217b4b374668d800a0eeb1a9b8069269bccf261
2019-06-11 10:32:16 -07:00
Michelle Zhuo f8f384902e Convert MediaSourceEngine to ES6
Issue #1157

Change-Id: Id9757ac39c37a149630c87bceacb11cdd2144f04
2019-06-10 22:19:14 +00:00
Theodore Abshire dc04edfa51 Use correct TextDisplayer in demo.
This sets a TextDisplayer to the native text displayer if native
controls were desired, or a custom UI text displayer otherwise.
This required adding methods to the player to switch out the current
text displayer if a new factory is provided, and a method to streaming
engine to reload the current text stream.

Change-Id: I85595e9ac9db0b60464ee7f20fa35855efb26424
2019-05-14 12:53:16 -07:00
Jacob Trimble d5780d401b Fix line length issues for indent fix.
Change-Id: I87d75fd88000f8f9bff7b9f1bf5667ba28f6dd60
2019-05-13 22:31:20 +00:00
Jacob Trimble f130dffcef Enable eslint indentation rule.
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
2019-05-13 22:31:09 +00:00
Jacob Trimble 0dd64074b9 Only allow one statement per line.
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
2019-05-13 22:11:50 +00:00
Jacob Trimble 47daf49f31 Use arrow functions for callbacks.
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
2019-05-09 16:40:46 +00:00
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 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 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 22aee05d49 Have MediaSourceEngine fill in buffering info
To make the getBufferedInfo method simpler for when we have three
different ways of responding (not loaded, loaded with media source, and
loaded with src=), this changes media source to fill-in a buffered info
object rather than return one.

Issue #816
Issue #997

Change-Id: If9e4558ca324808a1b94e3c235f4bfb42a5df8ce
2019-03-29 20:06:18 +00:00
Kevin Scroggins 9c224c1abc Fix React Native createObjectURL polyfill incompatibility (#1845)
React Native introduces its own polyfill for window.URL.createObjectURL which is not compatible with Shaka. Encapsulating a reference to the original function inside of the MediaSourceEngine circumvents this issue.

Closes #1842
2019-03-20 08:37:13 +05:30
Joey Parrish 73c2ac72d3 Fix CEA timestamps with presentationTimeOffset
When CEA captions are extracted from video segments, the
presentationTimeOffset of the video segment should be applied to the
extracted captions, as well.

Fixes b/70902665

Change-Id: I446333a14b8b6374786ab594a579b6e18bc73ac1
2019-02-13 10:45:34 -08:00
Aaron Vaage 0f0a3515b6 Refactor media source engine to take text displayer in constructor
Before, media source engine could be created with no text displayer.
However, player would always create media source engine with a
text displayer.

Just like with closed captions, this appeared to be a good time
to change it to be passed in the constructor and have media source
engine own it.

This now means that media source engine is responsible for destroying
it - lessening player's responsibilities.

Change-Id: I71cd1c28a3c22d3c765a3892fe74ae3f9abd1914
2019-01-24 01:12:37 +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 58d4163401 Add Important Note about Media Source Engine Construction
When we create a media source engine instance, we pass in
a closed captions parser. However a key subtlety was missing
from the parameter description; media source engine is taking
ownership over the parser.

Change-Id: Id49483ccac4cc1812c31ead9e82c09390ce2ed37
2019-01-04 17:18:31 +00:00
Aaron Vaage f09d5d7a6c Pass ClosedCaptionParser into MediaSourceEngine
Instead of requiring media source engine to create its own closed
caption parser and then allow tests to override it, have it be
passed into the constructor.

This allows us to easily use the fake one in all our tests and
removes the need for a test only method on media source engine.

Change-Id: Ia1d4f0bb988dca30699b30ccaf4522126f357f90
2018-12-07 00:10:13 +00:00
Michelle Zhuo bcd10c272e Refactor for Caption Parser
Similar to Transmuxer, adding a Caption Parser class as a wrapper of
mux.js's Caption Parser, and move all relevant operations from Media
Source Engine to Caption Parser wrapper class.

Issue: #1404

Change-Id: Iaafa22a963b53315e1f7ae52a5fe17a4cd3f2bde
2018-12-06 01:26:52 +00:00
Joey Parrish 7991b2a86b Update docs for setStreamProperties
This clarifies how the MediaSource append window works.

Change-Id: Ice5f095298f47af6ce5967d17e47b16b4b58787d
2018-11-30 18:48:55 +00:00
Michelle Zhuo 1afceadc9c Refactor Closed Captions Support for HLS
Refactor the closed captions support for HLS, using the same approach as
the closed captions support for Dash.
If closed captions are signaled in the manifest, player will create a
text stream for to represent the closed captions, and text engine will
store and append them. We don't need to set 'useEmbeddedText' value for
closed captions any longer.

Issue #1404

Change-Id: I9a5bf4df7e29d6e6982f29fd5e2df07bc78071d7
2018-11-27 20:59:52 +00:00
Michelle Zhuo dbdd39886b Small refactor for CEA closed captions for Dash
Removing a few hacks from player and streaming engine, so that now
closed captions streams are treated almost the same way as usual text streams.
Fixed the issue where toggling the closed captions doesn't work.
Fixed the delay of showing closed captions when we seek to a buffered
stream.

Issue #1404

Change-Id: I28a739f3033f30b53b3adf8fa1a181e3d4592f6f
2018-11-09 00:36:56 +00:00
Michelle Zhuo b9a806d071 Add test cases for CEA closed captions
Issue #1404

Change-Id: I35e679ef985ac5cef1f8d8673192845cae29b114
2018-11-08 15:13:51 -08:00
Michelle Zhuo 19a38ed6b5 CEA closed captions for Dash
Adding support for CEA closed captions embedded in video streams for
Dash.
1. Dash parser reads and parses closed captions' channel and language
information.
2. Player creates text streams for the closed captions.
3. Media Source Engine calls mux.js Caption Parser API to get the closed
captions embedded in the video streams.
4. Text Engine stores the closed captions, and text displayer shows the
captions.

TODO:
1. Add test cases, will send out another CL.
2. Change closed captions support for hls to the similar way we handle
dash closed captions, will send out another CL.
3. Handle dash content that's missing language indication from the manifest.

Issue: #1404
Change-Id: Ibae8f69623c13561415ec860107d7f5bc86e19e9
2018-11-06 09:53:18 -08:00
Jacob Trimble 443269a347 Fix MediaSource tear down race.
First, we cannot destroy the EventListener in MediaSourceEngine until
the in-progress tasks are done so we can get the 'updateend' event.
Second, we shouldn't detach MediaSource until the tasks are done to
ensure the media stack is still working.

As part of that, we need to delay the destruction of DrmEngine to
ensure it happens after MediaSourceEngine.

Fixes: 118148113
Change-Id: I2c77d72556eb0b1b6ef4a3f7a092f182b94e9156
2018-10-23 16:04:31 +00:00
Joey Parrish 45e16bf278 Fix exception when destroying MediaSourceEngine twice
A new WIP test accidentally destroyed MediaSourceEngine twice, which
should not result in an exception.  This fixes the exception.

Change-Id: I199e3072a3e7994083844c2013ac9c8f76406a63
2018-10-11 21:10:20 +00:00
Aaron Vaage 9f09df3000 Initialize MediaSourceEngine with Map
Changed MediaSourceEngine to be intialized with a map rather
than an Object.

Change-Id: I68cb26e7591cac8758abdaac0bffdf1901e0767e
2018-09-18 20:16:13 +00:00
Joey Parrish 7091275cbf Replace indexOf with includes, startsWith
This replaces almost every instance of indexOf on both String and
Array.  There are very few places where we really wanted an index.
Mostly, indexOf was used to check for inclusion.

Change-Id: I08e299768b6ffdb4bfc30b39b5d82a058c6d1b56
2018-09-14 19:10:56 +00:00
Joey Parrish 9cce246325 Fix TextEngine buffered range calculations
This reverts commit c38d4dd8d3, which
actually broke text range calculations in v2.3.10, and v2.4.2-v2.4.4.
The original commit was meant to account for the period start, but
resulted in a double-accounting of presentationTimeOffset.

The start and ends times passed into TextEngine's appendBuffer were
period-relative, so timestampOffset had already been applied.  To
avoid further confusion and to fix the original issue the reverted
commit tried to address, these have been changed to
presentation-relative timestamps.  Now the period start and all
offsets have been accounted for before the metadata reaches
MediaSourceEngine and TextEngine.

The tests added in the bad commit have been modified to test for the
opposite: that we do not erroneously account for timestamp offset when
calculating the buffered ranges for text.

Closes #1562

Change-Id: I9fa7a3f59906c4f3e623f411e48551f86f5c2ff7
2018-08-28 17:21:39 +00:00
Michelle Zhuo 1b150eef04 Don't clear buffer with a small gap between playhead and buffer start
When the video is looping and there's a small gap between the playhead
and buffer start, we should jump the gap instead of clear the buffer and
download it again later.

Change-Id: Ieead1462ac8c1cfcc957c391a61890396b870d40
Closes: #1459.
2018-07-23 21:47:50 +00:00
Joey Parrish fd0449d8f7 Re-enable some disabled style rules
This re-enables the following style rules:
  - "block-spacing"
  - "brace-style"
  - "comma-dangle"
  - "comma-spacing"
  - "new-cap"
  - "no-multi-spaces"
  - "no-multiple-empty-lines"
  - "one-var"
  - "padded-blocks"
  - "prefer-rest-params"

Change-Id: I15d616e8d5b88b273ded6128b4f9ad86bdb26bd1
2018-07-09 19:44:56 +00:00
Jacob Trimble 759eef9685 Change goo.gl links to bit.ly.
https://goo.gl is being turned-down, so we can't use it for new URLS.
So we have consistent short links, this converts them to be
https://bit.ly.

Change-Id: I07a86cba807b67157664893341f648023918d0de
2018-06-22 20:20:00 +00:00
Joey Parrish 6f6c2edb1b Add new-style vp09 codec probe, drop av1
MediaCapabilities only recognized the new vp09.... strings, even for
WebM.  So we should start checking for that when we look at browser
codec support.

The AV1 codec string has not been finalized as far as I know, so that
should not be in there yet.

Change-Id: Ia7cb51bf712d8875ff439a9574a181da13acee27
2018-06-01 21:07:58 +00:00