2016-03-10 55 views
0

我即将创建一个带有cocoon.js和three.js的Android和IOS设备定向控制的全景360视频播放器。Three.js视频纹理映射低质量/分辨率

我已经成功构建了关于threejs.org上的示例的演示,但是却遇到了一个问题: 我的原始测试视频文件是4000x1618分辨率,只有30秒长。加载这个可以听到的声音,但没有图片。 但是,如果我尝试将文件转换为720x292,那么它在android和ios上都可以很好地工作! 不幸的是,这个较低的分辨率。视频文件的质量太差,但是如果我尝试加载一个更大的文件,它只会发出声音而没有任何图像。

我发现,在亚行logcat这些错误日志开始了电影的时候:

E/OMXNodeInstance( 124): setParameter(4b:Nvidia.h264.decode, ParamPortDefinition(0x2000001) 
W/ACodec ( 124): [OMX.Nvidia.h264.decode] setting nBufferCountActual to 13 failed: -1010 

我的代码:

<!DOCTYPE html> 
 
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 
 
<script src='cordova.js'></script> 
 
<script src='js/three.js'></script> 
 
<script src='js/OrbitControls.js'></script> 
 
<script src='js/PointerLockControls.js'></script> 
 
<script src='js/DeviceOrientationControls.js'></script> 
 
<script src='js/stats.min.js'></script> 
 
<body style='margin: 0px;; overflow: hidden; text-align:center;'> 
 
<div id="btn" style='background: red; width: 200px; height: 200px; position: absolute; z-index: 1000;' onclick="start_video()">START VIDEÓ</div> 
 
<script> 
 

 
var video = document.createElement('video'); 
 
video.loop = true; 
 
video.src = 'heroes-new-720p.mp4'; 
 

 
function start_video() { 
 
\t document.getElementById('btn').style.visibility = 'hidden'; 
 
\t video.play(); 
 
} 
 

 
window.addEventListener('load', function() { 
 
\t var renderer \t = new THREE.WebGLRenderer({ 
 
\t \t antialias \t : true, 
 
\t }); 
 
\t renderer.setClearColor(new THREE.Color('lightgrey'), 1) 
 
\t renderer.setSize(window.innerWidth, window.innerHeight); 
 
\t document.body.appendChild(renderer.domElement); 
 
\t var onRenderFcts= []; 
 
\t var scene \t = new THREE.Scene(); 
 
\t var camera \t = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.01, 1000); 
 
\t camera.position.z = 3; 
 

 
\t var texture = new THREE.VideoTexture(video); 
 
\t texture.minFilter = THREE.LinearFilter; 
 
\t texture.format = THREE.RGBFormat; 
 
\t texture.generateMipmaps = false; 
 

 
\t var controls \t = new THREE.OrbitControls(camera) 
 
\t controls.target.copy(scene.position) 
 
\t function onDeviceOrientation(event){ 
 
\t \t if(!event.alpha) \t return; 
 
\t \t controls.enabled \t = false 
 
\t \t controls = new THREE.DeviceOrientationControls(camera); 
 
\t \t controls.connect(); 
 
\t \t window.removeEventListener('deviceorientation', onDeviceOrientation, false); 
 
\t \t renderer.domElement.addEventListener('click', function(){ 
 
\t \t \t var domElement \t = renderer.domElement 
 
\t \t \t if(domElement.requestFullscreen) \t \t domElement.requestFullscreen(); 
 
\t \t \t else if(domElement.msRequestFullscreen) \t domElement.msRequestFullscreen(); 
 
\t \t \t else if(domElement.mozRequestFullScreen) \t domElement.mozRequestFullScreen(); 
 
\t \t \t else if(domElement.webkitRequestFullscreen) \t domElement.webkitRequestFullscreen(); 
 
\t \t }, false); 
 
\t } 
 
\t window.addEventListener('deviceorientation', onDeviceOrientation, false); 
 
\t onRenderFcts.push(function(){ 
 
\t \t controls.update() 
 
\t }) 
 

 
;(function(){ 
 
\t var geometry \t = new THREE.SphereGeometry(10, 32, 16); 
 
\t var material \t = new THREE.MeshBasicMaterial({ 
 
       // opacity   : 0.5, 
 
       // transparent  : true, 
 
       // side   : THREE.DoubleSide, 
 
\t \t \t \t map: texture 
 
     }); 
 
\t var mesh \t = new THREE.Mesh(geometry, material); 
 
\t mesh.scale.x \t = -1 
 
\t scene.add(mesh); 
 
})() 
 

 

 
\t onRenderFcts.push(function(){ 
 
\t \t onWindowResize(); 
 
\t \t renderable(); 
 
\t }) 
 
\t 
 
\t function renderable() { 
 
\t \t if (video.readyState === video.HAVE_ENOUGH_DATA) { 
 
\t \t \t renderer.render(scene, camera); 
 
\t \t } \t \t \t \t 
 
\t } 
 
\t 
 
\t function onWindowResize(){ 
 
\t \t renderer.setSize(window.innerWidth, window.innerHeight) 
 
\t \t camera.aspect \t = window.innerWidth/window.innerHeight 
 
\t \t camera.updateProjectionMatrix() \t \t 
 
\t } 
 
\t window.addEventListener('resize', onWindowResize, false) 
 
\t 
 
\t // run the rendering loop 
 
\t var lastTimeMsec= null 
 
\t requestAnimationFrame(function animate(nowMsec){ 
 
\t \t // keep looping 
 
\t \t requestAnimationFrame(animate); 
 
\t \t // measure time 
 
\t \t lastTimeMsec \t = lastTimeMsec || nowMsec-1000/60 
 
\t \t var deltaMsec \t = Math.min(200, nowMsec - lastTimeMsec) 
 
\t \t lastTimeMsec \t = nowMsec 
 
\t \t // call each update function 
 
\t \t onRenderFcts.forEach(function(onRenderFct){ 
 
\t \t \t onRenderFct(deltaMsec/1000, nowMsec/1000) 
 
\t \t }) 
 
\t }) 
 
}) 
 
