Three.js 未捕获的安全错误:无法在“WebGLRenderingContext"上执行“texImage2D": [英] Three.js Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext':

查看:29
本文介绍了Three.js 未捕获的安全错误:无法在“WebGLRenderingContext"上执行“texImage2D":的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题源于上一期 html5 视频无法在 android 手机上播放.(Three.js WebGLRenderered 视频无法在安卓手机上播放)

正如 mrdoob 提到的,video.play() 应该通过用户发起的事件(例如点击)在移动设备上显式显示.完成此操作后,我已经能够播放该文件.但是我只能听到视频的音频部分.屏幕仍然是空白的.此外,我在开发控制台上看到以下异常.

未捕获的安全错误:无法在WebGLRenderingContext"上执行texImage2D":视频元素包含跨域数据,可能无法加载.三.min.js:507

正如您在下面的代码中看到的那样,我没有通过我的代码加载任何图像,并且错误似乎是在three.min.js 文件中抛出的.(下面的代码是 http://threejs.org/examples/#webgl_materials_video 使其在移动设备上运行)

请注意,这仅发生在移动设备上.该示例在网络上完美运行.

非常感谢您的帮助!

<html lang="zh-cn"><头><title>three.js webgl - 材料 - 视频</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><风格>身体 {背景色:#000;颜色:#fff;边距:0px;溢出:隐藏;字体系列:等宽;字体大小:13px;文字对齐:居中;字体粗细:粗体;文字对齐:居中;}一种 {颜色:#0078ff;}#信息{颜色:#fff;位置:绝对;顶部:0px;宽度:100%;填充:5px;z-索引:100;}</风格><身体><div id="信息"><a href="http://threejs.org" target="_blank">three.js</a>- webgl 视频演示.玩<a href="http://durian.blender.org/" target="_blank">sintel</a>预告片

<script src="js/three.min.js"></script><script src="js/shaders/ConvolutionShader.js"></script><script src="js/shaders/CopyShader.js"></script><script src="js/postprocessing/EffectComposer.js"></script><script src="js/postprocessing/RenderPass.js"></script><script src="js/postprocessing/MaskPass.js"></script><script src="js/postprocessing/BloomPass.js"></script><script src="js/postprocessing/ShaderPass.js"></script><script src="js/Detector.js"></script><video id="video" 自动播放循环样式="display:none"><source src="textures/sintel.mp4" type='video/mp4;编解码器="avc1.42E01E, mp4a.40.2"'><source src="textures/sintel.ogv" type='video/ogg;编解码器="theora, vorbis"'></视频><脚本>if (!Detector.webgl) Detector.addGetWebGLMessage();var 容器;var 相机、场景、渲染器、元素;var 视频、纹理、材质、网格;var作曲家;var mouseX = 0;变量鼠标Y = 0;var windowHalfX = window.innerWidth/2;var windowHalfY = window.innerHeight/2;var cube_count,网格 = [],材料 = [],xgrid = 20,ygrid = 10;在里面();动画();函数初始化(){container = document.createElement('div');document.body.appendChild(容器);camera = new THREE.PerspectiveCamera( 40, window.innerWidth/window.innerHeight, 1, 10000 );相机.位置.z = 500;场景 = 新的 THREE.Scene();var light = new THREE.DirectionalLight(0xffffff);light.position.set( 0.5, 1, 1 ).normalize();场景添加(光);renderer = new THREE.WebGLRenderer( { antialias: false } );renderer.setSize( window.innerWidth, window.innerHeight );元素=renderer.domElement;element.addEventListener('click', fullscreen, false);container.appendChild(renderer.domElement);video = document.getElementById('video');纹理 = 新的 THREE.Texture( 视频 );纹理.minFilter = THREE.LinearFilter;纹理.magFilter = THREE.LinearFilter;纹理格式 = THREE.RGBFormat;纹理.generateMipmaps = false;//var i, j, ux, uy, ox, oy,几何学,x 大小,y 大小;ux = 1/xgrid;uy = 1/ygrid;xsize = 480/xgrid;ysize = 204/ygrid;var 参数 = { 颜色:0xffffff,贴图:纹理 },material_base = new THREE.MeshLambertMaterial( 参数 );renderer.initMaterial(material_base,scene.__lights,scene.fog);立方体计数 = 0;for ( i = 0; i 200){for ( i = 0; i </html>

解决方案

正如这里所讨论的:https://code.google.com/p/chromium/issues/detail?id=173727视频"属性应该有这个设置:

video.setAttribute('crossorigin', 'anonymous');

但这本身并不能解决问题.这必须在 .load() 和 .play() 之前设置.我在 .load() 之后有这个,但它不起作用.所以这样做:

video.setAttribute('crossorigin', 'anonymous');video.src = "video/test.m4v";video.src = "video/test.mp4";视频加载();//必须在设置/更改源后调用视频播放();

此解决方案适用于由于上述安全错误而无法在移动设备上播放的视频.

<小时>

只是为了清楚crossorigin设置告诉浏览器向服务器请求使用视频的许可.服务器仍然必须授予该权限.如果服务器不授予权限设置 crossorigin 属性将不会让您使用视频.

This issue originated with the previous issue of html5 video not playing on android phones. (Three.js WebGLRenderered videos don't play on android phones)

And as mrdoob mentioned, video.play() should be explicit on mobile devices through user initiated events such as click. Having done this, I have been able to play the file. However I am only able to hear the audio part of the video. The screen is still blank. Moreover, I see the following exception on the dev console.

Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': The video element contains cross-origin data, and may not be loaded. three.min.js:507

I am not loading any image through my code as you can see in the code below and the error seems to be thrown in three.min.js file. (The code below is a slightly modified version of http://threejs.org/examples/#webgl_materials_video to make it run on mobile device)

Please note that this happens only on mobile device. The example works flawlessly on the web.

Your help is much appreciated!

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - materials - video</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                background-color: #000;
                color: #fff;
                margin: 0px;
                overflow: hidden;
                font-family:Monospace;
                font-size:13px;
                text-align:center;
                font-weight: bold;
                text-align:center;
            }

            a {
                color:#0078ff;
            }

            #info {
                color:#fff;
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
                z-index:100;
            }

        </style>
    </head>
    <body>

        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - webgl video demo. playing <a href="http://durian.blender.org/" target="_blank">sintel</a> trailer
        </div>

        <script src="js/three.min.js"></script>

        <script src="js/shaders/ConvolutionShader.js"></script>
        <script src="js/shaders/CopyShader.js"></script>

        <script src="js/postprocessing/EffectComposer.js"></script>
        <script src="js/postprocessing/RenderPass.js"></script>
        <script src="js/postprocessing/MaskPass.js"></script>
        <script src="js/postprocessing/BloomPass.js"></script>
        <script src="js/postprocessing/ShaderPass.js"></script>

        <script src="js/Detector.js"></script>

        <video id="video" autoplay loop style="display:none">
            <source src="textures/sintel.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
            <source src="textures/sintel.ogv" type='video/ogg; codecs="theora, vorbis"'>
        </video>

        <script>

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container;

            var camera, scene, renderer, element;

            var video, texture, material, mesh;

            var composer;

            var mouseX = 0;
            var mouseY = 0;

            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;

            var cube_count,

                meshes = [],
                materials = [],

                xgrid = 20,
                ygrid = 10;

            init();
            animate();

            function init() {

                container = document.createElement( 'div' );
                document.body.appendChild( container );

                camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
                camera.position.z = 500;

                scene = new THREE.Scene();

                var light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 0.5, 1, 1 ).normalize();
                scene.add( light );

                renderer = new THREE.WebGLRenderer( { antialias: false } );
                renderer.setSize( window.innerWidth, window.innerHeight );

                element=renderer.domElement;
                element.addEventListener('click', fullscreen, false);

                container.appendChild( renderer.domElement );

                video = document.getElementById( 'video' );

                texture = new THREE.Texture( video );
                texture.minFilter = THREE.LinearFilter;
                texture.magFilter = THREE.LinearFilter;
                texture.format = THREE.RGBFormat;
                texture.generateMipmaps = false;

                //

                var i, j, ux, uy, ox, oy,
                    geometry,
                    xsize, ysize;

                ux = 1 / xgrid;
                uy = 1 / ygrid;

                xsize = 480 / xgrid;
                ysize = 204 / ygrid;

                var parameters = { color: 0xffffff, map: texture },
                    material_base = new THREE.MeshLambertMaterial( parameters );

                renderer.initMaterial( material_base, scene.__lights, scene.fog );

                cube_count = 0;

                for ( i = 0; i < xgrid; i ++ )
                for ( j = 0; j < ygrid; j ++ ) {

                    ox = i;
                    oy = j;

                    geometry = new THREE.BoxGeometry( xsize, ysize, xsize );

                    change_uvs( geometry, ux, uy, ox, oy );

                    materials[ cube_count ] = new THREE.MeshLambertMaterial( parameters );

                    material = materials[ cube_count ];

                    material.hue = i/xgrid;
                    material.saturation = 1 - j/ygrid;

                    material.color.setHSL( material.hue, material.saturation, 0.5 );

                    mesh = new THREE.Mesh( geometry, material );

                    mesh.position.x =   ( i - xgrid/2 ) * xsize;
                    mesh.position.y =   ( j - ygrid/2 ) * ysize;
                    mesh.position.z = 0;

                    mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;

                    scene.add( mesh );

                    mesh.dx = 0.001 * ( 0.5 - Math.random() );
                    mesh.dy = 0.001 * ( 0.5 - Math.random() );

                    meshes[ cube_count ] = mesh;

                    cube_count += 1;

                }

                renderer.autoClear = false;

                document.addEventListener( 'mousemove', onDocumentMouseMove, false );

                // postprocessing

                var renderModel = new THREE.RenderPass( scene, camera );
                var effectBloom = new THREE.BloomPass( 1.3 );
                var effectCopy = new THREE.ShaderPass( THREE.CopyShader );

                effectCopy.renderToScreen = true;

                composer = new THREE.EffectComposer( renderer );

                composer.addPass( renderModel );
                composer.addPass( effectBloom );
                composer.addPass( effectCopy );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }
            function fullscreen() {

                video.play();
                console.log(video);
                  if (container.requestFullscreen) {
                    container.requestFullscreen();
                  } else if (container.msRequestFullscreen) {
                    container.msRequestFullscreen();
                  } else if (container.mozRequestFullScreen) {
                    container.mozRequestFullScreen();
                  } else if (container.webkitRequestFullscreen) {
                    container.webkitRequestFullscreen();
                  }
                }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );
                composer.reset();

            }

            function change_uvs( geometry, unitx, unity, offsetx, offsety ) {

                var faceVertexUvs = geometry.faceVertexUvs[ 0 ];

                for ( var i = 0; i < faceVertexUvs.length; i ++ ) {

                    var uvs = faceVertexUvs[ i ];

                    for ( var j = 0; j < uvs.length; j ++ ) {

                        var uv = uvs[ j ];

                        uv.x = ( uv.x + offsetx ) * unitx;
                        uv.y = ( uv.y + offsety ) * unity;

                    }

                }

            }


            function onDocumentMouseMove(event) {

                mouseX = ( event.clientX - windowHalfX );
                mouseY = ( event.clientY - windowHalfY ) * 0.3;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();

            }

            var h, counter = 1;

            function render() {

                var time = Date.now() * 0.00005;

                camera.position.x += ( mouseX - camera.position.x ) * 0.05;
                camera.position.y += ( - mouseY - camera.position.y ) * 0.05;

                camera.lookAt( scene.position );

                if ( video.readyState === video.HAVE_ENOUGH_DATA ) {

                    if ( texture ) texture.needsUpdate = true;

                }

                for ( i = 0; i < cube_count; i ++ ) {

                    material = materials[ i ];

                    h = ( 360 * ( material.hue + time ) % 360 ) / 360;
                    material.color.setHSL( h, material.saturation, 0.5 );

                }

                if ( counter % 1000 > 200 ) {

                    for ( i = 0; i < cube_count; i ++ ) {

                        mesh = meshes[ i ];

                        mesh.rotation.x += 10 * mesh.dx;
                        mesh.rotation.y += 10 * mesh.dy;

                        mesh.position.x += 200 * mesh.dx;
                        mesh.position.y += 200 * mesh.dy;
                        mesh.position.z += 400 * mesh.dx;

                    }

                }

                if ( counter % 1000 === 0 ) {

                    for ( i = 0; i < cube_count; i ++ ) {

                        mesh = meshes[ i ];

                        mesh.dx *= -1;
                        mesh.dy *= -1;

                    }

                }

                counter ++;

                renderer.clear();
                composer.render();

            }


        </script>

    </body>
</html>

解决方案

As discussed here: https://code.google.com/p/chromium/issues/detail?id=173727 the "video" attribute should have this set:

video.setAttribute('crossorigin', 'anonymous');

But this alone won't do the trick. This has to be set before .load() and .play(). I had this after .load() and it did not work. So do it like this:

video.setAttribute('crossorigin', 'anonymous');
video.src = "video/test.m4v";
video.src = "video/test.mp4";
video.load(); // must call after setting/changing source
video.play();

This is solution is for videos that don't play on mobile devices specifically due to the security error seen as above.


Just to be clear crossorigin settings tell the browser to ask the server for permission to use the video. The server still has to give that permission. If the server doesn't give permission setting the crossorigin attribute won't let you use the video.

这篇关于Three.js 未捕获的安全错误:无法在“WebGLRenderingContext"上执行“texImage2D":的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