A帧切换模板导致声音(视频?)重叠
A-frame switching template causes sound (video?) to overlap
我的操作(已编辑):
我正在使用 A-Frame 和 A-Frame 模板组件。
我使用模板组件从 <script id="..."> 标签加载模板,如 example.
我想使用 el.setAttribute 类比地动态更改模板,就像这个 example。
我的模板包含一个以视频为源的 <sky> 元素。
我可以加载一个模板,它就像一个魅力。我可以暂停、播放等等。
当我想将模板切换到使用相同视频资源的新模板,或者加载一个新模板然后 return 到第一个模板时,就会出现此问题。
现在我有 2 种声音 - 一种与视频不同步。
显示一个视频,但在后台播放第二个声音。我还可以验证声音不是来自显示的视频。我仍然可以 play/pause 它和它的声音在后台播放。
已编辑
我不仅希望能够修改 <sky> 元素,还希望能够修改其他一些元素,这就是我想使用模板组件的原因。假设我不知道最终会使用哪些资产,我不想使用资产管理系统来加载数十 Mb 的 videos/objects 和其他内容,并在加载屏幕上暂停用户。如前所述 here:
The scene won’t render or initialize until the browser fetches (or errors out) all the assets or the asset system reaches the timeout.
为了更清楚地说明我的意图,但仍然保持简单,我希望用户能够通过选择预制件来更改场景(假设每个视频 15Mb,即使有 6-7 个资产也可能几乎达到 100Mb ),或通过上传一个。我真的很想避免重新加载页面,因为从用户的角度来看,这不是一个优雅的解决方案。
我的猜测:
我认为旧视频没有完全处理。我尝试在各种元素/材料/视频本身上使用 three.js .dispose() 方法,但没有成功。
我还尝试使用 <a-video> 作为来源,并在切换前删除元素,但结果相同。
问题
- 如何正确删除模板加载的元素,使视频不在任何地方存储/缓存?
- 我能以某种方式设置 autoplay="false" 或类似于 <sky> 视频吗?
- 如果我的方法完全错误,你能指出正确的方向吗?
示例:
function switchVideoToFirst() {
console.log("switching to first");
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond() {
console.log('switching to second');
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
function playVideo() {
document.getElementById("skyVideo").components.material.material.map.image.play();
}
function pauseVideo() {
document.getElementById("skyVideo").components.material.material.map.image.pause();
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst()">switch video to first</button>
<button onclick="switchVideoToSecond()">switch video to second</button>
</br>
</br>
<button onclick="playVideo()">play</button>
<button onclick="pauseVideo()">Pause</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
我知道我在两个模板中都有相同的视频,但这是为了缩短示例。这个问题与重新加载相同的模板密切相关,要么切换到不同的模板然后返回,要么加载具有相同视频资源的新模板。
如何重现我的问题:
- 按“将视频切换到第一个”加载第一个模板。
- 按“将视频切换到第二个”以加载第二个模板。
- 视频没了,声音还在。
- 这一点可能不起作用,但如果您等待足够长的时间,第二个视频将加载,您将听到 2 种声音。然后 play/pause 控件将只对其中之一起作用。
我也经历过这个:
- 按“将视频切换到第一个”加载第一个模板
- 暂停视频
- 按“将视频切换到第二个”以加载第二个模板
- 可能需要一段时间白屏
- 加载“第二个”视频时,“第一个”视频仍会显示并暂停,但新视频会从头开始播放声音。那么你应该(或者不是,想不通)能够play/pause“第一个”视频。
示例 2
在 Piotr Adam Milewski 的大力投入后,我尝试了以下方法
- 按“将视频切换到第一个”加载第一个模板
- 按“将视频切换到第二个”以加载第二个模板
更换模板时没有声音,但加载第二个模板后声音从头开始播放,但视频暂停。
AFRAME.registerComponent("pausewhenremoved", {
init: function() {
this.el.addEventListener('materialvideoloadeddata', evt => {
this.videoElement = evt.detail.src;
//this.videoElement.pause();
});
},
remove() {
// once i'm removed, the video is going down too
this.videoElement.pause();
// I also tried removing the video from DOM but this only changed video to blank (sound was still on)
//this.videoElement.removeAttribute('src');
//this.videoElement.load();
//$(this.videoElement).empty().remove();
}
});
function switchVideoToFirst() {
console.log("switching to first");
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond() {
console.log('switching to second');
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst()">switch video to first</button>
<button onclick="switchVideoToSecond()">switch video to second</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
一个'kinda'工作示例
这是我(至少部分)解决此问题的方法。
我创建了一个标准 HTML 视频元素来存储视频并修改其来源,而不是将其留给 A-Frame。
您可以在两个模板之间切换,只要您切换的不是太快,它就会正常渲染(如果您尝试切换得太早,屏幕会变黑,但声音会正常播放)。
function switchVideoToFirst(buttonElement) {
console.log("switching to first");
if(document.getElementById("sky")) {
document.getElementById("sky").remove();
}
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond(buttonElement) {
console.log('switching to second');
if(document.getElementById("sky")) {
document.getElementById("sky").remove();
}
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<script>
AFRAME.registerComponent("pausewhenremoved", {
schema: {
src: {
type: 'string',
default: ''
}
},
init: function() {
this.videoElement = document.getElementById("skyVideoHolder");
this.videoElement.setAttribute('src', this.data.src);
this.videoElement.load();
},
play() {
if (this.videoElement) {
this.videoElement.play();
}
},
pause() {
if (this.videoElement) {
this.videoElement.pause();
}
},
remove() {
// once i'm removed, the video is going down too
this.videoElement.pause();
}
});
</script>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<video id="skyVideoHolder" src="" loop></video>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst(this)">switch video to first</button>
<button onclick="switchVideoToSecond(this)">switch video to second</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved="src: https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm" src="#skyVideoHolder">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved="src: https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm" src="#skyVideoHolder">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
免责声明
示例中使用的 360 视频来自 this website and the author is Jan Ainali
我认为你 运行 直接进入 this issue - once a-frame
creates a <video>
from an inline URL it kinda forgets about it. It is relevant, because the template component is just adding and removing 元素。
所以问题的一个很大的简化是 - 删除的 videosphere 仍然播放视频:
setTimeout(e => {
let sky = document.querySelector("a-sky")
sky.parentNode.removeChild(sky)
}, 2000)
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<a-scene background="color: #ECECEC">
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
</a-scene>
解决这个问题的一种方法是创建一个组件,它将获取加载的视频元素,并在实体移除时暂停/移除它:
setTimeout(e => {
let sky = document.querySelector("a-sky")
sky.parentNode.removeChild(sky)
}, 2000)
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("foo", {
init: function() {
// once the video data is loaded, store the element
this.el.addEventListener("materialvideoloadeddata", evt => {
this.videoEl = evt.detail.src;
})
},
remove() {
// once i'm removed, the video is going down too
this.videoEl.pause();
}
})
</script>
<a-scene background="color: #ECECEC">
<a-sky foo id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
</a-scene>
另一种方法是使用资产管理系统 - 您可以在其中控制视频 HTML 元素:
let video = document.querySelector("#vid");
let sky = document.querySelector("a-sky");
video.addEventListener("play", e => {
setTimeout(e => {
video.pause();
sky.parentNode.removeChild(sky);
}, 4000);
});
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<a-scene background="color: #ECECEC">
<a-assets>
<video id="vid" autoplay loop="true" preload="auto" crossorigin="anonymous" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm"></video>
</a-assets>
<a-sky id="skyVideo" src="#vid"> </a-sky>
</a-scene>
另一方面,如果您想更改/重新启动视频,并将立方体切换为球体,我不会使用 template
组件,只需管理视频 HTML 元素,并更改立方体/球体的可见性。
我的操作(已编辑):
我正在使用 A-Frame 和 A-Frame 模板组件。
我使用模板组件从 <script id="..."> 标签加载模板,如 example.
我想使用 el.setAttribute 类比地动态更改模板,就像这个 example。
我的模板包含一个以视频为源的 <sky> 元素。
我可以加载一个模板,它就像一个魅力。我可以暂停、播放等等。
当我想将模板切换到使用相同视频资源的新模板,或者加载一个新模板然后 return 到第一个模板时,就会出现此问题。
现在我有 2 种声音 - 一种与视频不同步。
显示一个视频,但在后台播放第二个声音。我还可以验证声音不是来自显示的视频。我仍然可以 play/pause 它和它的声音在后台播放。
已编辑
我不仅希望能够修改 <sky> 元素,还希望能够修改其他一些元素,这就是我想使用模板组件的原因。假设我不知道最终会使用哪些资产,我不想使用资产管理系统来加载数十 Mb 的 videos/objects 和其他内容,并在加载屏幕上暂停用户。如前所述 here:
The scene won’t render or initialize until the browser fetches (or errors out) all the assets or the asset system reaches the timeout.
为了更清楚地说明我的意图,但仍然保持简单,我希望用户能够通过选择预制件来更改场景(假设每个视频 15Mb,即使有 6-7 个资产也可能几乎达到 100Mb ),或通过上传一个。我真的很想避免重新加载页面,因为从用户的角度来看,这不是一个优雅的解决方案。
我的猜测:
我认为旧视频没有完全处理。我尝试在各种元素/材料/视频本身上使用 three.js .dispose() 方法,但没有成功。
我还尝试使用 <a-video> 作为来源,并在切换前删除元素,但结果相同。
问题
- 如何正确删除模板加载的元素,使视频不在任何地方存储/缓存?
- 我能以某种方式设置 autoplay="false" 或类似于 <sky> 视频吗?
- 如果我的方法完全错误,你能指出正确的方向吗?
示例:
function switchVideoToFirst() {
console.log("switching to first");
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond() {
console.log('switching to second');
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
function playVideo() {
document.getElementById("skyVideo").components.material.material.map.image.play();
}
function pauseVideo() {
document.getElementById("skyVideo").components.material.material.map.image.pause();
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst()">switch video to first</button>
<button onclick="switchVideoToSecond()">switch video to second</button>
</br>
</br>
<button onclick="playVideo()">play</button>
<button onclick="pauseVideo()">Pause</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
我知道我在两个模板中都有相同的视频,但这是为了缩短示例。这个问题与重新加载相同的模板密切相关,要么切换到不同的模板然后返回,要么加载具有相同视频资源的新模板。
如何重现我的问题:
- 按“将视频切换到第一个”加载第一个模板。
- 按“将视频切换到第二个”以加载第二个模板。
- 视频没了,声音还在。
- 这一点可能不起作用,但如果您等待足够长的时间,第二个视频将加载,您将听到 2 种声音。然后 play/pause 控件将只对其中之一起作用。
我也经历过这个:
- 按“将视频切换到第一个”加载第一个模板
- 暂停视频
- 按“将视频切换到第二个”以加载第二个模板
- 可能需要一段时间白屏
- 加载“第二个”视频时,“第一个”视频仍会显示并暂停,但新视频会从头开始播放声音。那么你应该(或者不是,想不通)能够play/pause“第一个”视频。
示例 2
在 Piotr Adam Milewski 的大力投入后,我尝试了以下方法
- 按“将视频切换到第一个”加载第一个模板
- 按“将视频切换到第二个”以加载第二个模板
更换模板时没有声音,但加载第二个模板后声音从头开始播放,但视频暂停。
AFRAME.registerComponent("pausewhenremoved", {
init: function() {
this.el.addEventListener('materialvideoloadeddata', evt => {
this.videoElement = evt.detail.src;
//this.videoElement.pause();
});
},
remove() {
// once i'm removed, the video is going down too
this.videoElement.pause();
// I also tried removing the video from DOM but this only changed video to blank (sound was still on)
//this.videoElement.removeAttribute('src');
//this.videoElement.load();
//$(this.videoElement).empty().remove();
}
});
function switchVideoToFirst() {
console.log("switching to first");
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond() {
console.log('switching to second');
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst()">switch video to first</button>
<button onclick="switchVideoToSecond()">switch video to second</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
一个'kinda'工作示例
这是我(至少部分)解决此问题的方法。
我创建了一个标准 HTML 视频元素来存储视频并修改其来源,而不是将其留给 A-Frame。
您可以在两个模板之间切换,只要您切换的不是太快,它就会正常渲染(如果您尝试切换得太早,屏幕会变黑,但声音会正常播放)。
function switchVideoToFirst(buttonElement) {
console.log("switching to first");
if(document.getElementById("sky")) {
document.getElementById("sky").remove();
}
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', "#firstVideo");
}
function switchVideoToSecond(buttonElement) {
console.log('switching to second');
if(document.getElementById("sky")) {
document.getElementById("sky").remove();
}
document.getElementById("skyVideoTemplate").setAttribute('template', 'src', '#secondVideo');
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.3.0/nunjucks.min.js"></script>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-template-component@3.2.1/dist/aframe-template-component.min.js"></script>
</head>
<body>
<script>
AFRAME.registerComponent("pausewhenremoved", {
schema: {
src: {
type: 'string',
default: ''
}
},
init: function() {
this.videoElement = document.getElementById("skyVideoHolder");
this.videoElement.setAttribute('src', this.data.src);
this.videoElement.load();
},
play() {
if (this.videoElement) {
this.videoElement.play();
}
},
pause() {
if (this.videoElement) {
this.videoElement.pause();
}
},
remove() {
// once i'm removed, the video is going down too
this.videoElement.pause();
}
});
</script>
<div style="width: 400px; height: 200px;">
<a-scene embedded>
<video id="skyVideoHolder" src="" loop></video>
<a-entity id="skyVideoTemplate" template="src: #"></a-entity>
</a-scene>
</div>
<button onclick="switchVideoToFirst(this)">switch video to first</button>
<button onclick="switchVideoToSecond(this)">switch video to second</button>
</body>
<script id="firstVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved="src: https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm" src="#skyVideoHolder">
</a-sky>
<a-box position="-1 1 -1" color="red"></a-box>
</script>
<script id="secondVideo" type='text/nunjucks'>
<a-sky id="skyVideo" pausewhenremoved="src: https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm" src="#skyVideoHolder">
</a-sky>
<a-sphere position="-1 1 -1" color="green"></a-sphere>
</script>
免责声明
示例中使用的 360 视频来自 this website and the author is Jan Ainali
我认为你 运行 直接进入 this issue - once a-frame
creates a <video>
from an inline URL it kinda forgets about it. It is relevant, because the template component is just adding and removing 元素。
所以问题的一个很大的简化是 - 删除的 videosphere 仍然播放视频:
setTimeout(e => {
let sky = document.querySelector("a-sky")
sky.parentNode.removeChild(sky)
}, 2000)
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<a-scene background="color: #ECECEC">
<a-sky id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
</a-scene>
解决这个问题的一种方法是创建一个组件,它将获取加载的视频元素,并在实体移除时暂停/移除它:
setTimeout(e => {
let sky = document.querySelector("a-sky")
sky.parentNode.removeChild(sky)
}, 2000)
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("foo", {
init: function() {
// once the video data is loaded, store the element
this.el.addEventListener("materialvideoloadeddata", evt => {
this.videoEl = evt.detail.src;
})
},
remove() {
// once i'm removed, the video is going down too
this.videoEl.pause();
}
})
</script>
<a-scene background="color: #ECECEC">
<a-sky foo id="skyVideo" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm">
</a-sky>
</a-scene>
另一种方法是使用资产管理系统 - 您可以在其中控制视频 HTML 元素:
let video = document.querySelector("#vid");
let sky = document.querySelector("a-sky");
video.addEventListener("play", e => {
setTimeout(e => {
video.pause();
sky.parentNode.removeChild(sky);
}, 4000);
});
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<a-scene background="color: #ECECEC">
<a-assets>
<video id="vid" autoplay loop="true" preload="auto" crossorigin="anonymous" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/f/fb/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm/Hundra_knektars_marsch_p%C3%A5_Forum_Vulgaris.webm.360p.vp9.webm"></video>
</a-assets>
<a-sky id="skyVideo" src="#vid"> </a-sky>
</a-scene>
另一方面,如果您想更改/重新启动视频,并将立方体切换为球体,我不会使用 template
组件,只需管理视频 HTML 元素,并更改立方体/球体的可见性。