Three.js Black Video CORS问题?

时间:2016-09-21 21:34:51

标签: three.js cross-domain webgl

我有一个长期持续存在的问题,有时会出现黑色视频,在移动设备上有时会出现Three.js纹理声音。

我一直在试图解决它的房子周围,这是我到目前为止:

if(!video || video == null){
    video = document.createElement( 'video' );
    source = document.createElement('source');

    video.crossOrigin = "anonymous";
    video.preload = 'auto';
    video.setAttribute('webkit-playsinline', 'true');
    source.setAttribute('type',"video/mp4");
}


if(isIOS() || isIE11())
  source.setAttribute('src',"http://" + document.domain + "/cdn/" + sceneObject.video);
    else
 source.setAttribute('src',cdnPrefix + "/" + sceneObject.video);

video.appendChild(source);
video.load();



(function () {

    THREE.noVideoTextureSupport = isIE11();


    THREE.VideoTexture = (function () {
        var _videoTexture = THREE.VideoTexture;
        var _ieVideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
            if (THREE.noVideoTextureSupport) {
                var scope = this;

                scope.video = video;
                scope.ctx2d = document.createElement('canvas').getContext('2d');
                var canvas = scope.ctx2d.canvas;
                canvas.width = 2048;
                canvas.height = 1024;

                scope.ctx2d.drawImage(scope.video, 0, 0, canvas.width, canvas.height);
                THREE.Texture.call( scope, scope.ctx2d.canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );

                scope.generateMipmaps = false;

                function update() {
                    requestAnimationFrame( update );
                    if ( video.readyState >= video.HAVE_CURRENT_DATA ) {
                        scope.ctx2d.drawImage(scope.video, 0, 0, canvas.width, canvas.height);
                        scope.needsUpdate = true;
                    }
                }

                update();
            }
        };
        return (THREE.noVideoTextureSupport ? _ieVideoTexture : _videoTexture);
    })();

    THREE.VideoTexture.prototype = Object.create( THREE.Texture.prototype );
    THREE.VideoTexture.prototype.constructor = THREE.VideoTexture;

})();



if(!isMobile)
    panoVideoPlay();
else if(!firstPlay)
    panoVideoPlay();
else{

    $('body').append('<div id="play-button" class="playButton"><i class="fa fa-play"></i></div>');
    $('#preloaderItems').remove();


    window.addEventListener('touchstart', function videoStart() {
        panoVideoPlay();
        $("body").scrollTop(1);
        $('#preloader').remove();
        if(firstPlay){
            $("#play-button").remove();
            firstPlay = false;
            showLoader();
        }

        this.removeEventListener('touchstart', videoStart);
    });
  }


 }

 function panoVideoPlay(){
   makeVideoPlayableInline(video);
   video.play();
  checkPlayBack();
 }



var checkPlayBack = function(event){
   console.log("panoVideo.checkPlayBack()");
   var panoPlayBackInterval = setInterval(function(){

     if (video.currentTime > 0 || video.readyState > 0){
       clearInterval(panoPlayBackInterval);
         hideLoader();
         showVideo(video);
     }
  },10);
 }

  function showVideo(video){
console.log("panoVideo.showVideo()");
geometry = new THREE.SphereGeometry( 500, 60, 40 );

texture = new THREE.VideoTexture( video );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;

material   = new THREE.MeshBasicMaterial( { map : texture } );

panoVideoMesh = new THREE.Mesh( geometry, material );
panoVideoMesh.scale.x = -1;
panoVideoMesh.rotation.y = Math.PI / 2;


loadScene();
scene.remove(box);
scene.add(panoVideoMesh);
addLights();
}

视频在FFMPEG

中编码
  

out.mp4 -vcodec libx264 -profile:v baseline -preset slow -pix_fmt yuv420p -b:v 5000k -maxrate 5000k -bufsize 2200k -s 1920:1080 -threads 0 -b:128k -movflags faststart out2K.mp4

正如你所看到的,我在IE和iOS上遇到了无数问题,所以我在IE上发现了一个讨厌的黑客攻击,我在Three.js论坛上发现了这个问题,对于iOS和IE我也是如此通过服务器从CDN代理文件,以解决我面临的无数安全问题。

Chrome通常很好(但我在三星S5上的Android上Chrome浏览器上有黑色屏幕声音报告),但是在Android Note 3上,我在这里遇到同样的问题Android Stock浏览器。

通常当出现错误时,每次渲染通常都会出现一个未识别的脚本错误。在没有Chrome的iOS和Android Stock浏览器上很难调试:检查!

在Android股票浏览器上,如果我使用CDN,我会收到黑色视频,声音和许多错误 - 如果我使用代理文件,我会收到黑屏并且没有加载..

我使用Amazon EC2作为服务器和CloudFront进行分发,在那里我遇到了跨域问题,我不得不诉诸Apache代理来通过EC2服务器提供文件。

我已经做了我能想到的让Cross Domain工作的一切,

S3具有以下CORS配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://*</AllowedOrigin>
        <AllowedOrigin>http://*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

CloudFront具有使用Origin,Access Control Headers&amp; amp;方法等。

我在服务器上设置了Mod_Headers .htaccess

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "http://cdn.example.com"
</IfModule> 

当我从主机中压缩文件时似乎没问题

即。

  

curl -I -H&#34;起源:http://example.com&#34; http://cdn.example.com/videofile.mp4

HTTP/1.1 200 OK
Content-Type: video/mp4
Content-Length: 38150681
Connection: keep-alive
Date: Wed, 21 Sep 2016 20:55:25 GMT
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Last-Modified: Fri, 08 Jul 2016 02:45:32 GMT
ETag: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
x-amz-meta-md5-hash: XXXXXXXXXXXXXXXXXXXXXXXXXX
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin
Age: 1094
X-Cache: Hit from cloudfront
Via: 1.1 XXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)
X-Amz-Cf-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

但是当我尝试另一种方式时

  

curl -I -H&#34;起源:http://cdn.example.com/videoFile.mp4&#34; http://example.com/file/from/java/server

我得到了

HTTP/1.1 405 Request method 'HEAD' not supported
Date: Wed, 21 Sep 2016 21:15:05 GMT
Server: Jetty(8.0.4.v20111024)
Access-Control-Allow-Origin: http://cdn.example.com
Access-Control-Allow-Credentials: true
Allow: GET
Content-Type: text/html;charset=ISO-8859-1
Cache-Control: must-revalidate,no-cache,no-store
Content-Length: 1431
Vary: User-Agent,Accept-Encoding
Connection: close

我不确定请求方法&#39; HEAD&#39;不支持将是一个问题。

我花了很多时间在这上面,而且我似乎已经到了某个地方但是现在还不知道下一步该尝试什么。

如果有人可以帮助我,我会非常感激!

1 个答案:

答案 0 :(得分:0)

crossorigin="anonymous"元素中添加video对我来说很有效。

例如:

<video src="https://video.url" loop muted playsinline crossorigin="anonymous" />