UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

160 lines (159 loc) 6.12 kB
"use strict"; import { VideoTexture, Loader } from "three"; import { CoreLoaderTexture } from "../Texture"; import { CoreBaseLoader } from "./../_Base"; import { Poly } from "../../../engine/Poly"; const VIDEO_SOURCE_TYPE_BY_EXT = { ogg: 'video/ogg; codecs="theora, vorbis"', ogv: 'video/ogg; codecs="theora, vorbis"', mp4: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' }; class VideoTextureLoader extends Loader { constructor(manager, originalUrls) { super(manager); this.originalUrls = originalUrls; } loadMultipleUrls(urls, onLoad, onProgress, onError) { const video = document.createElement("video"); video.setAttribute("crossOrigin", "anonymous"); video.setAttribute("playinline", `${true}`); video.setAttribute("muted", `${true}`); video.setAttribute("autoplay", `${true}`); video.style.display = "none"; const texture = new VideoTexture(video); video.onloadedmetadata = () => { onLoad(texture); }; video.onprogress = (ev) => { if (onProgress) { onProgress(ev.loaded / ev.total); } }; const _onError = (error) => { if (onError) { onError(new Error("failed to load video")); } }; video.onerror = _onError; const urlsCount = urls.length; for (let i = 0; i < urlsCount; i++) { const blobUrl = urls[i]; const originalUrl = this.originalUrls[i]; const ext = CoreBaseLoader.extension(originalUrl); const type = VIDEO_SOURCE_TYPE_BY_EXT[ext] || `video/${ext}`; const source = document.createElement("source"); source.src = blobUrl; source.type = type; video.append(source); } } } export class CoreVideoTextureLoader extends CoreBaseLoader { async loadVideo() { const urls = this._urlToLoad(); return new Promise(async (resolve, reject) => { const loader = await this._getLoader(); urls.forEach((url) => CoreLoaderTexture.incrementInProgressLoadsCount()); await CoreLoaderTexture.waitForMaxConcurrentLoadsQueueFreed(); loader.loadMultipleUrls( urls, (texture) => { urls.forEach((url, i) => { const isLast = i == urls.length - 1; CoreLoaderTexture.decrementInProgressLoadsCount(url, isLast ? texture : void 0); }); resolve(texture); }, void 0, (error) => { urls.forEach((url) => CoreLoaderTexture.decrementInProgressLoadsCount(url)); Poly.warn("error", error); reject(); } ); }); } async _getLoader() { const loader = new VideoTextureLoader(this.loadingManager, this._url); return loader; } // constructor(protected override _url: string, protected override _node: BaseNodeType) { // super(_url, _node); // } // loadVideo(): Promise<VideoTexture> { // // if (1 + 1) { // // return this._loadVideoFull(); // // } else { // return this._loadVideoDefault(); // // } // } // // private _loadVideoFull(): Promise<VideoTexture> { // // return new Promise(async (resolve) => { // // const url = await this._urlToLoad(); // // console.log(url); // // fetch(url, {mode: 'no-cors'}).then(async (response) => { // // console.log({response}); // // const blob = await response.blob(); // // console.log({blob}); // // const source = URL.createObjectURL(blob); // // console.log(source); // // const video = document.createElement('video'); // // video.src = source; // // const texture = new VideoTexture(video); // // // document.body.append(video) // // resolve(texture); // // }); // // }); // // } // private _loadVideoDefault(): Promise<VideoTexture> { // return new Promise(async (resolve, reject) => { // const url = await this._urlToLoad(); // CoreLoaderTexture.incrementInProgressLoadsCount(); // await CoreLoaderTexture.waitForMaxConcurrentLoadsQueueFreed(); // const video = document.createElement('video'); // video.setAttribute('crossOrigin', 'anonymous'); // video.setAttribute('autoplay', `${true}`); // to ensure it loads // video.setAttribute('loop', `${true}`); // // wait for onloadedmetadata to ensure that we have a duration // // video.onloadeddata = function (e) { // // console.log('onloadeddata', e); // // }; // video.onloadedmetadata = function () { // video.pause(); // const texture = new VideoTexture(video); // // video.setAttribute('controls', true) // // video.style="display:none" // CoreLoaderTexture.decrementInProgressLoadsCount(url, texture); // resolve(texture); // }; // // add source as is // const originalSource = document.createElement('source'); // const originalExt = CoreBaseLoader.extension(url) as keyof VideoSourceTypeByExt; // let type: string = VideoTextureLoader.VIDEO_SOURCE_TYPE_BY_EXT[originalExt]; // type = type || VideoTextureLoader._default_video_source_type(url); // originalSource.setAttribute('type', type); // originalSource.setAttribute('src', url); // video.appendChild(originalSource); // // add secondary source, either mp4 or ogv depending on the first url // let secondaryUrl: string | undefined; // if (originalExt == 'mp4') { // // add ogv // secondaryUrl = CoreLoaderTexture.replaceExtension(url, 'ogv'); // } else { // // add mp4 // secondaryUrl = CoreLoaderTexture.replaceExtension(url, 'mp4'); // } // const secondary_source = document.createElement('source'); // const secondary_ext = CoreBaseLoader.extension(secondaryUrl) as keyof VideoSourceTypeByExt; // type = VideoTextureLoader.VIDEO_SOURCE_TYPE_BY_EXT[secondary_ext]; // type = type || VideoTextureLoader._default_video_source_type(url); // secondary_source.setAttribute('type', type); // secondary_source.setAttribute('src', url); // video.appendChild(secondary_source); // }); // } // static _default_video_source_type(url: string) { // const ext = CoreBaseLoader.extension(url); // return `video/${ext}`; // } }