Files
v10/dist/dev/dom/google-cast/utils.js
T

143 lines
4.8 KiB
JavaScript

import { loadScript } from "@videojs/utils/dom";
//#region src/dom/google-cast/utils.ts
var InvalidStateError = class extends Error {};
var NotSupportedError = class extends Error {};
var NotFoundError = class extends Error {};
const GOOGLE_CAST_FRAMEWORK_URL = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
const HLS_RESPONSE_HEADERS = [
"application/x-mpegURL",
"application/vnd.apple.mpegurl",
"audio/mpegurl"
];
var IterableWeakSet = class {
#refs = /* @__PURE__ */ new Set();
#seen = /* @__PURE__ */ new WeakMap();
add(value) {
if (this.#seen.has(value)) return this;
const ref = new WeakRef(value);
this.#seen.set(value, ref);
this.#refs.add(ref);
return this;
}
delete(value) {
const ref = this.#seen.get(value);
if (!ref) return false;
this.#seen.delete(value);
return this.#refs.delete(ref);
}
forEach(fn) {
for (const ref of this.#refs) {
const value = ref.deref();
if (value) fn(value);
else this.#refs.delete(ref);
}
}
};
function onCastApiAvailable(callback) {
const whenDefined = () => customElements.whenDefined("google-cast-button").then(callback);
if (!globalThis.chrome?.cast?.isAvailable) globalThis.__onGCastApiAvailable = whenDefined;
else if (typeof cast === "undefined" || !cast.framework) whenDefined();
else callback();
}
function requiresCastFramework() {
return Boolean(globalThis.chrome);
}
async function loadCastFramework() {
if (globalThis.chrome?.cast) return;
await loadScript(GOOGLE_CAST_FRAMEWORK_URL);
}
function getCastContext() {
return typeof cast === "undefined" ? void 0 : cast.framework?.CastContext.getInstance();
}
function currentSession() {
return getCastContext()?.getCurrentSession();
}
function currentMedia() {
return currentSession()?.getSessionObj().media[0] ?? void 0;
}
function editTracksInfo(request) {
return new Promise((resolve, reject) => {
currentMedia().editTracksInfo(request, resolve, reject);
});
}
function getMediaStatus(request) {
return new Promise((resolve, reject) => {
currentMedia().getStatus(request, resolve, reject);
});
}
const MEDIA_NAMESPACE = "urn:x-cast:com.google.cast.media";
let requestId = 0;
function setPlaybackRate(rate) {
const media = currentMedia();
return currentSession().sendMessage(MEDIA_NAMESPACE, {
type: "SET_PLAYBACK_RATE",
playbackRate: rate,
mediaSessionId: media?.mediaSessionId,
requestId: ++requestId
});
}
function setCastOptions(options) {
getCastContext().setOptions({
...getDefaultCastOptions(),
...options
});
}
function getDefaultCastOptions() {
return {
receiverApplicationId: "CC1AD845",
autoJoinPolicy: globalThis.chrome?.cast?.AutoJoinPolicy?.ORIGIN_SCOPED ?? "origin_scoped",
androidReceiverCompatible: false,
language: "en-US",
resumeSavedSession: true
};
}
function getFormat(segment) {
if (!segment) return void 0;
const match = segment.match(/\.([a-zA-Z0-9]+)(?:\?.*)?$/);
return match ? match[1] : null;
}
function parsePlaylistUrls(playlistContent) {
const lines = playlistContent.split("\n");
const urls = [];
for (let i = 0; i < lines.length; i++) if (lines[i].trim().startsWith("#EXT-X-STREAM-INF")) {
const nextLine = lines[i + 1] ? lines[i + 1].trim() : "";
if (nextLine && !nextLine.startsWith("#")) urls.push(nextLine);
}
return urls;
}
function parseSegment(playlistContent) {
return playlistContent.split("\n").find((line) => !line.trim().startsWith("#") && line.trim() !== "");
}
async function isHls(url) {
if (!url) return false;
if (/\.m3u8?(\?.*)?$/i.test(url)) return true;
if (url.startsWith("blob:")) return false;
try {
const contentType = (await fetch(url, { method: "HEAD" })).headers.get("Content-Type");
if (!contentType) return false;
const normalizedContentType = contentType.toLowerCase().split(";")[0].trim();
return HLS_RESPONSE_HEADERS.some((header) => normalizedContentType === header.toLowerCase());
} catch (err) {
console.error("Error while trying to get the Content-Type of the manifest", err);
return false;
}
}
async function getPlaylistSegmentFormat(url) {
try {
const mainManifestContent = await (await fetch(url)).text();
let availableChunksContent = mainManifestContent;
const playlists = parsePlaylistUrls(mainManifestContent);
if (playlists.length > 0) {
const chosenPlaylistUrl = new URL(playlists[0], url).toString();
availableChunksContent = await (await fetch(chosenPlaylistUrl)).text();
}
return getFormat(parseSegment(availableChunksContent));
} catch (err) {
console.error("Error while trying to parse the manifest playlist", err);
return;
}
}
//#endregion
export { InvalidStateError, IterableWeakSet, NotFoundError, NotSupportedError, currentMedia, currentSession, editTracksInfo, getCastContext, getMediaStatus, getPlaylistSegmentFormat, isHls, loadCastFramework, onCastApiAvailable, requiresCastFramework, setCastOptions, setPlaybackRate };
//# sourceMappingURL=utils.js.map