A-Frame a-video 在 safari ios16.1 和 iphone 12 中不起作用?

问题描述 投票:0回答:1

我是A-Frame的新手。我尝试制作一个演示,我在场景中放了一段视频。它在我的电脑上工作,但在我的移动设备上有一个黑色的飞机。这是屏幕截图和代码。

demo run in Macos chrome & safari

demo run in ios safari,它适用于 chrome。


<html>
  <head>
    <script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>

    <script id="vertexShader" type="glsl">
      varying vec2 vUv;
      void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
      }
    </script>
  
    <script id="fragmentShader" type="glsl">
      uniform sampler2D tex;
      uniform float texWidth;
      uniform float texHeight;
  
      uniform vec3 keyColor;
      uniform float similarity;
      uniform float smoothness;
      uniform float spill;
      
      varying vec2 vUv;
  
      // From https://github.com/libretro/glsl-shaders/blob/master/nnedi3/shaders/rgb-to-yuv.glsl
      vec2 RGBtoUV(vec3 rgb) {
        return vec2(
          rgb.r * -0.169 + rgb.g * -0.331 + rgb.b *  0.5    + 0.5,
          rgb.r *  0.5   + rgb.g * -0.419 + rgb.b * -0.081  + 0.5
        );
      }
  
      vec4 ProcessChromaKey(vec2 texCoord) {
        vec4 rgba = texture2D(tex, texCoord);
        float chromaDist = distance(RGBtoUV(texture2D(tex, texCoord).rgb), RGBtoUV(keyColor));
  
        float baseMask = chromaDist - similarity;
        float fullMask = pow(clamp(baseMask / smoothness, 0., 1.), 1.5);
        rgba.a = fullMask;
  
        float spillVal = pow(clamp(baseMask / spill, 0., 1.), 1.5);
        float desat = clamp(rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722, 0., 1.);
        rgba.rgb = mix(vec3(desat, desat, desat), rgba.rgb, spillVal);
  
        return rgba;
      }
  
      void main(void) {
        vec2 texCoord = vUv;
        gl_FragColor = ProcessChromaKey(texCoord);
      }
    </script>
  

    <script>
      AFRAME.registerShader('custom-shader', {
        init: function(data) {
          const video = document.getElementById('video')
          const texture = new THREE.VideoTexture(video)
          this.material = new THREE.ShaderMaterial( {

            uniforms: {

            tex: { value: texture },
            keyColor: {
                value: new THREE.Color(0x00ff00)
              },
              texWidth: {
                value: 1920
              },
              texHeight: {
                value: 1080
              },
              similarity: {
                value: 0.4
              },
              smoothness: {
                value: 0.08
              },
              spill: {
                value: 0.1
              }

            },

            vertexShader: document.getElementById( 'vertexShader' ).textContent,
            fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
            transparent: true

          });
        }
      });
    </script>
  </head>
  <body>
    <a-scene>
      <a-assets>
        <video id="video" autoplay loop="true" muted="true" crossOrigin="anonymous">
          <source src="./assets/mixkit-a-woman-talking-on-the-phone-on-a-green-screen-24388-medium.mp4" type='video/mp4'>
        </video>
      </a-assets>   
      <a-video material="shader: custom-shader;" webkit-playsinline playsinline position="0 0 -10" height="9" width="16" rotation="0 0 0"></a-video>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
    <script>
      const video = document.getElementById('video');
      video.play();
    </script>
  </body>
</html>

这是我的demo

我已经为视频设置了一些属性,比如 webkit-playsinline playsinline。但它不起作用。

有人知道怎么解决吗?谢谢。

webgl mobile-safari aframe
1个回答
0
投票

我相信移动浏览器需要明确的“用户交互”,例如“点击”来播放视频。这是必需的,因为许多移动设备使用蜂窝数据,如果我在我的网站上嵌入一个 1GB 的视频并在后台自动播放它会耗尽你的电池,你不会对数据费用感到满意。尝试添加一个点击处理程序来启动视频,如果单击“开始”按钮有效,那么您就遇到了这个限制。该文档还暗示了this

移动和桌面浏览器一直在收紧视频自动播放政策,以节省电量并避免侵入性广告。大多数浏览器现在需要用户操作(例如单击或点击事件)才能开始播放视频:

他们甚至提供了一个example

<html>
  <head>
    <script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script>

    <script id="vertexShader" type="glsl">
      varying vec2 vUv;
      void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
      }
    </script>
  
    <script id="fragmentShader" type="glsl">
      uniform sampler2D tex;
      uniform float texWidth;
      uniform float texHeight;
  
      uniform vec3 keyColor;
      uniform float similarity;
      uniform float smoothness;
      uniform float spill;
      
      varying vec2 vUv;
  
      // From https://github.com/libretro/glsl-shaders/blob/master/nnedi3/shaders/rgb-to-yuv.glsl
      vec2 RGBtoUV(vec3 rgb) {
        return vec2(
          rgb.r * -0.169 + rgb.g * -0.331 + rgb.b *  0.5    + 0.5,
          rgb.r *  0.5   + rgb.g * -0.419 + rgb.b * -0.081  + 0.5
        );
      }
  
      vec4 ProcessChromaKey(vec2 texCoord) {
        vec4 rgba = texture2D(tex, texCoord);
        float chromaDist = distance(RGBtoUV(texture2D(tex, texCoord).rgb), RGBtoUV(keyColor));
  
        float baseMask = chromaDist - similarity;
        float fullMask = pow(clamp(baseMask / smoothness, 0., 1.), 1.5);
        rgba.a = fullMask;
  
        float spillVal = pow(clamp(baseMask / spill, 0., 1.), 1.5);
        float desat = clamp(rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722, 0., 1.);
        rgba.rgb = mix(vec3(desat, desat, desat), rgba.rgb, spillVal);
  
        return rgba;
      }
  
      void main(void) {
        vec2 texCoord = vUv;
        gl_FragColor = ProcessChromaKey(texCoord);
      }
    </script>
  

    <script>
      AFRAME.registerShader('custom-shader', {
        init: function(data) {
          const video = document.getElementById('video')
          const texture = new THREE.VideoTexture(video)
          this.material = new THREE.ShaderMaterial( {

            uniforms: {

            tex: { value: texture },
            keyColor: {
                value: new THREE.Color(0x00ff00)
              },
              texWidth: {
                value: 1920
              },
              texHeight: {
                value: 1080
              },
              similarity: {
                value: 0.4
              },
              smoothness: {
                value: 0.08
              },
              spill: {
                value: 0.1
              }

            },

            vertexShader: document.getElementById( 'vertexShader' ).textContent,
            fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
            transparent: true

          });
        }
      });
    </script>
  </head>
  <body>
    <a-scene>
      <a-assets>
        <video id="video" autoplay loop="true" muted="true" crossOrigin="anonymous">
          <source src="./assets/mixkit-a-woman-talking-on-the-phone-on-a-green-screen-24388-medium.mp4" type='video/mp4'>
        </video>
      </a-assets>   
      <a-video material="shader: custom-shader;" webkit-playsinline playsinline position="0 0 -10" height="9" width="16" rotation="0 0 0"></a-video>
      <a-sky color="#ECECEC"></a-sky>
    </a-scene>
    <button id="start">Start</button>
    <script>
      const start = document.getElementById('start');
      const video = document.getElementById('video');
      start.addEventListener('click', () => {
        video.play();
      });
    </script>
  </body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.