Files
nothoughts/node_modules/pixi.js/lib/assets/loader/parsers/textures/loadVideoTextures.mjs
2025-08-04 18:57:35 +02:00

117 lines
4.2 KiB
JavaScript

import { ExtensionType } from '../../../../extensions/Extensions.mjs';
import { VideoSource } from '../../../../rendering/renderers/shared/texture/sources/VideoSource.mjs';
import { detectVideoAlphaMode } from '../../../../utils/browser/detectVideoAlphaMode.mjs';
import { getResolutionOfUrl } from '../../../../utils/network/getResolutionOfUrl.mjs';
import { checkDataUrl } from '../../../utils/checkDataUrl.mjs';
import { checkExtension } from '../../../utils/checkExtension.mjs';
import { createTexture } from './utils/createTexture.mjs';
"use strict";
const validVideoExtensions = [".mp4", ".m4v", ".webm", ".ogg", ".ogv", ".h264", ".avi", ".mov"];
const validVideoMIMEs = validVideoExtensions.map((ext) => `video/${ext.substring(1)}`);
function crossOrigin(element, url, crossorigin) {
if (crossorigin === void 0 && !url.startsWith("data:")) {
element.crossOrigin = determineCrossOrigin(url);
} else if (crossorigin !== false) {
element.crossOrigin = typeof crossorigin === "string" ? crossorigin : "anonymous";
}
}
function preloadVideo(element) {
return new Promise((resolve, reject) => {
element.addEventListener("canplaythrough", loaded);
element.addEventListener("error", error);
element.load();
function loaded() {
cleanup();
resolve();
}
function error(err) {
cleanup();
reject(err);
}
function cleanup() {
element.removeEventListener("canplaythrough", loaded);
element.removeEventListener("error", error);
}
});
}
function determineCrossOrigin(url, loc = globalThis.location) {
if (url.startsWith("data:")) {
return "";
}
loc = loc || globalThis.location;
const parsedUrl = new URL(url, document.baseURI);
if (parsedUrl.hostname !== loc.hostname || parsedUrl.port !== loc.port || parsedUrl.protocol !== loc.protocol) {
return "anonymous";
}
return "";
}
const loadVideoTextures = {
name: "loadVideo",
extension: {
type: ExtensionType.LoadParser,
name: "loadVideo"
},
test(url) {
const isValidDataUrl = checkDataUrl(url, validVideoMIMEs);
const isValidExtension = checkExtension(url, validVideoExtensions);
return isValidDataUrl || isValidExtension;
},
async load(url, asset, loader) {
const options = {
...VideoSource.defaultOptions,
resolution: asset.data?.resolution || getResolutionOfUrl(url),
alphaMode: asset.data?.alphaMode || await detectVideoAlphaMode(),
...asset.data
};
const videoElement = document.createElement("video");
const attributeMap = {
preload: options.autoLoad !== false ? "auto" : void 0,
"webkit-playsinline": options.playsinline !== false ? "" : void 0,
playsinline: options.playsinline !== false ? "" : void 0,
muted: options.muted === true ? "" : void 0,
loop: options.loop === true ? "" : void 0,
autoplay: options.autoPlay !== false ? "" : void 0
};
Object.keys(attributeMap).forEach((key) => {
const value = attributeMap[key];
if (value !== void 0)
videoElement.setAttribute(key, value);
});
if (options.muted === true) {
videoElement.muted = true;
}
crossOrigin(videoElement, url, options.crossorigin);
const sourceElement = document.createElement("source");
let mime;
if (url.startsWith("data:")) {
mime = url.slice(5, url.indexOf(";"));
} else if (!url.startsWith("blob:")) {
const ext = url.split("?")[0].slice(url.lastIndexOf(".") + 1).toLowerCase();
mime = VideoSource.MIME_TYPES[ext] || `video/${ext}`;
}
sourceElement.src = url;
if (mime) {
sourceElement.type = mime;
}
return new Promise((resolve) => {
const onCanPlay = async () => {
const base = new VideoSource({ ...options, resource: videoElement });
videoElement.removeEventListener("canplay", onCanPlay);
if (asset.data.preload) {
await preloadVideo(videoElement);
}
resolve(createTexture(base, loader, url));
};
videoElement.addEventListener("canplay", onCanPlay);
videoElement.appendChild(sourceElement);
});
},
unload(texture) {
texture.destroy(true);
}
};
export { crossOrigin, determineCrossOrigin, loadVideoTextures, preloadVideo };
//# sourceMappingURL=loadVideoTextures.mjs.map