1 Star 0 Fork 56

jinzhexian / vr-stream-web-player

forked from lhbxxx / vr-stream-web-player 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
index.html 26.63 KB
一键复制 编辑 Web IDE 原始数据 按行查看 历史
jinzhexian 提交于 2020-09-07 10:47 . VR 调试
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
<!DOCTYPE html>
<html lang="en">
<head>
<title>Web VR boilerplate</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<style>
body {
width: 100%;
height: 100%;
background-color: #000;
color: #fff;
margin: 0px;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body></body>
<script>
/*
* Debug parameters.
*/
WebVRConfig = {
/**
* webvr-polyfill configuration
*/
// Forces availability of VR mode.
//FORCE_ENABLE_VR: true, // Default: false.
// Complementary filter coefficient. 0 for accelerometer, 1 for gyro.
// K_FILTER: 0.5, // Default: 0.98.
// How far into the future to predict during fast motion.
PREDICTION_TIME_S: 0.020,
// Default: 0.040 (in seconds).
// Flag to disable touch panner. In case you have your own touch controls
//TOUCH_PANNER_DISABLED: true, // Default: false.
// Enable yaw panning only, disabling roll and pitch. This can be useful for
// panoramas with nothing interesting above or below.
//YAW_ONLY: true, // Default: false.
// Enable the deprecated version of the API (navigator.getVRDevices).
//ENABLE_DEPRECATED_API: true, // Default: false.
// Scales the recommended buffer size reported by WebVR, which can improve
// performance. Making this very small can lower the effective resolution of
// your scene.
BUFFER_SCALE: 2.0,
// default: 1.0
// Allow VRDisplay.submitFrame to change gl bindings, which is more
// efficient if the application code will re-bind it's resources on the
// next frame anyway.
// Dirty bindings include: gl.FRAMEBUFFER_BINDING, gl.CURRENT_PROGRAM,
// gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING,
// and gl.TEXTURE_BINDING_2D for texture unit 0
// Warning: enabling this might lead to rendering issues.
//DIRTY_SUBMIT_FRAME_BINDINGS: true // default: false
};
</script>
<!--
A polyfill for Promises. Needed for IE and Edge.
-->
<!-- <script src="node_modules/es6-promise/dist/es6-promise.js"></script> -->
<!--
three.js 3d library
-->
<script src="src/three.min.js"></script>
<script src="src/stats.min.js"></script>
<script src="src/extra/Animation.js"></script>
<script src="src/extra/AnimationHandler.js"></script>
<script src="src/extra/KeyFrameAnimation.js"></script>
<script src="src/extra/ColladaLoader.js"></script>
<!-- <script src="src/extra/Detector.js"></script> -->
<script src="src/extra/dat.gui.min.js"></script>
<!--
VRControls.js acquires positional information from connected VR devices and applies the transformations to a three.js camera object.
-->
<script src="node_modules/three/examples/js/controls/VRControls.js"></script>
<!--
VREffect.js handles stereo camera setup and rendering.
-->
<script src="node_modules/three/examples/js/effects/VREffect.js"></script>
<!--
A polyfill for WebVR using the Device{Motion,Orientation}Event API.
-->
<script src="node_modules/webvr-polyfill/build/webvr-polyfill.js"></script>
<!--
Helps enter and exit VR mode, provides best practices while in VR.
-->
<script src="build/webvr-manager.js"></script>
<script src="src/jquery-3.1.1.min.js"></script>
<video id="video" autoplay="true" loop="false" hidden="hidden" src="vr_style_s.mp4" muted webkit-playsinline></video>
<video id="video_content" hidden="hidden" src="dd.mp4" autoplay="true" loop="false" webkit-playsinline></video>
<video id="video2" hidden="hidden" webkit-playsinline></video>
<script type="x-shader/x-vertex" id="vertexShader">
uniform sampler2D uSampler;
varying mediump vec4 vDirection;
void main() {
vec4 outExtraPixel = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
gl_Position = outExtraPixel;
vDirection = vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
precision mediump float;
#define PI 3.1415926535897932384626433832795
uniform sampler2D uSampler;
uniform sampler2D uSource;
uniform float uRotate;
uniform float uTop;
uniform float uScale;
uniform float uDiff;
varying mediump vec4 vDirection;
mediump vec4 samplerColor(mediump vec3 direction){
mediump float theta = atan(direction.x, -1.0 * direction.z);
mediump float phi = atan(direction.y, length(direction.xz));
if (abs(direction.x) < 1e-4 * abs(direction.z))
theta = 0.5*PI * (1.0 - sign(-1.0 * direction.z));
if (abs(direction.y) < 1e-4 * length(direction.xz))
phi = 0.0;
float radio = 9.5 / 3.5 ;
float base = uScale;
float left = 3.;
float top = uTop;
float dy = (phi / PI + 0.5)*base-top;
if(dy >1.||dy < 0.){
return vec4(0.,1.,0.,1.);
}
float dx=(mod(theta / (2.0*PI), 1.0))*base*radio-left;
if(dx >1. || dx < 0.){
return vec4(0.,1.,0.,1.);
}
return texture2D(uSampler,vec2(dx,dy));
}
mediump vec4 sourceColor(mediump vec3 direction){
mediump float theta = atan(direction.x, -1.0 * direction.z);
mediump float phi = atan(direction.y, length(direction.xz));
if (abs(direction.x) < 1e-4 * abs(direction.z))
theta = 0.5*PI * (1.0 - sign(-1.0 * direction.z));
if (abs(direction.y) < 1e-4 * length(direction.xz))
phi = 0.0;
float dx=mod(theta / (2.0*PI), 1.0);
float dy=phi / PI + 0.5;
dx+=uRotate;
if(dx>1.){
dx-=1.;
}
return texture2D(uSource,vec2(dx,dy));
}
void main() {
mediump vec3 direction = vec3(vDirection.xyz/vDirection.w);
float diff=uDiff;
float left=.45;
vec4 sourcePixel = sourceColor(direction);
vec4 extraPixel = samplerColor(direction);
vec4 outExtraPixel =extraPixel;
if(vDirection.x+left<0.){
outExtraPixel = sourcePixel;
}
if (extraPixel.g > 0.50 && extraPixel.r < 0.5 && extraPixel.b <0.5){
outExtraPixel = sourcePixel;
}else if(extraPixel.g>0.7&&extraPixel.r > 0.4 && extraPixel.r <0.65 && extraPixel.b>0.4&&extraPixel.b<0.65){
outExtraPixel = sourcePixel;
}else if(extraPixel.g>0.9&& extraPixel.r<0.1 &&extraPixel.b<0.1){
outExtraPixel = sourcePixel;
}else if((extraPixel.g/extraPixel.r)>diff&&(extraPixel.g/extraPixel.b)>diff){
outExtraPixel = sourcePixel;
}else if(extraPixel.r == 0.0 && extraPixel.g == 0.0 && extraPixel.b == 0.0){
outExtraPixel = sourcePixel;
}
gl_FragColor= outExtraPixel;
}
</script>
<script>
// Setup three.js WebGL renderer. Note: Antialiasing is a big performance hit.
// Only enable it if you actually need to.
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
// Append the canvas element created by the renderer to document body element.
document.body.appendChild(renderer.domElement);
// Create a three.js scene.
var scene = new THREE.Scene();
// Create a three.js camera.
var camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,10000);
// Apply VR headset positional data to camera.
var controls = new THREE.VRControls(camera);
controls.standing = true;
// Apply VR stereo rendering to renderer.
var effect = new THREE.VREffect(renderer);
effect.setSize(window.innerWidth, window.innerHeight);
// Add a repeating grid as a skybox.
var boxSize = 1;
video = document.getElementById('video');
texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
function getCubeBox() {
var geometry = new THREE.CubeGeometry(20,20,20);
// cubeFaceVertexUvs
var originUv = [[new THREE.Vector2(1,1.0 / 2), new THREE.Vector2(1,0), new THREE.Vector2(2.0 / 3,1.0 / 2)], [new THREE.Vector2(1,0), new THREE.Vector2(2.0 / 3,0), new THREE.Vector2(2.0 / 3,1.0 / 2)]];
var originUvs = [];
for (var i = 0; i < 12; i++) {
var tUv = [];
var dx = (parseInt(i / 2) % 3) * 1.0 / 3;
var dy = parseInt(i / 6) * 1.0 / 2;
var index = (i + 1) % 2;
tUv[0] = new THREE.Vector2(originUv[index][0].x - dx,originUv[index][0].y + dy);
tUv[1] = new THREE.Vector2(originUv[index][1].x - dx,originUv[index][1].y + dy);
tUv[2] = new THREE.Vector2(originUv[index][2].x - dx,originUv[index][2].y + dy);
originUvs.push(tUv);
}
//* Place cubemap video faces in right places
for (var i = 0; i < 12; i++) {
geometry.faceVertexUvs[0][11 - i] = originUvs[i];
}
var temp1 = geometry.faceVertexUvs[0][0];
var temp2 = geometry.faceVertexUvs[0][1];
geometry.faceVertexUvs[0][0] = geometry.faceVertexUvs[0][2];
geometry.faceVertexUvs[0][1] = geometry.faceVertexUvs[0][3];
geometry.faceVertexUvs[0][2] = temp1;
geometry.faceVertexUvs[0][3] = temp2;
//* Cubemap video faces are expanded 1.01 by ffmpeg transform,fix them here.
var fixP = 0.0018;
for (var i = 0; i < 12; i += 2) {
geometry.faceVertexUvs[0][i][0].y -= fixP;
geometry.faceVertexUvs[0][i][2].y -= fixP;
geometry.faceVertexUvs[0][i][0].x -= fixP;
geometry.faceVertexUvs[0][i][1].x -= fixP;
geometry.faceVertexUvs[0][i][1].y += fixP;
geometry.faceVertexUvs[0][i][2].x += fixP;
geometry.faceVertexUvs[0][i + 1][0].y += fixP;
geometry.faceVertexUvs[0][i + 1][1].y += fixP;
geometry.faceVertexUvs[0][i + 1][1].x += fixP;
geometry.faceVertexUvs[0][i + 1][2].x += fixP;
geometry.faceVertexUvs[0][i + 1][0].x -= fixP;
geometry.faceVertexUvs[0][i + 1][2].y -= fixP;
}
var cubebox = new THREE.Mesh(geometry,material);
cubebox.position.y = 1.5;
cubebox.position.x = 0;
cubebox.rotation.y = 2 * Math.PI;
return cubebox;
}
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.BackSide
});
// For high end VR devices like Vive and Oculus, take into account the stage
// parameters provided.
setupStage();
var plane_position = 0;
function addPlane(item) {
var img = item.pictures.img;
img = img.replace('http:/', '/u');
var texture = new THREE.TextureLoader().load(img);
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
var radio = 1.5;
var planeWidth = 0.4 * radio;
var planeHeight = 0.3 * radio;
var planeSpan = 0.05 * radio;
var geometry = new THREE.PlaneGeometry(planeWidth,planeHeight);
var material = new THREE.MeshBasicMaterial({
map: texture,
color: 0xffffff,
side: THREE.BackSide
});
var plane = new THREE.Mesh(geometry,material);
plane.name = "plane_" + plane_position;
plane.data = item;
plane.position.set(1.5, controls.userHeight - 0.5, 0.5);
plane.position.y += (plane_position % 4) * (planeHeight + planeSpan);
plane.position.z = parseInt(plane_position / 4) * (planeWidth + planeSpan);
plane_position += 1;
plane.rotation.y = Math.PI / 2;
scene.add(plane);
if (!playing) {
playing = true;
playRoom(item);
}
}
var liveItems;
function getPlanesData() {
var url = "/u/api.m.panda.tv/ajax_get_live_list_by_cate?cate=dota2&pageno=0&pagenum=12&__plat=h5";
$.getJSON(url, '', function(json) {
var items = json.data.items;
liveItems = items;
for (var i = 0; i < items.length; i++) {
var item = items[i];
addPlane(item);
}
});
}
// getPlanesData();
// monster (front animation)
var clock = new THREE.Clock();
var dae;
var mixer;
var dae_x = 4.09;
var dae_y = -1.42;
mixer = new THREE.AnimationMixer(scene);
function addMonster() {
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('models/monster.dae', function(collada) {
dae = collada.scene;
dae.traverse(function(child) {
if (child instanceof THREE.SkinnedMesh) {
var animation = new THREE.Animation(child,child.geometry.animation);
animation.play();
}
});
dae.scale.x = dae.scale.y = dae.scale.z = 0.001;
dae.position.x = dae_x;
dae.position.y = dae_y;
dae.position.z = -2;
dae.rotation.y = 1 * Math.PI;
dae.updateMatrix();
scene.add(dae);
scene.add(new THREE.AmbientLight(0xffffff));
});
}
addMonster();
var logo_text;
var logo;
function addAppgameLogo(text) {
var loader = new THREE.FontLoader();
loader.load('models/appgame.typeface.json', function(font) {
text = text.replace(/[^任玩堂游戏手机好超级知道你我他]/g, '');
var logo_text = new THREE.TextGeometry(text,{
font: font,
size: 0.1,
height: 0.01
});
if (logo) {
scene.remove(logo);
logo.geometry.dispose();
}
logo = new THREE.Mesh(logo_text,new THREE.MeshBasicMaterial());
logo.position.set(0, controls.userHeight, 0);
logo.position.z -= 2;
scene.add(logo);
});
}
$(function() {
addAppgameLogo('任玩堂');
});
// Chromakey content
var video_content;
var texture_content;
var v_texture;
var v_shaderMaterial;
var effectController = {
bg_rotate: 0.,
//background rotate
c_top: 0.79,
//content top
c_scale: 3.53,
monster_left: dae_x,
monster_top: dae_y,
video: 'vr_style_s',
text: '任玩堂',
c_diff: 1.11,
cubemapMode: false,
'bg_play/pause': function() {
if (video.paused) {
video.play();
} else {
video.pause();
}
},
'stream_panda': function() {
video_content.muted = true;
getPlanesData();
}
};
var changeCube = false;
function getContentVideo() {
var contentBox;
video_content = document.getElementById('video_content');
texture_content = new THREE.VideoTexture(video_content);
texture_content.minFilter = THREE.LinearFilter;
texture_content.magFilter = THREE.LinearFilter;
var geometry = new THREE.SphereBufferGeometry(50,32,32);
v_shaderMaterial = new THREE.ShaderMaterial({
uniforms: {
'uSampler': {
value: texture_content
},
'uSource': {
value: texture
},
'uRotate': {
value: effectController.bg_rotate
},
'uTop': {
value: effectController.c_top
},
'uScale': {
value: effectController.c_scale
},
'uDiff': {
value: effectController.c_diff
}
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
side: THREE.DoubleSide
});
v_shaderMaterial.extensions.derivatives = true;
contentBox = new THREE.Mesh(geometry,v_shaderMaterial);
contentBox.position.set(0, controls.userHeight, 0);
contentBox.rotation.y = 0.6 * Math.PI;
video_content.play();
return contentBox;
}
function setupGui() {
var gui = new dat.GUI();
var valuesChanger = function() {
// velocityUniforms.seperationDistance.value = effectController.seperation;
// velocityUniforms.alignmentDistance.value = effectController.alignment;
// velocityUniforms.cohesionDistance.value = effectController.cohesion;
// velocityUniforms.freedomFactor.value = effectController.freedom;
if (v_shaderMaterial) {
v_shaderMaterial.uniforms.uRotate.value = effectController.bg_rotate;
v_shaderMaterial.uniforms.uTop.value = effectController.c_top;
v_shaderMaterial.uniforms.uScale.value = effectController.c_scale;
v_shaderMaterial.uniforms.uDiff.value = effectController.c_diff;
dae_x = effectController.monster_left;
dae_y = effectController.monster_top;
$(video).attr('src', effectController.video + '.mp4');
addAppgameLogo(effectController.text);
if (changeCube != effectController.cubemapMode) {
if (effectController.cubemapMode) {
scene.remove(skybox);
skybox = getCubeBox();
scene.add(skybox);
} else {
scene.remove(skybox);
skybox = getContentVideo();
scene.add(skybox);
}
changeCube = effectController.cubemapMode;
}
}
};
valuesChanger();
gui.add(effectController, "bg_rotate", 0.0, 1.0, 0.01).onChange(valuesChanger);
gui.add(effectController, "c_diff", 0.0, 2.0, 0.01).onChange(valuesChanger);
gui.add(effectController, "c_top", -1.0, 10.0, 0.01).onChange(valuesChanger);
gui.add(effectController, "c_scale", 0.1, 10, 0.01).onChange(valuesChanger);
gui.add(effectController, "monster_left", -10, 10, 0.01).onChange(valuesChanger);
gui.add(effectController, "monster_top", -5, 5, 0.01).onChange(valuesChanger);
gui.add(effectController, "video", ['vr_style_s', '100m', 'lol']).onChange(valuesChanger);
gui.add(effectController, "cubemapMode").onChange(valuesChanger);
gui.add(effectController, "text").onChange(valuesChanger);
gui.add(effectController, "bg_play/pause");
gui.add(effectController, "stream_panda");
$(gui.domElement).on('touchstart,touchend,touchmove', function(event) {
console.log(event)
event.stopPropagation();
});
// $(gui.domElement).on('mousemove',function(event){
// event.stopPropagation();
// });
// gui.close();
}
$(setupGui);
skybox = getContentVideo();
scene.add(skybox);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var select = false;
var playing = false;
function onMouseUp(event) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
select = true;
}
window.addEventListener('mouseup', onMouseUp, false);
// Create a VR manager helper to enter and exit VR mode.
var params = {
hideButton: false,
// Default: false.
isUndistorted: false // Default: false.
};
var manager = new WebVRManager(renderer,effect,params);
// Kick off animation loop
requestAnimationFrame(animate);
window.addEventListener('resize', onResize, true);
window.addEventListener('vrdisplaypresentchange', onResize, true);
// Request animation frame loop function
var lastRender = 0;
function animate(timestamp) {
var delta = Math.min(timestamp - lastRender, 500);
lastRender = timestamp;
// Update VR headset position and apply to camera.
controls.update();
// dae_x-=0.01;
if (dae) {
dae.position.x = dae_x;
dae.position.y = dae_y;
}
// update the picking ray with the camera and mouse position
raycaster.setFromCamera(mouse, camera);
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects(scene.children);
if (select) {
select = false;
for (var i = 0; i < intersects.length; i++) {
var object = intersects[i].object;
if (object.data) {
playRoom(object.data);
}
}
}
var delta = clock.getDelta();
// animate Collada model
THREE.AnimationHandler.update(delta);
mixer.update(delta);
// Render the scene through the manager.
manager.render(scene, camera, timestamp);
requestAnimationFrame(animate);
}
function onResize(e) {
effect.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
var display;
// Get the HMD, and if we're dealing with something that specifies
// stageParameters, rearrange the scene.
function setupStage() {// navigator.getVRDisplays().then(function(displays) {
// if (displays.length > 0) {
// display = displays[0];
// if (display.stageParameters) {
// setStageDimensions(display.stageParameters);
// }
// }
// });
}
function setStageDimensions(stage) {
// Make the skybox fit the stage.
var material = skybox.material;
scene.remove(skybox);
// Size the skybox according to the size of the actual stage.
var geometry = new THREE.BoxGeometry(stage.sizeX,boxSize,stage.sizeZ);
skybox = new THREE.Mesh(geometry,material);
// Place it on the floor.
skybox.position.y = boxSize / 2;
scene.add(skybox);
}
//show fps
// var stats = new Stats();
// stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
// document.body.appendChild( stats.dom );
// function fps() {
// stats.begin();
// // monitored code goes here
// stats.end();
// requestAnimationFrame( fps );
// }
// requestAnimationFrame( fps );
function playRoom(room) {
console.log(room);
var url = "/u/room.api.m.panda.tv/index.php?method=room.shareapi&roomid=" + room.id;
$.getJSON(url, '', function(json) {
var urlVideo = json.data.videoinfo.address;
urlVideo = urlVideo.replace('http:/', '/u');
VRhls.loadSource(urlVideo);
VRhls.attachMedia(video2);
});
}
</script>
<script src="src/hls.min.js"></script>
<script>
var VRhls;
if (Hls.isSupported()) {
function playVideo(video) {
var texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
var geometry = new THREE.PlaneGeometry(3,1.8);
var material = new THREE.MeshBasicMaterial({
map: texture,
color: 0xffffff,
side: THREE.DoubleSide
});
var videoPlane = new THREE.Mesh(geometry,material);
videoPlane.position.set(0, controls.userHeight, -1.5);
videoPlane.position.x = 0;
scene.add(videoPlane);
}
var video2 = document.getElementById('video2');
var hls = new Hls();
var VRhls = hls;
hls.attachMedia(video2);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
// video2.play();
playVideo(video2);
});
}
$(renderer.domElement).on('click', function() {
video.play();
video2.play();
video_content.play();
});
</script>
</html>
JavaScript
1
https://gitee.com/jinzhexian/vr-stream-web-player.git
git@gitee.com:jinzhexian/vr-stream-web-player.git
jinzhexian
vr-stream-web-player
vr-stream-web-player
master

搜索帮助