</script> 
 
</body>

UPDATE: 从那时起,我想通了,在问题不是视频分辨率本身,而是尺寸。我创建了一个运行良好的原始视频的1920x1080版本,所以困扰我的唯一事情就是质量。即使是16000 kbps的全高清视频,在我的Nexus 7和iPad 4上看起来都非常像素,我相信它应该更好......

+0

代码在浏览器中工作吗?在我看来,它可能与cocoon.js相关,而不是three.js – 2pha

+0

感谢您的评论!那么,我不确定我如何在浏览器中测试它。与“常规”phonegap/cordova应用程序不同,Cocoon开发人员应用程序只是封装了我的源代码并启动了应用程序,但我无法看到在浏览器中测试它的方式。如果你能告诉我如何做到这一点,我将非常感激,因为现在我只能通过cocoon开发人员应用程序启动应用程序,并观看logcat出错。从那时起,我已经更新了我的初始帖子,现在只有图像质量是困扰我... – fmarton

回答

2

好吧,最后我想通了,我的测试设备(Moto G,Nexus 7,iPad4,HTC m8)可以在尺寸为1920x1080的three.js球体中处理视频纹理。我不确定原因,但是我发现了一篇关于全景视频分辨率的非常有趣的文章,它也突出了质量问题。在360度视频中,120度全高清视频的2K宽度变为682像素宽度,所以这就是为什么我发现我的视频质量令人不满意的原因。

这里的文章,如果有人有兴趣:

http://www.360heros.com/2015/02/4k-vr-360-video-what-is-it-and-how-can-i-produce-it/

+0

为了你的纹理限制在webgl结帐http://alteredqualia.com/tmp/webgl-maxparams-test/和http: //codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/可能这会回答你在移动设备上的纹理限制 –

+0

非常有用的文章,谢谢! – fmarton

0

它不是threejs也没有相关cocoonjs。 分辨率高于1080p对手机屏幕没有意义(除了你的用例),所以硬件不支持它(在大多数情况下)。 您可以检查的是,如果h264配置文件符合您的视频文件的分辨率。特殊的iPhone在编码错误的情况下非常挑剔!