Caches the results of MediaSource.isTypeSupported, which is slow on some platforms, to reduce the
number of calls needed. This is especially helpful on manifests with many similar variants (multiple languages, etc).
Data collected from 2 months of practical testing shows that this helps reduce the start lag by 40% on Chromecast, 15% on WebOS, and 12% on Tizen.
See https://github.com/shaka-project/shaka-player/issues/4726 for more
context.
This allows Cast devices to properly filter stream variants with a
resolution surpassing that of the device's capabilities.
We place the fix in the `MediaCapabilities` polyfill since it's intended
to be the right way to check for anything related to platform support.
HDR support checks will require `eotf=smpte2048`, as indicated in
https://github.com/shaka-project/shaka-player/issues/2813#issue-684874730.
Specifically, a `{hev|hvc}1.2` profile is only an *indication* of an HDR
transfer function, but *may* be a non-HDR 10-bit color stream.
In Cast, the platform can distinguish between the two by explicitly
providing the transfer function; it uses `smpte2048` (`"PQ"`) because
this is the "basis of HDR video formats..."
(https://en.wikipedia.org/wiki/Perceptual_quantizer).
This PR caches the result of `requestMediaKeySystemAccess` saving time
on subsequent calls.
It also makes the calls to `decodingInfo` synchronous. The reason for
this, is the result of testing on multiple devices that the behaviour of
`requestMediaKeySystemAccess` appears to be synchronous, making this
synchronous can save over a second on older TVs.
Closes#4574
We started using AbortController in HlsParser in 777c27ee, but that
change was made while the Tizen TV in our lab was offline. This restores
functionality to Tizen.
This polyfill uses getters, a feature of ES6 that the compiler won't
transpile into ES3, so this also changes the output language to ES5.
This should not be an issue, since ES5 has been well supported in all
browsers since IE10.
An internal build system failed to compile v4.3.0 due to the use of
static "this". This change fixes it.
Unfortunately, we are already running the latest public compiler
release, so there is no way we could have caught this on GitHub.
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