2024-01-24 13:51:00 +00:00
|
|
|
import { detect } from "detect-browser";
|
2023-01-10 18:53:55 +00:00
|
|
|
import fscreen from "fscreen";
|
2023-12-04 20:55:43 +00:00
|
|
|
import Hls from "hls.js";
|
2023-01-10 18:53:55 +00:00
|
|
|
|
|
|
|
export const isSafari = /^((?!chrome|android).)*safari/i.test(
|
2023-12-23 05:24:43 +00:00
|
|
|
navigator.userAgent,
|
2023-01-10 18:53:55 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let cachedVolumeResult: boolean | null = null;
|
|
|
|
export async function canChangeVolume(): Promise<boolean> {
|
|
|
|
if (cachedVolumeResult === null) {
|
|
|
|
const timeoutPromise = new Promise<false>((resolve) => {
|
|
|
|
setTimeout(() => resolve(false), 1e3);
|
|
|
|
});
|
|
|
|
const promise = new Promise<true>((resolve) => {
|
|
|
|
const video = document.createElement("video");
|
|
|
|
const handler = () => {
|
|
|
|
video.removeEventListener("volumechange", handler);
|
|
|
|
resolve(true);
|
|
|
|
};
|
|
|
|
|
|
|
|
video.addEventListener("volumechange", handler);
|
|
|
|
|
|
|
|
video.volume = 0.5;
|
|
|
|
});
|
|
|
|
|
|
|
|
cachedVolumeResult = await Promise.race([promise, timeoutPromise]);
|
|
|
|
}
|
|
|
|
return cachedVolumeResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function canFullscreenAnyElement(): boolean {
|
|
|
|
return fscreen.fullscreenEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function canWebkitFullscreen(): boolean {
|
|
|
|
return canFullscreenAnyElement() || isSafari;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function canFullscreen(): boolean {
|
|
|
|
return canFullscreenAnyElement() || canWebkitFullscreen();
|
|
|
|
}
|
2023-02-27 06:58:36 +00:00
|
|
|
|
|
|
|
export function canPictureInPicture(): boolean {
|
|
|
|
return "pictureInPictureEnabled" in document;
|
|
|
|
}
|
2023-02-27 09:43:14 +00:00
|
|
|
|
|
|
|
export function canWebkitPictureInPicture(): boolean {
|
|
|
|
return "webkitSupportsPresentationMode" in document.createElement("video");
|
|
|
|
}
|
2023-11-29 16:27:17 +00:00
|
|
|
|
|
|
|
export function canPlayHlsNatively(video: HTMLVideoElement): boolean {
|
2023-12-04 20:55:43 +00:00
|
|
|
if (Hls.isSupported()) return false; // no need to play natively
|
2023-11-29 16:27:17 +00:00
|
|
|
return !!video.canPlayType("application/vnd.apple.mpegurl");
|
|
|
|
}
|
2024-01-24 13:51:00 +00:00
|
|
|
|
|
|
|
export type ExtensionDetectionResult =
|
|
|
|
| "unknown" // unknown detection or weird browser
|
|
|
|
| "firefox" // firefox extensions
|
|
|
|
| "chrome" // chrome extension (could be chromium, but still works with chrome extensions)
|
|
|
|
| "ios"; // ios, no extensions
|
|
|
|
|
|
|
|
export function detectExtensionInstall(): ExtensionDetectionResult {
|
|
|
|
const res = detect();
|
|
|
|
|
|
|
|
// not a browser or failed to detect
|
|
|
|
if (res?.type !== "browser") return "unknown";
|
|
|
|
|
|
|
|
if (res.name === "ios" || res.name === "ios-webview") return "ios";
|
|
|
|
if (
|
|
|
|
res.name === "chrome" ||
|
|
|
|
res.name === "chromium-webview" ||
|
2024-01-24 16:32:57 +00:00
|
|
|
res.name === "edge-chromium" ||
|
|
|
|
res.name === "opera"
|
2024-01-24 13:51:00 +00:00
|
|
|
)
|
|
|
|
return "chrome";
|
|
|
|
if (res.name === "firefox") return "firefox";
|
|
|
|
return "unknown";
|
|
|
|
}
|