WebGL:取消了Chrome中的视频网络请求?

时间:2016-12-04 02:44:48

标签: javascript google-chrome html5-video

我正在尝试将视频加载到纹理的webgl实现中。该实现适用于Firefox,但我得到一个铬错误,没有纹理:

INVALID_VALUE: texImage2D: no video

当我查看netowrk请求时,它会显示视频已在Chrome中取消。

时,我发现视频在HTML元素中正常播放
video = document.getElementById('video');

在JS中被禁用。但是,Chrome中的视频中有音频输入。 有什么想法吗?

init()和draw()是在JS的下半部分附近发生的一切。

HTML:

<html>
    <head>
            <script type="text/javascript" src="webgl-utils.js"></script>
            <script type="text/javascript" src="webgl-debug.js"></script>
            <script type="text/javascript" src="cuon-utils.js"></script>
            <script type="text/javascript" src="cuon-matrix.js"></script>
            <script type="text/javascript" src="prog5.js"></script>
            <script type="text/javascript" src="chest.js"></script>
            <script type="text/javascript" src="cube.js"></script>

    </head>
    <body onload="init()">
            <script id="vertexShader" type="x-shader/x-vertex">
                    precision mediump float;

                    uniform mat4 modelMatrix;
                    uniform mat4 viewMatrix;
                    uniform mat4 projectionMatrix;
                    uniform vec4 lightPosition;

                    attribute vec4 vertexPosition;  
                    attribute vec3 vertexNormal;
                    attribute vec2 vertexTexCoord;                              

                    varying vec3 fragmentNormal;
                    varying vec3 fragmentLight;
                    varying vec3 fragmentView;
                    varying vec4 fragmentPosition; 
                    varying vec2 fragmentTexCoord;                              

                    void main() {
                            mat4 modelViewMatrix = viewMatrix * modelMatrix;

                            vec4 p = modelViewMatrix * vertexPosition;
                            vec4 q = viewMatrix * lightPosition;                            

                            fragmentPosition    = vertexPosition; 
                            fragmentNormal      = normalize(mat3(modelViewMatrix) * vertexNormal);
                            fragmentLight       = normalize(vec3(q - p));
                            fragmentView        = normalize(vec3(-p));
                            fragmentTexCoord    = vertexTexCoord;               

                            gl_Position     = projectionMatrix * modelViewMatrix * vertexPosition;
                    }
            </script>
            <script id="lightingFragmentShader" type="x-shader/x-fragment">
                    precision mediump float;

                    varying vec3 fragmentNormal;
                    varying vec3 fragmentLight;
                    varying vec3 fragmentView;
                    varying vec4 fragmentPosition; 
                    varying vec2 fragmentTexCoord;

                    uniform sampler2D modelTexture;
                    uniform vec3 modelColor;
                    uniform vec3 lightColor;

                    void main() {
                            vec3 n = normalize(fragmentNormal);
                            vec3 l = normalize(fragmentLight);
                            vec3 v = normalize(fragmentView);
                            vec3 h = normalize(l + v);
                            vec4 modelColor          = texture2D(modelTexture, fragmentTexCoord);

                            float d = max(dot(l,n) , 0.0);
                            float s = pow(max(dot(h, n), 0.0), 10.0);

                            vec3 fragmentColor  = vec3(modelColor) * lightColor * d + lightColor * s;

                            gl_FragColor        = vec4(fragmentColor, 1.0); 
                    }
            </script> 
            <center>
                <canvas id="webgl" width="500px" height="500px">
                    This content requires <a href="http://get.webgl.org/">WebGL</a>
                </canvas>
                <font face ="Arial">
                    <br>
                    Light Source Position
                    <br>
                    X-AXIS<input id="x-light" type="range" min="-5.0" max="5.0" value="0" step="0.1" oninput="refresh()">
                    <br>
                    Y-AXIS <input id="y-light" type="range" min="-5.0" max="5.0" value="0" step="0.1" oninput="refresh()">
                    <br>
                    Z-AXIS<input id="z-light" type="range" min="-5.0" max="5.0" value="0" step="0.1" oninput="refresh()">
                </font>
            </center>
        <video id="video" src="Firefox.ogv" autoplay style="display:none;">
      Your browser doesn't appear to support the <code>&lt;video&gt;</code> element.
        </video>

    </body>
</html>

JS:

var gl;
var canvas;

