【问题标题】:Aframe splashscreen if videopsphere loads加载 videopsphere 时的 Aframe 启动画面
【发布时间】:2019-02-11 16:54:13
【问题描述】:

Hiho 社区,

如果我的 videosphere 加载,我会尝试显示启动画面。我使用此代码 - > set a loading animation with a-frame 在场景之前加载启动画面并且效果很好,但我需要让我的视频具有预加载属性,所以如果我启动它们,它们也需要一些时间来加载并且应该弹出启动画面又起来了。一些想法(也许第二个听众说:如果视频加载则显示启动画面)?

HTML:

<body>
 <div id="splash">
   <div class="loading"></div>
 </div>

 <a-scene>
   <a-assets>
     <video id="vid" loop="false" preload="none" 
      crossorigin="anonymous">
          <source type="video/mp4" src="..." />
     </video>
   </a-assets>

   <a-videosphere src="#vid"></a-videosphere>

 </a-scene>
</body>

CSS:

#splash {
  position: absolute;

  display: flex;
  align-items: center;
  justify-content: center;

  top: 0;
  bottom: 0;
  left: 0;
  right: 0;

  width: 200px;
  height: 200px;

  margin: auto;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loading {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 0.25rem solid rgba(255, 255, 255, 0.2);
  border-top-color: white;
  animation: spin 1s infinite linear;
}

javascript:

document.addEventListener('DOMContentLoaded', function() {
    var scene = document.querySelector('a-scene');
    var splash = document.querySelector('#splash');
    scene.addEventListener('loaded', function (e) {
        splash.style.display = 'none';
    });
});

【问题讨论】:

    标签: javascript video load aframe virtual-reality


    【解决方案1】:

    有很多方法可以解决这个问题,复杂程度各不相同。根据我的经验,视频的问题在于浏览器很少完全预加载视频。它们只会加载到某个点,直到用户观看播放头移动的视频。

    我注意到您在视频中设置了preload="none";我会考虑将其更改为preload="auto"

    如果您有网络连接,我能想到的最简单的方法是每隔一段时间检查视频的readyState。我已经尝试在 loadeddata 事件上这样做,但结果不一致,所以我不建议这样做。

    https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState

    您可以尝试这样的事情(最好在 A-Frame 系统或组件中):

    // The video element
    var video = document.querySelector('#vid');
    
    // Define interval in milliseconds
    var interval = 1000;
    
    // Check readyState immediately
    checkVidState();
    
    // Function to detect if video has enough data to play
    function checkVidState() {
    
      if (video.readyState === 4) {
        removeSplash();
        return true;
      }
    
      // If readyState !== 4, check again at set interval
      setTimeout(checkVidState, interval);
      return false;
    
    }
    
    // Function for removing splash
    function removeSplash() {
      // Logic for removing splash here...
    }
    

    如果您需要能够为多个视频执行此操作并且不使用 A-Frame 组件,您可以按如下方式定义函数:

    function checkVidState( video, interval ) {
      // Same inner code as above
    }
    

    您只需要传递视频元素和检查间隔值。

    然后为每个视频元素调用它们或循环遍历它们的数组:

    checkVideoState( video1, interval ); // or time in milleseconds
    checkVideoState( video2, interval );
    . . .
    

    【讨论】:

    • 谢谢我试试。我需要让 preload = none 因为我不希望有电话的人使用我的视频的漏洞数据。它们是 4k 360 度视频,非常沉重。
    • 它有效,但我猜我需要这个作为听众
    • 什么是返回真?是不是我需要先将某些东西设置为 false 才能重复此行为?
    • 哦,是的,看起来 return true 使它无法重复,所以我只是删除了该行,现在它在没有听众的情况下也可以工作,非常感谢现在一切都很好
    • 是的,return true; 是这样,函数在设置另一个超时以重复检查之前返回。如果您删除它,即使在视频加载后它也会不断检查,因此删除它可能不是最佳选择。在这种情况下,返回的值并不重要;您可以使用returnreturn false 等。我只选择return true;,以防您想检查checkVidState() 的值。示例:if ( checkVidState() ) { //do stuff; } 如果检查失败,我将添加 return false;
    【解决方案2】:

    喜欢这样吗? @Dan S.

      // The video element
      var videoEl_1 = document.querySelector('#intro');
      var videoEl_2 = document.querySelector('#dach');
      var videoEl_3 = document.querySelector('#door');
      var videoEl_4 = document.querySelector('#grube');
      var videoEl_5 = document.querySelector('#schleifen');
      var videoEl_6 = document.querySelector('#outro');
    
      // Define interval in milliseconds
      var interval = 1000;
    
    function checkVidState( videoEl_1, interval ) {
    
      // Check readyState immediately
      checkVidState();
    
      // Function to detect if video has enough data to play
      function checkVidState() {
    
        if (videoEl_1.readyState === 4) {
          removeSplash_2();
          return true;
        }
    
        /*if (videoEl_2.readyState === 4) {
          removeSplash_2();
          return true;
        }
    
        if (videoEl_3.readyState === 4) {
          removeSplash_2();
          return true;
        }
    
        if (videoEl_4.readyState === 4) {
          removeSplash_2();
          return true;
        }
    
        if (videoEl_5.readyState === 4) {
          removeSplash_2();
          return true;
        }
    
        if (videoEl_6.readyState === 4) {
          removeSplash_2();
          return true;
        }*/
    
        // If readyState !== 4, check again at set interval
        setTimeout(checkVidState, interval);
        return false;
      }
    
      // Function for removing splash
      function removeSplash_2() {
        var splash_2 = document.querySelector('#splash_2');
        splash_2.style.display = 'none';
      }
    }
    
    <a-box onclick="checkVideoState( videoEl_1, interval );"></a-box>
    <a-box onclick="checkVideoState( videoEl_2, interval );"></a-box>
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 2010-10-26
      • 2022-08-11
      • 1970-01-01
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多