上次看到jwplayer的3D播放,于是决定研究一下这种3D播放器到底是如何实现的,这篇文章记录了其中的一些要点。关于jwplayer的3D播放器实例可以参考下面的网页:
https://developer.jwplayer.com/jw-player/demos/innovation/3d-cube/
https://developer.jwplayer.com/jw-player/demos/innovation/360-video/
下面是其中一个截图:
查看其网页源码发现应该是基于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/