diff --git a/src/components/gltf-model-plus.js b/src/components/gltf-model-plus.js index 33699eacf7d127c506ae99740a137a2853890efa..4ca78bb33c89f0b62f36307ff1e7d9807560ecb2 100644 --- a/src/components/gltf-model-plus.js +++ b/src/components/gltf-model-plus.js @@ -215,7 +215,7 @@ async function resolveGLTFUri(gltfProperty, basePath) { if (url.protocol === "blob:") { gltfProperty.uri = url.href; } else { - const { raw } = await resolveMedia(url.href); + const { raw } = await resolveMedia(url.href, null, true); gltfProperty.uri = raw; } } diff --git a/src/components/media-loader.js b/src/components/media-loader.js index 0cc6792ab211b2d6d8059368134aa24eeeffe1f4..81303a07d67946e187ea7664252dab3af20846b3 100644 --- a/src/components/media-loader.js +++ b/src/components/media-loader.js @@ -13,6 +13,13 @@ AFRAME.registerComponent("media-loader", { this.showLoader = this.showLoader.bind(this); }, + remove() { + if (this.blobURL) { + URL.revokeObjectURL(this.blobURL); + this.blobURL = null; + } + }, + setShapeAndScale(resize) { const mesh = this.el.getObject3D("mesh"); const box = getBox(this.el, mesh); @@ -58,16 +65,19 @@ AFRAME.registerComponent("media-loader", { if (!url) return; - const { raw, contentType } = await resolveMedia(url, token); + const { raw, origin, contentType } = await resolveMedia(url, token); - let blobUrl; if (token) { + if (this.blobURL) { + URL.revokeObjectURL(this.blobURL); + this.blobURL = null; + } const response = await fetch(raw, { method: "GET", headers: { Authorization: `Token ${token}` } }); const blob = await response.blob(); - blobUrl = window.URL.createObjectURL(blob); + this.blobURL = window.URL.createObjectURL(blob); } if (contentType.startsWith("image/") || contentType.startsWith("video/") || contentType.startsWith("audio/")) { @@ -78,7 +88,7 @@ AFRAME.registerComponent("media-loader", { }, { once: true } ); - this.el.setAttribute("image-plus", { src: blobUrl || raw, contentType, token }); + this.el.setAttribute("image-plus", { src: this.blobURL || raw, contentType, token }); this.el.setAttribute("position-at-box-shape-border", { target: ".delete-button", dirs: ["forward", "back"] }); } else if ( contentType.includes("application/octet-stream") || @@ -96,8 +106,9 @@ AFRAME.registerComponent("media-loader", { { once: true } ); this.el.addEventListener("model-error", this.onError, { once: true }); + const src = this.blobURL || origin || url; this.el.setAttribute("gltf-model-plus", { - src: blobUrl || url, + src, contentType, inflate: true }); diff --git a/src/utils/media-utils.js b/src/utils/media-utils.js index 36debd69e3a1dceecf01fd1cc6842ea0e11237d3..dc7d5773085acee914e3b70d894d0b14adfe221b 100644 --- a/src/utils/media-utils.js +++ b/src/utils/media-utils.js @@ -17,7 +17,7 @@ const fetchContentType = async (url, token) => { }; const resolveMediaCache = new Map(); -export const resolveMedia = async (url, token) => { +export const resolveMedia = async (url, token, skipContentType) => { const parsedUrl = new URL(url); if (resolveMediaCache.has(url)) return resolveMediaCache.get(url); @@ -31,7 +31,7 @@ export const resolveMedia = async (url, token) => { body: JSON.stringify({ media: { url } }) }).then(r => r.json()); - if (!isNotHttpOrHttps) { + if (!isNotHttpOrHttps && !skipContentType) { const contentType = (resolved.meta && resolved.meta.expected_content_type) || (await fetchContentType(resolved.raw, token)); resolved.contentType = contentType;