我是A-Frame的新手。我尝试制作一个演示,我在场景中放了一段视频。它在我的电脑上工作,但在我的移动设备上有一个黑色的飞机。这是屏幕截图和代码。
<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。但它不起作用。
有人知道怎么解决吗?谢谢。
我相信移动浏览器需要明确的“用户交互”,例如“点击”来播放视频。这是必需的,因为许多移动设备使用蜂窝数据,如果我在我的网站上嵌入一个 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>