var dragging = false;
var texShader;
var chestModel;

var xValue = 0;
var yValue = 0;
var zValue = 0;

var modelRotationX = 0;
var modelRotationY = 0;
var lastClientX;
var lastClientY;

var copyVideo;
var video;
var modelTexture;

//refresh function used to request animation frame after moving slider in HTML
function refresh(){
    xValue = document.getElementById("x-light").value;
    yValue = document.getElementById("y-light").value;
    zValue = document.getElementById("z-light").value;
    requestAnimationFrame(draw);
}

//define 'flatten' function to flatten tables to single array
function flatten(a) {    
    return a.reduce(function (b, v) { b.push.apply(b, v); return b }, [])   
}

//create tumble interaction functions to click and drag cube
function onmousedown(event){
    dragging    = true;
    lastClientX = event.clientX;
    lastClientY = event.clientY;
}

function onmouseup(event){ 
    dragging = false;
}

/*using clientX and clientY derived from click event, use to create modelX and Y 
rotation before passing to model matrices rotation transformations*/
function onmousemove(event){
    //console.log(event.clientX, event.clientY);
    if (dragging){  
        var dX = event.clientX - lastClientX;
        var dY = event.clientY - lastClientY;

        modelRotationY = modelRotationY + dX;
        modelRotationX = modelRotationX + dY;


        if (modelRotationX > 90.0){
            modelRotationX = 90.0;
        }

        if (modelRotationX < -90.0){
            modelRotationX = -90.0;
        }

    requestAnimationFrame(draw);
    }
     lastClientX = event.clientX;
     lastClientY = event.clientY;

}
function startVideo() {
  video.play();
  intervalID = setInterval(draw, 15);
}

function videoDone() {
  clearInterval(intervalID);
}


//define Shader object constructor function
function Shader(vertexId, fragmentId){

    this.program = createProgram(gl, document.getElementById( vertexId).text,
                                     document.getElementById(fragmentId).text);

    this.modelMatrixLocation         = gl.getUniformLocation(this.program, 'modelMatrix');
    this.viewMatrixLocation          = gl.getUniformLocation(this.program, 'viewMatrix');
    this.projectionMatrixLocation    = gl.getUniformLocation(this.program, 'projectionMatrix');
    this.vertexPositionLocation      = gl.getAttribLocation(this.program, 'vertexPosition'); 
    this.lightPositionLocation       = gl.getUniformLocation(this.program, 'lightPosition');
    this.modelColorLocation          = gl.getUniformLocation(this.program, 'modelColor');
    this.lightColorLocation          = gl.getUniformLocation(this.program, 'lightColor');
    this.vertexNormalLocation        = gl.getAttribLocation(this.program, 'vertexNormal');
    this.vertexTexCoordLocation      = gl.getAttribLocation(this.program, 'vertexTexCoord');

    gl.enableVertexAttribArray(this.vertexPositionLocation);
    gl.enableVertexAttribArray(this.vertexNormalLocation);
    gl.enableVertexAttribArray(this.vertexTexCoordLocation);
}

//define use() method for Shader objects
Shader.prototype.use = function(projectionMatrix, modelMatrix, viewMatrix){

    gl.useProgram(this.program);

    gl.uniformMatrix4fv(this.modelMatrixLocation, false, modelMatrix.elements);
    gl.uniformMatrix4fv(this.viewMatrixLocation, false, viewMatrix.elements);
    gl.uniformMatrix4fv(this.projectionMatrixLocation, false, projectionMatrix.elements);

    gl.uniform4f(this.lightPositionLocation, xValue, yValue, zValue, 0.0);
    gl.uniform3f(this.modelColorLocation, 0.6, 0.3, 0.2);
    gl.uniform3f(this.lightColorLocation, 1.0, 1.0, 1.0);
}

//define Model object constructor function
function Model(positions, triangles, normals, texCoords){
    //initialize buffer objects
    this.positionBuffer  = gl.createBuffer();
    this.triangleBuffer  = gl.createBuffer();
    this.normalsBuffer   = gl.createBuffer();
    this.texCoordBuffer  = gl.createBuffer();


    //copy vertex data from array in CPU onto GPU
    this.positionArray = new Float32Array(flatten(positions));
    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.positionArray, gl.STATIC_DRAW);    

    //copy triangle data from array in CPU onto GPU
    this.triangleArray = new Uint16Array(flatten(triangles));
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.triangleBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.triangleArray, gl.STATIC_DRAW);

    this.normalsArray = new Float32Array(flatten(normals));
    gl.bindBuffer(gl.ARRAY_BUFFER, this.normalsBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.normalsArray, gl.STATIC_DRAW);

    this.textCoordArray = new Float32Array(flatten(texCoords));
    gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.textCoordArray, gl.STATIC_DRAW);
}

