1. 程式人生 > >VR播放器研究: 基於 javascrip 和webGL初探

VR播放器研究: 基於 javascrip 和webGL初探

上次看到jwplayer的3D播放,於是決定研究一下這種3D播放器到底是如何實現的,這篇文章記錄了其中的一些要點。關於jwplayer的3D播放器例項可以參考下面的網頁:

下面是其中一個截圖:


檢視其網頁原始碼發現應該是基於javascrip技術,於是開始研究javascrip,在一個javascrip 線上編輯網站runjs.cn中無意看到一個demo,基於webgl實現的3d視訊,看效果和jwplayer的效果類似,於是研究其原始碼,終於有了一個基本認識。

實現類似3D視訊網頁播放,原來是基於webgl這個api,因為要實現滑鼠等互動,而且要實現360度瀏覽,所以,必然要用到類似opengl的開發api,這個在web中的opengl就是webgl 了,據說基於opengl es 2.0 衍生 出了web GL1.0, 有個網站可以看看你的瀏覽器是不是支援webgl: 

http://doesmybrowsersupportwebgl.com/

於是基於javascript中的webgl,寫一個類似的播放器似乎很簡單了;直接上程式碼

一個網頁html的:

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
		<meta name="author" content="Intptr" />
		<title>
			3D Video
		</title>
		<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/12/trgpcxmy/three.min.js">
		</script>
		<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/12/trgpcxmy/TrackballControls.js">
		</script>
	</head>
	<body>
		<div>
			<input type="file" id="file" />
			<input type="button" id="submit" value="確定" />
			<input type="button" id="play" value="播放" />
			<input type="button" id="pause" value="暫停" />
		</div>
		<div id="webgl">
                <script type="text/javascript" src="3dvideo.js"></script>
		</div>
	</body>
</html>

其中的3dvideo.js就是我們建立webgl場景的原始碼
window.onload = function() {
	var URL = window.URL || window.webkitURL;

	var video = document.createElement("video");
	video.width = 320;
	video.height = 240;

	var width = 800;
	var height = 600;
	var fov = 45;
	var near = 0.1;
	var far = 10000;

	var renderer = new THREE.WebGLRenderer({
		antialias: true
	});
	var camera = new THREE.PerspectiveCamera(fov, width / height, near, far);
	var scene = new THREE.Scene();
	scene.add(camera);
	camera.position.z = 500;
	renderer.setSize(width, height);
	document.getElementById("webgl").appendChild(renderer.domElement);
	var light = new THREE.AmbientLight(0xffffff);
	scene.add(light);
	var texture = new THREE.Texture(video);
	var material = new THREE.MeshLambertMaterial({
		map: texture,
		side: THREE.DoubleSide
	});
	var plane = new THREE.Mesh(new THREE.PlaneGeometry(320, 240), material);
	scene.add(plane);
	//var sphere = new THREE.Mesh(new THREE.SphereGeometry(300, 200, 200), material);  
      //sphere.overdraw = true;  
      //scene.add(sphere); 
	
	var trackball = new THREE.TrackballControls(camera, renderer.domElement);
	function render() {
		if (video.readyState == video.HAVE_ENOUGH_DATA) {
			texture.needsUpdate = true;
		}
		renderer.clear();
		renderer.render(scene, camera);
	}
	function animate() {
		trackball.update();
		render();
		requestAnimationFrame(animate);
	}
	animate();
	var file = document.getElementById("file");
	var old_url;
	document.getElementById("submit").onclick = function() {
		if (file.files.length) {
			if (old_url) {
				URL.revokeObjectURL(old_url);
			}
			old_url = URL.createObjectURL(file.files[0]);
			video.src = old_url;
			video.load();
			video.play();
		}
	};
	document.getElementById("play").onclick = function() {
		video.play();
	};
	document.getElementById("pause").onclick = function() {
		video.pause();
	};
}

上面在webgl中建立一個平面,載入視訊播放到平面上:

我在本機的nginx伺服器上實驗了一下,類似效果,速度還挺快:


沒錯,這是一個面,6個面同時渲染即可。

上面的網頁中還引入了兩個javascrip指令碼:其中一個重要的指令碼: three.min.js 

這就是webgl的開發環境了:下面這個網站能讓你更加清晰的認識webgl。具體請移步: http://www.hewebgl.com/