0

cocoon.js と three.js を使用して、Android と IOS 用のデバイスの向きを制御できるパノラマ 360 ビデオ プレーヤーを作成しようとしています。

threejs.org の例でデモを正常に作成しましたが、問題に苦しんでいます。元のテスト ビデオ ファイルの解像度は 4000x1618 で、長さはわずか 30 秒です。これをロードすると、音声は聞こえますが、画像は表示されません。ただし、ファイルを 720x292 に変換して試してみると、Android と iOS の両方で問題なく動作します。残念ながら、この低解像度。動画ファイルの品質が低すぎますが、これ以上大きいファイルを読み込もうとすると、音声のみになり、画像が表示されなくなります。

ムービーを開始すると、adb 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() {
	document.getElementById('btn').style.visibility = 'hidden';
	video.play();
}

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

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

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

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


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

更新: それ以来、問題はビデオの解像度自体ではなく、寸法にあることがわかりました。元のビデオの 1920x1080 バージョンを作成しましたが、正常に動作するので、気になるのは品質だけです。16000 kbps のフル HD ビデオでさえ、私の Nexus 7 と iPad 4 ではかなりピクセル化されているように見えます。

4

2 に答える 2

2

最終的に、テストしたデバイス (Moto G、Nexus 7、iPad4、HTC m8) のいずれも、1920x1080 より大きい three.js 球体のテクスチャとしてビデオを処理できないことがわかりました。理由はよくわかりませんが、パノラマ動画の解像度に関する非常に興味深い記事を見つけました。これは、品質の問題についても説明しています。

簡単に言うと、360 度ビデオでは、120 度のフル HD ビデオの 2K 幅が 682 ピクセル幅になるため、ビデオの品質が満足できないと感じたのはこのためです。

興味のある方は以下の記事をどうぞ。

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

于 2016-03-22T20:28:18.577 に答える
0

threejs も cocoonjs も関係ありません。1080p よりも高い解像度は、モバイル画面では意味がありません (ユース ケースを除く)。そのため、ハードウェアはそれをサポートしていません (ほとんどの場合)。確認できるのは、h264 プロファイルがビデオファイルの解像度に適合しているかどうかです。特別なiPhoneは、間違ったエンコーディングの場合に非常にうるさいです!

于 2016-03-23T20:52:40.653 に答える