//define draw() method for Model objects to bind barray buffers
Model.prototype.draw = function(shader){

    gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
    gl.vertexAttribPointer(shader.vertexPositionLocation, 3, gl.FLOAT, false, 0, 0);

    gl.bindBuffer(gl.ARRAY_BUFFER, this.normalsBuffer);
    gl.vertexAttribPointer(shader.vertexNormalLocation, 3, gl.FLOAT, false, 0, 0);

    gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);    
    gl.vertexAttribPointer(shader.vertexTexCoordLocation, 2, gl.FLOAT, false, 0, 0);


    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.triangleBuffer);
    gl.drawElements(gl.TRIANGLES, this.triangleArray.length, gl.UNSIGNED_SHORT, 0);


}

//initizlize texture object
function loadTexture(image, texture){
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    requestAnimationFrame(draw);                                                        
}


function init(){

    //initialize GL context
    canvas = document.getElementById('webgl');
    gl = getWebGLContext(canvas, false);

    canvas.onmousedown  = onmousedown;
    canvas.onmouseup    = onmouseup;
    canvas.onmousemove  = onmousemove;

    //instantiate shader objects for each defined shader
    texShader           = new Shader('vertexShader', 'lightingFragmentShader');    
    //instantiate model objects for each model
    chestModel          = new Model(chest.positions, chest.triangles, chest.normals, chest.texCoords);
    modelTexture    = gl.createTexture();


   video = document.getElementById('video');



   /*
     video.onload   = function() {
       loadTexture(video, modelTexture);
    } 
    */

     video.addEventListener("canplaythrough", startVideo, true);
    video.addEventListener("ended", videoDone, true);


    loadTexture(video, modelTexture);
    video.src = 'Firefox.ogv';
    video.crossOrigin  = "anonymous";       
    video.preload = "auto";
   //video.load();
   // video.play();



    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);                               
    gl.enable(gl.DEPTH_TEST);

    //request animation frame
    requestAnimationFrame(draw);    

}


function draw(){

    updateTexture();

    //compose matrices for transformations
    var viewMatrix          = new Matrix4();
    var projectionMatrix    = new Matrix4();  

    viewMatrix.translate(0.0, 0.0, -1.8);
    projectionMatrix.perspective(90, 1, 1, 10);

    //set color and refresh rendering for canvas       
    gl.clearColor(0.5, 0.5, 0.5, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    /*instantiate model matrices for each respective model 
      and draw models with applied shader*/
    var chestModelMatrix    = new Matrix4();
    chestModelMatrix.rotate(modelRotationX, 1, 0, 0 );
    chestModelMatrix.rotate(modelRotationY, 0, 1, 0 ); 
    chestModelMatrix.translate(0.0, 0.0, 0.0, 0.0 );

    //set uniform locations and apply shader to designated model
    texShader.use(projectionMatrix, chestModelMatrix, viewMatrix);    
    chestModel.draw(texShader);

}



function updateTexture() {
  gl.bindTexture(gl.TEXTURE_2D, modelTexture);
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
}

我可以在此处找到一些其他来源,例如Firefox.ogv和胸部模型:

https://github.com/TacoB0t/CSC43/tree/prog/prog5

我很好奇是否与我的元素有关:

<video id="video" src="Firefox.ogv" autoplay style="display:none;">
      Your browser doesn't appear to support the <code>&lt;video&gt;</code> element.
</video>

我也在我的JS中设置以下内容:

video = document.getElementById('video');
video.src = 'Firefox.ogv';

1 个答案:

答案 0 :(得分:2)

您最有可能获取网络请求已取消的消息,因为您正在加载2个视频。第一个视频在您的视频代码中以HTML格式指定

<video id="video" src="Firefox.ogv" ...

所以Chrome开始下载该视频

然后在JavaScript中使用此行替换

video.src = 'Firefox.ogv';

因此,chrome取消原始请求并开始通过JavaScript下载视频集。