Skip to content

Commit

Permalink
fix(Cast): Incorrect detection of MediaCapabilities on Chromecast (#6656
Browse files Browse the repository at this point in the history
)

Fixes #5776
  • Loading branch information
avelad authored and joeyparrish committed May 31, 2024
1 parent 45d8a34 commit 7681d4f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 12 deletions.
12 changes: 7 additions & 5 deletions lib/polyfill/media_capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ shaka.polyfill.MediaCapabilities = class {
* @export
*/
static install() {
// Since MediaCapabilities implementation is buggy on the Chromecast
// platform (see https://github.com/shaka-project/shaka-player/issues/4569),
// we should always install polyfills on all Chromecast models.
// TODO: re-evaluate MediaCapabilities in the future versions of Chromecast.
// We can enable MediaCapabilities in Android and Fuchsia devices, but not
// in Linux devices because the implementation is buggy.
// Since MediaCapabilities implementation is buggy in Apple browsers, we
// should always install polyfill for Apple browsers.
// See: https://github.com/shaka-project/shaka-player/issues/3530
Expand All @@ -50,12 +48,16 @@ shaka.polyfill.MediaCapabilities = class {
// Since MediaCapabilities implementation is buggy in Hisense browsers, we
// should always install polyfill for Hisense browsers.
let canUseNativeMCap = true;
if (shaka.util.Platform.isChromecast() &&
!shaka.util.Platform.isAndroidCastDevice() &&
!shaka.util.Platform.isFuchsiaCastDevice()) {
canUseNativeMCap = false;
}
if (shaka.util.Platform.isApple() ||
shaka.util.Platform.isPS5() ||
shaka.util.Platform.isPS4() ||
shaka.util.Platform.isWebOS() ||
shaka.util.Platform.isTizen() ||
shaka.util.Platform.isChromecast() ||
shaka.util.Platform.isEOS() ||
shaka.util.Platform.isHisense()) {
canUseNativeMCap = false;
Expand Down
42 changes: 41 additions & 1 deletion lib/util/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ shaka.util.Platform = class {
return Platform.isChromecast() && Platform.isAndroid();
}

/**
* Check if the current platform is a Google Chromecast with Fuchsia
* (i.e. Google Nest Hub).
*
* @return {boolean}
*/
static isFuchsiaCastDevice() {
const Platform = shaka.util.Platform;
return Platform.isChromecast() && Platform.isFuchsia();
}

/**
* Returns a major version number for Chrome, or Chromium-based browsers.
*
Expand Down Expand Up @@ -458,6 +469,34 @@ shaka.util.Platform = class {
return shaka.util.Platform.userAgentContains_('Android');
}

/**
* Return true if the platform is a Fuchsia, regardless of the browser.
*
* @return {boolean}
*/
static isFuchsia() {
return shaka.util.Platform.userAgentContains_('Fuchsia');
}

/**
* Return true if the platform is controlled by a remote control.
*
* @return {boolean}
*/
static isSmartTV() {
const Platform = shaka.util.Platform;
if (Platform.isTizen() || Platform.isWebOS() ||
Platform.isXboxOne() || Platform.isPS4() ||
Platform.isPS5() || Platform.isAmazonFireTV() ||
Platform.isEOS() || Platform.isAPL() ||
Platform.isVirginMedia() || Platform.isOrange() ||
Platform.isWPE() || Platform.isChromecast() ||
Platform.isHisense()) {
return true;
}
return false;
}

/**
* Check if the user agent contains a key. This is the best way we know of
* right now to detect platforms. If there is a better way, please send a
Expand Down Expand Up @@ -554,7 +593,8 @@ shaka.util.Platform = class {
return false;
}
// Older chromecasts without GoogleTV seem to not support SMOOTH properly.
if (Platform.isChromecast() && !Platform.isAndroidCastDevice()) {
if (Platform.isChromecast() && !Platform.isAndroidCastDevice() &&
!Platform.isFuchsiaCastDevice()) {
return false;
}
// See: https://chromium-review.googlesource.com/c/chromium/src/+/4577759
Expand Down
12 changes: 6 additions & 6 deletions test/polyfill/media_capabilities_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ describe('MediaCapabilities', () => {
await navigator.mediaCapabilities.decodingInfo(mockDecodingConfig);

expect(mockCanDisplayType).not.toHaveBeenCalled();
// 1 (during install()) +
// 3 (during install()) +
// 1 (for video config check) +
// 1 (for audio config check).
expect(isChromecastSpy).toHaveBeenCalledTimes(3);
expect(isChromecastSpy).toHaveBeenCalledTimes(5);
// 1 (fallback in canCastDisplayType()) +
// 1 (mockDecodingConfig.audio).
expect(supportMap.has(mockDecodingConfig.video.contentType))
Expand All @@ -221,10 +221,10 @@ describe('MediaCapabilities', () => {
await navigator.mediaCapabilities.decodingInfo(mockDecodingConfig);

expect(mockCanDisplayType).not.toHaveBeenCalled();
// 1 (during install()) +
// 3 (during install()) +
// 1 (for video config check) +
// 1 (for audio config check).
expect(isChromecastSpy).toHaveBeenCalledTimes(3);
expect(isChromecastSpy).toHaveBeenCalledTimes(5);
// 1 (fallback in canCastDisplayType()) +
// 1 (mockDecodingConfig.audio).
expect(supportMap.has(mockDecodingConfig.video.contentType))
Expand Down Expand Up @@ -270,10 +270,10 @@ describe('MediaCapabilities', () => {
shaka.polyfill.MediaCapabilities.install();
await navigator.mediaCapabilities.decodingInfo(mockDecodingConfig);

// 1 (during install()) +
// 3 (during install()) +
// 1 (for video config check) +
// 1 (for audio config check).
expect(isChromecastSpy).toHaveBeenCalledTimes(3);
expect(isChromecastSpy).toHaveBeenCalledTimes(5);
// 1 (mockDecodingConfig.audio).
expect(supportMap.has(chromecastType)).toBe(true);
// Called once in canCastDisplayType.
Expand Down

0 comments on commit 7681d4f

Please sign in to comment.