It appears that the problems we previously had with TS content
on Safari have been fixed. We no longer need the workaround where
we transmuxed TS on that platform.
Add support for HLS com.apple.streamingkeydelivery through MSE/EME implementation.
Close#3346
## Tests
Tested on:
- Mac 11.6 Safari 15.2
- iOS 15.2 Safari 15.2
- Mac 11.6 Chrome 96 (for potential regressions on Widevine keySystem)
| Mode | DRM API | TS | CMAF (mono-key and multi-keys)
|---|---|---|---|
| file | EME | ✅ | ✅ |
| file | Legacy-prefixed | ✅ | ✅ |
| media-source | EME | **mux-js**: `encrypted` never fired<br />**real MSE**: `encrypted` event received, but with incorrect `sinf` initData (*1) | ✅ |
| media-source | Legacy-prefixed | **mux-js**: `webkitneedkey` never fired<br/>**real MSE**: TBD | 🔴 fails to append media segment to SourceBuffer (init segment ok) `(video:4) – "failed fetch and append: code=3015"` |
## Support table
| Mode | DRM API | TS | CMAF (mono-key and multi-keys)
|---|---|---|---|
| file | EME | ✅ | ✅ |
| file | Legacy-prefixed | ✅ | ✅ |
| media-source | EME | 🚫 `4040: HLS_MSE_ENCRYPTED_MP2T_NOT_SUPPORTED` | ✅ |
| media-source | Legacy-prefixed | 🚫 `4041: HLS_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED` |🚫 `4041: HLS_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED` |
⚠️ Use EME APIs with multi-keys CMAF makes the video stalling with the audio continuing alone after a short time (~3 minutes in the stream, could be shorter, could be longer). Didn't find an explanation to that yet. I've observed the same behaviour with hls.js code so I don't think this is a player issue.
Revert "fix: Work around override of MediaCapabilities polyfill in Apple browsers (#3668)"
This reverts commit 31c0cd4b8c.
Fixes#3843 (usage of Shaka without polyfills)
Re-opens #3530 (MediaCapabilities polyfill not working on Safari)
Change-Id: Ib5aff1b38759e1a39200332f3f07d3d6bd3bd2e1
Previously, many events were being defined with a data dictionary
that used variable-type keys (e.g. {key: value}). This worked fine
in uncompiled mode, but in compiled mode it lead to those properties
being obfuscated.
This changes the FakeEvent constructor to take a map rather than an
object, so the compiler will force the keys to be strings.
Closes#3710
Change-Id: I67b1a391540a5ee21f0aaf940ae054d26f4c10a4
This change allows polyfills to be installed individually e.g. shaka.polyfill.MediaCapabilities.install() instead of shaka.polyfill.installAll()
Related to #2625
In iOS, there is no support for MediaSource, and we should have 'file' as the type of the MediaiDecodingConfig, to check whether the content is supported or not. We should only require MediaSource support in the polyfill when the type of MediaiDecodingConfig is 'media-source'.
Issue: #3530 .
All the attributes listed in the polyfill already begin with "aria".
However, to add extra protection against the possibility of XSS
attacks through one of the polyfill's internal methods, this enforces
"aria-" at the beginning of the snake-case attribute name, even if
somehow "aria" were missing from the input JavaScript attribute name.
This change is based on the outcome of an internal security review.
Change-Id: Iec8a9cbd5f88fdf4b87da3e5cd058c4ffb69c3ff
The MediaCapabilities polyfill caused compiler errors in stricter
environments, in which navigator.mediaCapabilities was marked as
const. This suppresses constness errors from the compiler in the
install method of the polyfill.
Change-Id: Idb47a473335c886a2a7b3c77b84ce8f51fce4114
Chromecast firmware now includes limited support for
mediaCapabilities, but we still need to install the polyfill for now.
The platform will let us overwrite the decodingInfo method, but not
the mediaCapabilities object itself. This fixes the polyfill to
handle this situation.
Change-Id: Ia770457ad8465ec1caf4420ef757303adbe55ce5
The ARIAMixin interface mixin lets users apply ARIA attributes to
DOM elements without having to rely on setAttribute and getAttribute.
It is one of our goals to switch to using that interface.
Unfortunately, it is not implemented on Firefox, so a polyfill is
necessary for that platform, before we can start using it.
Issue #3378
Change-Id: Ia878900d75c7c2c04613360baacb4524774ac746
MediaCapabilities supports 'vp09...' codecs, but not 'vp9'. Translate
vp9 codec strings into 'vp09...', to allow such content to play with
mediaCapabilities enabled.
Change-Id: Iff7ddae379efb8a9f0766c89a62b85a325f81e93
Since we got some unexpected decodingInfo results from MediaCapabilities
on Chromecast, we should fall back to MediaSource.isTypeSupported() on
Chromecast.
Issue #1391
Change-Id: I4947ec78624e98c7039df64ad691e14ece2588e0
In DrmEngine, previously we created MediaKeySystemConfiguration for the
variants, and called navigator.requestMediaKeySystemAccess() to get the
mediaKeySystemAccess, and set up MediaKeys.
Now we can use the mediaKeySystemAccess from the decodingInfo results of
the variants directly to set up MediaKeys.
Issue #1391
Change-Id: Id93a5e2fed7f6827317ae11644967185fc0cffbd
In StreamUtils, add a MediaCapabilitiesKeySystemConfiguration
for each key system for the encrypted variant passed to the
decodingInfo API, to get the mediaKeySystemAccess as a part of
the decodingInfo results.
We create a list of mediaDecodingConfigurations for each variant,
and call decodingInfo() with each mediaDecodingConfiguration to
get the mediaKeySystemAccess.
Eventually, we'll use the mediaKeySystemAccess from the
decodingInfo results to replace the call of
navigator.requestMediaKeySystemAccess() in DrmEngine. That will be
in the next CL.
Also, adding MediaCapabilties polyfill with mediaKeysSystemAccess.
Issue #1391
Change-Id: Ied4a27dd8a1ade43209bcf07f21f0c9b31c2693c
If navigator.mediaCapabilties is not supported by the browser, use
MediaSource.isTypeSupported to check if the stream is supported.
Issue #1391
Change-Id: Iee0c7e339add2a07028ed14a03df14e4d36a203e
@avelad reported that PR #3021 caused a regression. Rather than
revert the entire thing, we are disabling one part of that change to
make it easier to re-enable once the issue is fixed. We will also
reopen issue #2999 until this is resolved.
Change-Id: I65d93da903d90668bb19e5248658eb458e8bb5c4
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
Some smart TVs only recognize the older "vp9" codec string, but not
the newer "vp09...." string. This change recognizes those platforms
and patches them so that newer, compliant content can still be
recognized as playable on those platforms.
Closes#2870
Change-Id: I6026ecea4f3176303237c7fddaf26cd150c7751d
The IndexedDB polyfill was preventing Cast apps from using IndexedDB
outside of Shaka Player. Instead of breaking IDB, we should just
directly disallow offline storage on the Cast platform.
Fixes#2850
b/168565999
Change-Id: Ie504531c412723cc0f93530b2e34000873bfaf32
Instead of assuming that hevc1.2 indicates HDR, we should get HDR
profile information from DASH manifests. This removes the assumption
in the Cast isTypeSupported polyfill.
Issue #2813
Change-Id: Ieb40a06c78c99b6975082eaffb23d5e09a5f2464
The polyfill assigns a static method over window.VTTCue, which is then
called with "new". This will not work on Edge in uncompiled mode,
since the method is not an old-style "function".
To fix this, we wrap the chosen static method into a "function".
Change-Id: I9b5687e39b3af1bd160e4db4595de06720564a1d
There are some platforms (e.g. iPad) which can be rotated,
but do not support the screen.orientation API. This is relevant
because iPad now supports requestFullscreen, which it did not
before.
Found while investigating #2653
Change-Id: Iacc93433aa1fb50a25d968203dc9fd4f7f16b4ae
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
@exportInterface is used by the extern generator, but ignored by the
compiler. @export should be used for shaka.polyfill.
Closes#2549 .
Change-Id: I400db152ec8ca222a45a598ab58ddfbe44552443
Also add a note to the MSE polyfill about restrictions being applied
in Player as well. We used to restrict Safari versions only in the
polyfill, and I had forgotten about the other version check.
Closes#2548
Change-Id: I4d2f319939c3a079e7f0ec7134876d91fc425bf4
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
The latest Closure Compiler initially complained about "initData" not
being a known property of "Event". Correcting the type to
MediaEncryptedEvent exposed a potential bug, which is that we were
assigning Uint8Array in some cases instead of the correct ArrayBuffer.
This fixes both the type of the event and converts the Uint8Arrays to
ArrayBuffers.
This also works around a complaint about "code" on "Error". We use
"Error" objects as look-alikes for DOMException because there is no
exposed constructor for DOMExceptions. To satisfy the compiler, we
use square brackets now to set the "code" field on these DOMException
look-alikes.
Finally, this removes the "method" field on certain Errors in the
WebKit EME polyfill. These must have been leftover from some
debugging, and are not used at all.
Issue #2528
Change-Id: I32c4617b14a30c412d5bc532ec17a46fdc1fea1a