You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Asset加载视频时materialvideoloadeddata事件未触发问题

Fixing A-Frame Video Texture Events When Using the Asset System

Hey there! I totally get the frustration of those events not firing when you're using A-Frame's Asset system for videos—let's break down what's going on and how to fix it so your popup can auto-resize properly.

The Core Issue

When you reference a video via the Asset system (src: #myvideoId), A-Frame preloads that video early on. By the time you assign it to your plane's material, the video is already loaded, so A-Frame's built-in materialvideoloadeddata and materialtextureloaded events don't trigger (they only fire when the material initiates the video load from scratch). Directly using a URL works because the material starts the load process itself, triggering the events as expected.

Solutions That Work

Here are a few reliable ways to detect when your video asset is ready and resize your plane:

1. Listen to the Asset's loaded Event

A-Frame's asset elements fire a loaded event once they're fully loaded. You can hook into this to get the video dimensions and adjust your plane:

// Grab your video asset and plane elements
const videoAsset = document.querySelector('#myvideo');
const videoPlayer = document.querySelector('#videoPlayer');

videoAsset.addEventListener('loaded', () => {
  // Get the video's natural dimensions
  const videoWidth = videoAsset.videoWidth;
  const videoHeight = videoAsset.videoHeight;
  // Calculate aspect ratio and resize the plane
  const aspectRatio = videoWidth / videoHeight;
  videoPlayer.setAttribute('scale', `${aspectRatio} 1 1`);
  console.log('Video asset loaded—plane resized!');
});

2. Listen to the Video DOM Element's loadeddata Event

Since the asset's <video> tag is a regular HTML5 video element, you can use standard video events like loadeddata (triggers when enough video data is available to start playing):

const videoAsset = document.querySelector('#myvideo');
const videoPlayer = document.querySelector('#videoPlayer');

videoAsset.addEventListener('loadeddata', () => {
  const { videoWidth, videoHeight } = videoAsset;
  const aspectRatio = videoWidth / videoHeight;
  videoPlayer.setAttribute('scale', `${aspectRatio} 1 1`);
  console.log('Video data ready—plane adjusted!');
});

3. Fallback: Check Video Ready State Manually

If you're setting the material source dynamically after initialization, you can check if the video is already loaded and resize immediately, otherwise wait for the event:

const videoPlayer = document.querySelector('#videoPlayer');
const videoAsset = document.querySelector('#myvideo');

// Assign the video asset to the plane's material
videoPlayer.setAttribute('material', 'src', `#${videoAsset.id}`);

// Check if the video is already loaded (readyState >= 2 means we have data)
if (videoAsset.readyState >= 2) {
  const { videoWidth, videoHeight } = videoAsset;
  const aspectRatio = videoWidth / videoHeight;
  videoPlayer.setAttribute('scale', `${aspectRatio} 1 1`);
  console.log('Video was already loaded—resized plane right away!');
} else {
  // Wait for the video to load if it's not ready yet
  videoAsset.addEventListener('loadeddata', () => {
    const { videoWidth, videoHeight } = videoAsset;
    const aspectRatio = videoWidth / videoHeight;
    videoPlayer.setAttribute('scale', `${aspectRatio} 1 1`);
  });
}

Why This Works

These methods bypass A-Frame's material-specific events and interact directly with the video asset itself. Since the Asset system preloads videos, we need to detect when that preload finishes instead of waiting for the material to start the load process.

内容的提问来源于stack exchange,提问作者aframefvtc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:53:53