mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-26 17:46:26 +03:00
65ad9adf2b
Closes #2360 Change-Id: I789ea3fed108a9d05544502b11bfcbf8adb5dc31
209 lines
5.5 KiB
JavaScript
209 lines
5.5 KiB
JavaScript
/** @license
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
goog.provide('shaka.util.Platform');
|
|
|
|
goog.require('shaka.util.Timer');
|
|
|
|
|
|
/**
|
|
* A wrapper for platform-specific functions.
|
|
*
|
|
* @final
|
|
*/
|
|
shaka.util.Platform = class {
|
|
/**
|
|
* Check if the current platform supports media source. We assume that if
|
|
* the current platform supports media source, then we can use media source
|
|
* as per its design.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static supportsMediaSource() {
|
|
// Browsers that lack a media source implementation will have no reference
|
|
// to |window.MediaSource|. Platforms that we see having problematic media
|
|
// source implementations will have this reference removed via a polyfill.
|
|
if (!window.MediaSource) {
|
|
return false;
|
|
}
|
|
|
|
// Some very old MediaSource implementations didn't have isTypeSupported.
|
|
if (!MediaSource.isTypeSupported) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the media type is supported natively by the platform.
|
|
*
|
|
* @param {string} mimeType
|
|
* @return {boolean}
|
|
*/
|
|
static supportsMediaType(mimeType) {
|
|
const video = shaka.util.Platform.anyMediaElement();
|
|
return video.canPlayType(mimeType) != '';
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is MS Edge.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isEdge() {
|
|
return shaka.util.Platform.userAgentContains_('Edge/');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is MS IE.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isIE() {
|
|
return shaka.util.Platform.userAgentContains_('Trident/');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is a Tizen TV.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isTizen() {
|
|
return shaka.util.Platform.userAgentContains_('Tizen');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is a Tizen 3 TV.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isTizen3() {
|
|
return shaka.util.Platform.userAgentContains_('Tizen 3');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is a WebOS.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isWebOS() {
|
|
return shaka.util.Platform.userAgentContains_('Web0S');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is a Google Chromecast.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isChromecast() {
|
|
return shaka.util.Platform.userAgentContains_('CrKey');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Google Chrome.
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isChrome() {
|
|
// The Edge user agent will also contain the "Chrome" keyword, so we need
|
|
// to make sure this is not Edge.
|
|
return shaka.util.Platform.userAgentContains_('Chrome') &&
|
|
!shaka.util.Platform.isEdge();
|
|
}
|
|
|
|
|
|
/**
|
|
* Check if the current platform is an Apple device (iOS, desktop Safari, etc)
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isApple() {
|
|
return !!navigator.vendor && navigator.vendor.includes('Apple');
|
|
}
|
|
|
|
/**
|
|
* Guesses if the platform is a mobile one (iOS or Android).
|
|
*
|
|
* @return {boolean}
|
|
*/
|
|
static isMobile() {
|
|
if (/(?:iPhone|iPad|iPod|Android)/.test(navigator.userAgent)) {
|
|
// This is Android, iOS, or iPad < 13.
|
|
return true;
|
|
}
|
|
|
|
// Starting with iOS 13 on iPad, the user agent string no longer has the
|
|
// word "iPad" in it. It looks very similar to desktop Safari. This seems
|
|
// to be intentional on Apple's part.
|
|
// See: https://forums.developer.apple.com/thread/119186
|
|
//
|
|
// So if it's an Apple device with multi-touch support, assume it's a mobile
|
|
// device. If some future iOS version starts masking their user agent on
|
|
// both iPhone & iPad, this clause should still work. If a future
|
|
// multi-touch desktop Mac is released, this will need some adjustment.
|
|
//
|
|
// As of January 2020, this is mainly used to adjust the default UI config
|
|
// for mobile devices, so it's low risk if something changes to break this
|
|
// detection.
|
|
return shaka.util.Platform.isApple() && navigator.maxTouchPoints > 1;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* PR.
|
|
*
|
|
* @param {string} key
|
|
* @return {boolean}
|
|
* @private
|
|
*/
|
|
static userAgentContains_(key) {
|
|
const userAgent = navigator.userAgent || '';
|
|
return userAgent.includes(key);
|
|
}
|
|
|
|
/**
|
|
* For canPlayType queries, we just need any instance.
|
|
*
|
|
* First, use a cached element from a previous query.
|
|
* Second, search the page for one.
|
|
* Third, create a temporary one.
|
|
*
|
|
* Cached elements expire in one second so that they can be GC'd or removed.
|
|
*
|
|
* @return {!HTMLMediaElement}
|
|
*/
|
|
static anyMediaElement() {
|
|
const Platform = shaka.util.Platform;
|
|
if (Platform.cachedMediaElement_) {
|
|
return Platform.cachedMediaElement_;
|
|
}
|
|
|
|
if (!Platform.cacheExpirationTimer_) {
|
|
Platform.cacheExpirationTimer_ = new shaka.util.Timer(() => {
|
|
Platform.cachedMediaElement_ = null;
|
|
});
|
|
}
|
|
|
|
Platform.cachedMediaElement_ = /** @type {HTMLMediaElement} */(
|
|
document.querySelector('video') || document.querySelector('audio'));
|
|
|
|
if (!Platform.cachedMediaElement_) {
|
|
Platform.cachedMediaElement_ = /** @type {!HTMLMediaElement} */(
|
|
document.createElement('video'));
|
|
}
|
|
|
|
Platform.cacheExpirationTimer_.tickAfter(/* seconds= */ 1);
|
|
return Platform.cachedMediaElement_;
|
|
}
|
|
};
|
|
|
|
/** @private {shaka.util.Timer} */
|
|
shaka.util.Platform.cacheExpirationTimer_ = null;
|
|
|
|
/** @private {HTMLMediaElement} */
|
|
shaka.util.Platform.cachedMediaElement_ = null;
|