mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-04 10:19:24 +02:00
1311 lines
49 KiB
JavaScript
1311 lines
49 KiB
JavaScript
import videojs from 'video.js';
|
|
import THREE$1 from 'three';
|
|
|
|
/**
|
|
* @author alteredq / http://alteredqualia.com/
|
|
* @author mr.doob / http://mrdoob.com/
|
|
*/
|
|
|
|
//in case it's running on node.js
|
|
var win = {};
|
|
|
|
if (typeof window !== "undefined") {
|
|
win = window;
|
|
}
|
|
|
|
var Detector = {
|
|
|
|
canvas: !!win.CanvasRenderingContext2D,
|
|
webgl: function () {
|
|
|
|
try {
|
|
|
|
var canvas = document.createElement('canvas');return !!(win.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')));
|
|
} catch (e) {
|
|
|
|
return false;
|
|
}
|
|
}(),
|
|
workers: !!win.Worker,
|
|
fileapi: win.File && win.FileReader && win.FileList && win.Blob,
|
|
|
|
Check_Version: function Check_Version() {
|
|
var rv = -1; // Return value assumes failure.
|
|
|
|
if (navigator.appName == 'Microsoft Internet Explorer') {
|
|
|
|
var ua = navigator.userAgent,
|
|
re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
|
|
|
|
if (re.exec(ua) !== null) {
|
|
rv = parseFloat(RegExp.$1);
|
|
}
|
|
} else if (navigator.appName == "Netscape") {
|
|
/// in IE 11 the navigator.appVersion says 'trident'
|
|
/// in Edge the navigator.appVersion does not say trident
|
|
if (navigator.appVersion.indexOf('Trident') !== -1) rv = 11;else {
|
|
var ua = navigator.userAgent;
|
|
var re = new RegExp("Edge\/([0-9]{1,}[\\.0-9]{0,})");
|
|
if (re.exec(ua) !== null) {
|
|
rv = parseFloat(RegExp.$1);
|
|
}
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
},
|
|
|
|
supportVideoTexture: function supportVideoTexture() {
|
|
//ie 11 and edge 12 doesn't support video texture.
|
|
var version = this.Check_Version();
|
|
return version === -1 || version >= 13;
|
|
},
|
|
|
|
isLiveStreamOnSafari: function isLiveStreamOnSafari(videoElement) {
|
|
//live stream on safari doesn't support video texture
|
|
var videoSources = [].slice.call(videoElement.querySelectorAll("source"));
|
|
var result = false;
|
|
if (videoElement.src && videoElement.src.indexOf('.m3u8') > -1) {
|
|
videoSources.push({
|
|
src: videoElement.src,
|
|
type: "application/x-mpegURL"
|
|
});
|
|
}
|
|
for (var i = 0; i < videoSources.length; i++) {
|
|
var currentVideoSource = videoSources[i];
|
|
if ((currentVideoSource.type === "application/x-mpegURL" || currentVideoSource.type === "application/vnd.apple.mpegurl") && /(Safari|AppleWebKit)/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)) {
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
|
|
getWebGLErrorMessage: function getWebGLErrorMessage() {
|
|
|
|
var element = document.createElement('div');
|
|
element.id = 'webgl-error-message';
|
|
|
|
if (!this.webgl) {
|
|
|
|
element.innerHTML = win.WebGLRenderingContext ? ['Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />', 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'].join('\n') : ['Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>', 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'].join('\n');
|
|
}
|
|
|
|
return element;
|
|
},
|
|
|
|
addGetWebGLMessage: function addGetWebGLMessage(parameters) {
|
|
|
|
var parent, id, element;
|
|
|
|
parameters = parameters || {};
|
|
|
|
parent = parameters.parent !== undefined ? parameters.parent : document.body;
|
|
id = parameters.id !== undefined ? parameters.id : 'oldie';
|
|
|
|
element = Detector.getWebGLErrorMessage();
|
|
element.id = id;
|
|
|
|
parent.appendChild(element);
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Created by yanwsh on 6/6/16.
|
|
*/
|
|
var MobileBuffering = {
|
|
prev_currentTime: 0,
|
|
counter: 0,
|
|
|
|
isBuffering: function isBuffering(currentTime) {
|
|
if (currentTime == this.prev_currentTime) this.counter++;else this.counter = 0;
|
|
this.prev_currentTime = currentTime;
|
|
if (this.counter > 10) {
|
|
//not let counter overflow
|
|
this.counter = 10;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Created by wensheng.yan on 4/4/16.
|
|
*/
|
|
function whichTransitionEvent() {
|
|
var t;
|
|
var el = document.createElement('fakeelement');
|
|
var transitions = {
|
|
'transition': 'transitionend',
|
|
'OTransition': 'oTransitionEnd',
|
|
'MozTransition': 'transitionend',
|
|
'WebkitTransition': 'webkitTransitionEnd'
|
|
};
|
|
|
|
for (t in transitions) {
|
|
if (el.style[t] !== undefined) {
|
|
return transitions[t];
|
|
}
|
|
}
|
|
}
|
|
|
|
function mobileAndTabletcheck() {
|
|
var check = false;
|
|
(function (a) {
|
|
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
|
|
})(navigator.userAgent || navigator.vendor || window.opera);
|
|
return check;
|
|
}
|
|
|
|
function isIos() {
|
|
return (/iPhone|iPad|iPod/i.test(navigator.userAgent)
|
|
);
|
|
}
|
|
|
|
function isRealIphone() {
|
|
return (/iPhone|iPod/i.test(navigator.platform)
|
|
);
|
|
}
|
|
|
|
//adopt code from: https://github.com/MozVR/vr-web-examples/blob/master/threejs-vr-boilerplate/js/VREffect.js
|
|
function fovToNDCScaleOffset(fov) {
|
|
var pxscale = 2.0 / (fov.leftTan + fov.rightTan);
|
|
var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5;
|
|
var pyscale = 2.0 / (fov.upTan + fov.downTan);
|
|
var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5;
|
|
return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] };
|
|
}
|
|
|
|
function fovPortToProjection(fov, rightHanded, zNear, zFar) {
|
|
|
|
rightHanded = rightHanded === undefined ? true : rightHanded;
|
|
zNear = zNear === undefined ? 0.01 : zNear;
|
|
zFar = zFar === undefined ? 10000.0 : zFar;
|
|
|
|
var handednessScale = rightHanded ? -1.0 : 1.0;
|
|
|
|
// start with an identity matrix
|
|
var mobj = new THREE.Matrix4();
|
|
var m = mobj.elements;
|
|
|
|
// and with scale/offset info for normalized device coords
|
|
var scaleAndOffset = fovToNDCScaleOffset(fov);
|
|
|
|
// X result, map clip edges to [-w,+w]
|
|
m[0 * 4 + 0] = scaleAndOffset.scale[0];
|
|
m[0 * 4 + 1] = 0.0;
|
|
m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale;
|
|
m[0 * 4 + 3] = 0.0;
|
|
|
|
// Y result, map clip edges to [-w,+w]
|
|
// Y offset is negated because this proj matrix transforms from world coords with Y=up,
|
|
// but the NDC scaling has Y=down (thanks D3D?)
|
|
m[1 * 4 + 0] = 0.0;
|
|
m[1 * 4 + 1] = scaleAndOffset.scale[1];
|
|
m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale;
|
|
m[1 * 4 + 3] = 0.0;
|
|
|
|
// Z result (up to the app)
|
|
m[2 * 4 + 0] = 0.0;
|
|
m[2 * 4 + 1] = 0.0;
|
|
m[2 * 4 + 2] = zFar / (zNear - zFar) * -handednessScale;
|
|
m[2 * 4 + 3] = zFar * zNear / (zNear - zFar);
|
|
|
|
// W result (= Z in)
|
|
m[3 * 4 + 0] = 0.0;
|
|
m[3 * 4 + 1] = 0.0;
|
|
m[3 * 4 + 2] = handednessScale;
|
|
m[3 * 4 + 3] = 0.0;
|
|
|
|
mobj.transpose();
|
|
|
|
return mobj;
|
|
}
|
|
|
|
function fovToProjection(fov, rightHanded, zNear, zFar) {
|
|
var DEG2RAD = Math.PI / 180.0;
|
|
|
|
var fovPort = {
|
|
upTan: Math.tan(fov.upDegrees * DEG2RAD),
|
|
downTan: Math.tan(fov.downDegrees * DEG2RAD),
|
|
leftTan: Math.tan(fov.leftDegrees * DEG2RAD),
|
|
rightTan: Math.tan(fov.rightDegrees * DEG2RAD)
|
|
};
|
|
|
|
return fovPortToProjection(fovPort, rightHanded, zNear, zFar);
|
|
}
|
|
|
|
function extend(superClass) {
|
|
var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
|
|
for (var method in superClass) {
|
|
if (superClass.hasOwnProperty(method) && !subClassMethods.hasOwnProperty(method)) {
|
|
subClassMethods[method] = superClass[method];
|
|
}
|
|
}
|
|
return subClassMethods;
|
|
}
|
|
|
|
function deepCopy(obj) {
|
|
var to = {};
|
|
|
|
for (var name in obj) {
|
|
to[name] = obj[name];
|
|
}
|
|
|
|
return to;
|
|
}
|
|
|
|
function getTouchesDistance(touches) {
|
|
return Math.sqrt((touches[0].clientX - touches[1].clientX) * (touches[0].clientX - touches[1].clientX) + (touches[0].clientY - touches[1].clientY) * (touches[0].clientY - touches[1].clientY));
|
|
}
|
|
|
|
var util = {
|
|
whichTransitionEvent: whichTransitionEvent,
|
|
mobileAndTabletcheck: mobileAndTabletcheck,
|
|
isIos: isIos,
|
|
isRealIphone: isRealIphone,
|
|
fovToProjection: fovToProjection,
|
|
extend: extend,
|
|
deepCopy: deepCopy,
|
|
getTouchesDistance: getTouchesDistance
|
|
};
|
|
|
|
/**
|
|
*
|
|
* (c) Wensheng Yan <yanwsh@gmail.com>
|
|
* Date: 10/30/16
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
var HAVE_CURRENT_DATA = 2;
|
|
|
|
var BaseCanvas = function BaseCanvas(baseComponent, THREE) {
|
|
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
|
|
return {
|
|
constructor: function init(player, options) {
|
|
this.settings = options;
|
|
//basic settings
|
|
this.width = player.el().offsetWidth, this.height = player.el().offsetHeight;
|
|
this.lon = options.initLon, this.lat = options.initLat, this.phi = 0, this.theta = 0;
|
|
this.videoType = options.videoType;
|
|
this.clickToToggle = options.clickToToggle;
|
|
this.mouseDown = false;
|
|
this.isUserInteracting = false;
|
|
|
|
//define render
|
|
this.renderer = new THREE.WebGLRenderer();
|
|
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
this.renderer.setSize(this.width, this.height);
|
|
this.renderer.autoClear = false;
|
|
this.renderer.setClearColor(0x000000, 1);
|
|
|
|
//define texture, on ie 11, we need additional helper canvas to solve rendering issue.
|
|
var video = settings.getTech(player);
|
|
this.supportVideoTexture = Detector.supportVideoTexture();
|
|
this.liveStreamOnSafari = Detector.isLiveStreamOnSafari(video);
|
|
if (this.liveStreamOnSafari) this.supportVideoTexture = false;
|
|
if (!this.supportVideoTexture) {
|
|
this.helperCanvas = player.addChild("HelperCanvas", {
|
|
video: video,
|
|
width: options.helperCanvas.width ? options.helperCanvas.width : this.width,
|
|
height: options.helperCanvas.height ? options.helperCanvas.height : this.height
|
|
});
|
|
var context = this.helperCanvas.el();
|
|
this.texture = new THREE.Texture(context);
|
|
} else {
|
|
this.texture = new THREE.Texture(video);
|
|
}
|
|
|
|
video.style.visibility = "hidden";
|
|
|
|
this.texture.generateMipmaps = false;
|
|
this.texture.minFilter = THREE.LinearFilter;
|
|
this.texture.maxFilter = THREE.LinearFilter;
|
|
this.texture.format = THREE.RGBFormat;
|
|
|
|
this.el_ = this.renderer.domElement;
|
|
this.el_.classList.add('vjs-video-canvas');
|
|
|
|
options.el = this.el_;
|
|
baseComponent.call(this, player, options);
|
|
|
|
this.attachControlEvents();
|
|
this.player().on("play", function () {
|
|
this.time = new Date().getTime();
|
|
this.startAnimation();
|
|
}.bind(this));
|
|
},
|
|
|
|
attachControlEvents: function attachControlEvents() {
|
|
this.on('mousemove', this.handleMouseMove.bind(this));
|
|
this.on('touchmove', this.handleTouchMove.bind(this));
|
|
this.on('mousedown', this.handleMouseDown.bind(this));
|
|
this.on('touchstart', this.handleTouchStart.bind(this));
|
|
this.on('mouseup', this.handleMouseUp.bind(this));
|
|
this.on('touchend', this.handleTouchEnd.bind(this));
|
|
if (this.settings.scrollable) {
|
|
this.on('mousewheel', this.handleMouseWheel.bind(this));
|
|
this.on('MozMousePixelScroll', this.handleMouseWheel.bind(this));
|
|
}
|
|
this.on('mouseenter', this.handleMouseEnter.bind(this));
|
|
this.on('mouseleave', this.handleMouseLease.bind(this));
|
|
this.on('dispose', this.handleDispose.bind(this));
|
|
},
|
|
|
|
handleDispose: function handleDispose(event) {
|
|
this.off('mousemove', this.handleMouseMove.bind(this));
|
|
this.off('touchmove', this.handleTouchMove.bind(this));
|
|
this.off('mousedown', this.handleMouseDown.bind(this));
|
|
this.off('touchstart', this.handleTouchStart.bind(this));
|
|
this.off('mouseup', this.handleMouseUp.bind(this));
|
|
this.off('touchend', this.handleTouchEnd.bind(this));
|
|
if (this.settings.scrollable) {
|
|
this.off('mousewheel', this.handleMouseWheel.bind(this));
|
|
this.off('MozMousePixelScroll', this.handleMouseWheel.bind(this));
|
|
}
|
|
this.off('mouseenter', this.handleMouseEnter.bind(this));
|
|
this.off('mouseleave', this.handleMouseLease.bind(this));
|
|
this.off('dispose', this.handleDispose.bind(this));
|
|
this.stopAnimation();
|
|
},
|
|
|
|
startAnimation: function startAnimation() {
|
|
this.render_animation = true;
|
|
this.animate();
|
|
},
|
|
|
|
stopAnimation: function stopAnimation() {
|
|
this.render_animation = false;
|
|
if (this.requestAnimationId) {
|
|
cancelAnimationFrame(this.requestAnimationId);
|
|
}
|
|
},
|
|
|
|
handleResize: function handleResize() {
|
|
this.width = this.player().el().offsetWidth, this.height = this.player().el().offsetHeight;
|
|
this.renderer.setSize(this.width, this.height);
|
|
},
|
|
|
|
handleMouseUp: function handleMouseUp(event) {
|
|
this.mouseDown = false;
|
|
if (this.clickToToggle) {
|
|
var clientX = event.clientX || event.changedTouches && event.changedTouches[0].clientX;
|
|
var clientY = event.clientY || event.changedTouches && event.changedTouches[0].clientY;
|
|
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
|
var diffX = Math.abs(clientX - this.onPointerDownPointerX);
|
|
var diffY = Math.abs(clientY - this.onPointerDownPointerY);
|
|
if (diffX < 0.1 && diffY < 0.1) this.player().paused() ? this.player().play() : this.player().pause();
|
|
}
|
|
},
|
|
|
|
handleMouseDown: function handleMouseDown(event) {
|
|
event.preventDefault();
|
|
var clientX = event.clientX || event.touches && event.touches[0].clientX;
|
|
var clientY = event.clientY || event.touches && event.touches[0].clientY;
|
|
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
|
this.mouseDown = true;
|
|
this.onPointerDownPointerX = clientX;
|
|
this.onPointerDownPointerY = clientY;
|
|
this.onPointerDownLon = this.lon;
|
|
this.onPointerDownLat = this.lat;
|
|
},
|
|
|
|
handleTouchStart: function handleTouchStart(event) {
|
|
if (event.touches.length > 1) {
|
|
this.isUserPinch = true;
|
|
this.multiTouchDistance = util.getTouchesDistance(event.touches);
|
|
}
|
|
this.handleMouseDown(event);
|
|
},
|
|
|
|
handleTouchEnd: function handleTouchEnd(event) {
|
|
this.isUserPinch = false;
|
|
this.handleMouseUp(event);
|
|
},
|
|
|
|
handleMouseMove: function handleMouseMove(event) {
|
|
var clientX = event.clientX || event.touches && event.touches[0].clientX;
|
|
var clientY = event.clientY || event.touches && event.touches[0].clientY;
|
|
if (typeof clientX === "undefined" || clientY === "undefined") return;
|
|
if (this.settings.clickAndDrag) {
|
|
if (this.mouseDown) {
|
|
this.lon = (this.onPointerDownPointerX - clientX) * 0.2 + this.onPointerDownLon;
|
|
this.lat = (clientY - this.onPointerDownPointerY) * 0.2 + this.onPointerDownLat;
|
|
}
|
|
} else {
|
|
var x = clientX - this.el_.offsetLeft;
|
|
var y = clientY - this.el_.offsetTop;
|
|
this.lon = x / this.width * 430 - 225;
|
|
this.lat = y / this.height * -180 + 90;
|
|
}
|
|
},
|
|
|
|
handleTouchMove: function handleTouchMove(event) {
|
|
//handle single touch event,
|
|
if (!this.isUserPinch || event.touches.length <= 1) {
|
|
this.handleMouseMove(event);
|
|
}
|
|
},
|
|
|
|
handleMobileOrientation: function handleMobileOrientation(event) {
|
|
if (typeof event.rotationRate === "undefined") return;
|
|
var x = event.rotationRate.alpha;
|
|
var y = event.rotationRate.beta;
|
|
var portrait = typeof event.portrait !== "undefined" ? event.portrait : window.matchMedia("(orientation: portrait)").matches;
|
|
var landscape = typeof event.landscape !== "undefined" ? event.landscape : window.matchMedia("(orientation: landscape)").matches;
|
|
var orientation = event.orientation || window.orientation;
|
|
|
|
if (portrait) {
|
|
this.lon = this.lon - y * this.settings.mobileVibrationValue;
|
|
this.lat = this.lat + x * this.settings.mobileVibrationValue;
|
|
} else if (landscape) {
|
|
var orientationDegree = -90;
|
|
if (typeof orientation != "undefined") {
|
|
orientationDegree = orientation;
|
|
}
|
|
|
|
this.lon = orientationDegree == -90 ? this.lon + x * this.settings.mobileVibrationValue : this.lon - x * this.settings.mobileVibrationValue;
|
|
this.lat = orientationDegree == -90 ? this.lat + y * this.settings.mobileVibrationValue : this.lat - y * this.settings.mobileVibrationValue;
|
|
}
|
|
},
|
|
|
|
handleMouseWheel: function handleMouseWheel(event) {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
},
|
|
|
|
handleMouseEnter: function handleMouseEnter(event) {
|
|
this.isUserInteracting = true;
|
|
},
|
|
|
|
handleMouseLease: function handleMouseLease(event) {
|
|
this.isUserInteracting = false;
|
|
if (this.mouseDown) {
|
|
this.mouseDown = false;
|
|
}
|
|
},
|
|
|
|
animate: function animate() {
|
|
if (!this.render_animation) return;
|
|
this.requestAnimationId = requestAnimationFrame(this.animate.bind(this));
|
|
if (!this.player().paused()) {
|
|
if (typeof this.texture !== "undefined" && (!this.isPlayOnMobile && this.player().readyState() >= HAVE_CURRENT_DATA || this.isPlayOnMobile && this.player().hasClass("vjs-playing"))) {
|
|
var ct = new Date().getTime();
|
|
if (ct - this.time >= 30) {
|
|
this.texture.needsUpdate = true;
|
|
this.time = ct;
|
|
}
|
|
if (this.isPlayOnMobile) {
|
|
var currentTime = this.player().currentTime();
|
|
if (MobileBuffering.isBuffering(currentTime)) {
|
|
if (!this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) {
|
|
this.player().addClass("vjs-panorama-mobile-inline-video-buffering");
|
|
}
|
|
} else {
|
|
if (this.player().hasClass("vjs-panorama-mobile-inline-video-buffering")) {
|
|
this.player().removeClass("vjs-panorama-mobile-inline-video-buffering");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.render();
|
|
},
|
|
|
|
render: function render() {
|
|
if (!this.isUserInteracting) {
|
|
var symbolLat = this.lat > this.settings.initLat ? -1 : 1;
|
|
var symbolLon = this.lon > this.settings.initLon ? -1 : 1;
|
|
if (this.settings.backToVerticalCenter) {
|
|
this.lat = this.lat > this.settings.initLat - Math.abs(this.settings.returnStepLat) && this.lat < this.settings.initLat + Math.abs(this.settings.returnStepLat) ? this.settings.initLat : this.lat + this.settings.returnStepLat * symbolLat;
|
|
}
|
|
if (this.settings.backToHorizonCenter) {
|
|
this.lon = this.lon > this.settings.initLon - Math.abs(this.settings.returnStepLon) && this.lon < this.settings.initLon + Math.abs(this.settings.returnStepLon) ? this.settings.initLon : this.lon + this.settings.returnStepLon * symbolLon;
|
|
}
|
|
}
|
|
this.lat = Math.max(this.settings.minLat, Math.min(this.settings.maxLat, this.lat));
|
|
this.lon = Math.max(this.settings.minLon, Math.min(this.settings.maxLon, this.lon));
|
|
this.phi = THREE.Math.degToRad(90 - this.lat);
|
|
this.theta = THREE.Math.degToRad(this.lon);
|
|
|
|
if (!this.supportVideoTexture) {
|
|
this.helperCanvas.update();
|
|
}
|
|
this.renderer.clear();
|
|
},
|
|
|
|
playOnMobile: function playOnMobile() {
|
|
this.isPlayOnMobile = true;
|
|
if (this.settings.autoMobileOrientation) window.addEventListener('devicemotion', this.handleMobileOrientation.bind(this));
|
|
},
|
|
|
|
el: function el() {
|
|
return this.el_;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Created by yanwsh on 4/3/16.
|
|
*/
|
|
|
|
var Canvas = function Canvas(baseComponent, THREE) {
|
|
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
|
|
var parent = BaseCanvas(baseComponent, THREE, settings);
|
|
|
|
return util.extend(parent, {
|
|
constructor: function init(player, options) {
|
|
parent.constructor.call(this, player, options);
|
|
|
|
this.VRMode = false;
|
|
//define scene
|
|
this.scene = new THREE.Scene();
|
|
//define camera
|
|
this.camera = new THREE.PerspectiveCamera(options.initFov, this.width / this.height, 1, 2000);
|
|
this.camera.target = new THREE.Vector3(0, 0, 0);
|
|
|
|
//define geometry
|
|
var geometry = this.videoType === "equirectangular" ? new THREE.SphereGeometry(500, 60, 40) : new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
|
if (this.videoType === "fisheye") {
|
|
var normals = geometry.attributes.normal.array;
|
|
var uvs = geometry.attributes.uv.array;
|
|
for (var i = 0, l = normals.length / 3; i < l; i++) {
|
|
var x = normals[i * 3 + 0];
|
|
var y = normals[i * 3 + 1];
|
|
var z = normals[i * 3 + 2];
|
|
|
|
var r = Math.asin(Math.sqrt(x * x + z * z) / Math.sqrt(x * x + y * y + z * z)) / Math.PI;
|
|
if (y < 0) r = 1 - r;
|
|
var theta = x == 0 && z == 0 ? 0 : Math.acos(x / Math.sqrt(x * x + z * z));
|
|
if (z < 0) theta = theta * -1;
|
|
uvs[i * 2 + 0] = -0.8 * r * Math.cos(theta) + 0.5;
|
|
uvs[i * 2 + 1] = 0.8 * r * Math.sin(theta) + 0.5;
|
|
}
|
|
geometry.rotateX(options.rotateX);
|
|
geometry.rotateY(options.rotateY);
|
|
geometry.rotateZ(options.rotateZ);
|
|
} else if (this.videoType === "dual_fisheye") {
|
|
var _normals = geometry.attributes.normal.array;
|
|
var _uvs = geometry.attributes.uv.array;
|
|
var _l = _normals.length / 3;
|
|
for (var _i = 0; _i < _l / 2; _i++) {
|
|
var _x2 = _normals[_i * 3 + 0];
|
|
var _y = _normals[_i * 3 + 1];
|
|
var _z = _normals[_i * 3 + 2];
|
|
|
|
var _r = _x2 == 0 && _z == 0 ? 1 : Math.acos(_y) / Math.sqrt(_x2 * _x2 + _z * _z) * (2 / Math.PI);
|
|
_uvs[_i * 2 + 0] = _x2 * options.dualFish.circle1.rx * _r * options.dualFish.circle1.coverX + options.dualFish.circle1.x;
|
|
_uvs[_i * 2 + 1] = _z * options.dualFish.circle1.ry * _r * options.dualFish.circle1.coverY + options.dualFish.circle1.y;
|
|
}
|
|
for (var _i2 = _l / 2; _i2 < _l; _i2++) {
|
|
var _x3 = _normals[_i2 * 3 + 0];
|
|
var _y2 = _normals[_i2 * 3 + 1];
|
|
var _z2 = _normals[_i2 * 3 + 2];
|
|
|
|
var _r2 = _x3 == 0 && _z2 == 0 ? 1 : Math.acos(-_y2) / Math.sqrt(_x3 * _x3 + _z2 * _z2) * (2 / Math.PI);
|
|
_uvs[_i2 * 2 + 0] = -_x3 * options.dualFish.circle2.rx * _r2 * options.dualFish.circle2.coverX + options.dualFish.circle2.x;
|
|
_uvs[_i2 * 2 + 1] = _z2 * options.dualFish.circle2.ry * _r2 * options.dualFish.circle2.coverY + options.dualFish.circle2.y;
|
|
}
|
|
geometry.rotateX(options.rotateX);
|
|
geometry.rotateY(options.rotateY);
|
|
geometry.rotateZ(options.rotateZ);
|
|
}
|
|
geometry.scale(-1, 1, 1);
|
|
//define mesh
|
|
this.mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map: this.texture }));
|
|
//this.mesh.scale.x = -1;
|
|
this.scene.add(this.mesh);
|
|
},
|
|
|
|
enableVR: function enableVR() {
|
|
this.VRMode = true;
|
|
if (typeof vrHMD !== 'undefined') {
|
|
var eyeParamsL = vrHMD.getEyeParameters('left');
|
|
var eyeParamsR = vrHMD.getEyeParameters('right');
|
|
|
|
this.eyeFOVL = eyeParamsL.recommendedFieldOfView;
|
|
this.eyeFOVR = eyeParamsR.recommendedFieldOfView;
|
|
}
|
|
|
|
this.cameraL = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000);
|
|
this.cameraR = new THREE.PerspectiveCamera(this.camera.fov, this.width / 2 / this.height, 1, 2000);
|
|
},
|
|
|
|
disableVR: function disableVR() {
|
|
this.VRMode = false;
|
|
this.renderer.setViewport(0, 0, this.width, this.height);
|
|
this.renderer.setScissor(0, 0, this.width, this.height);
|
|
},
|
|
|
|
handleResize: function handleResize() {
|
|
parent.handleResize.call(this);
|
|
this.camera.aspect = this.width / this.height;
|
|
this.camera.updateProjectionMatrix();
|
|
if (this.VRMode) {
|
|
this.cameraL.aspect = this.camera.aspect / 2;
|
|
this.cameraR.aspect = this.camera.aspect / 2;
|
|
this.cameraL.updateProjectionMatrix();
|
|
this.cameraR.updateProjectionMatrix();
|
|
}
|
|
},
|
|
|
|
handleMouseWheel: function handleMouseWheel(event) {
|
|
parent.handleMouseWheel(event);
|
|
// WebKit
|
|
if (event.wheelDeltaY) {
|
|
this.camera.fov -= event.wheelDeltaY * 0.05;
|
|
// Opera / Explorer 9
|
|
} else if (event.wheelDelta) {
|
|
this.camera.fov -= event.wheelDelta * 0.05;
|
|
// Firefox
|
|
} else if (event.detail) {
|
|
this.camera.fov += event.detail * 1.0;
|
|
}
|
|
this.camera.fov = Math.min(this.settings.maxFov, this.camera.fov);
|
|
this.camera.fov = Math.max(this.settings.minFov, this.camera.fov);
|
|
this.camera.updateProjectionMatrix();
|
|
if (this.VRMode) {
|
|
this.cameraL.fov = this.camera.fov;
|
|
this.cameraR.fov = this.camera.fov;
|
|
this.cameraL.updateProjectionMatrix();
|
|
this.cameraR.updateProjectionMatrix();
|
|
}
|
|
},
|
|
|
|
handleTouchMove: function handleTouchMove(event) {
|
|
parent.handleTouchMove.call(this, event);
|
|
if (this.isUserPinch) {
|
|
var currentDistance = util.getTouchesDistance(event.touches);
|
|
event.wheelDeltaY = (currentDistance - this.multiTouchDistance) * 2;
|
|
this.handleMouseWheel.call(this, event);
|
|
this.multiTouchDistance = currentDistance;
|
|
}
|
|
},
|
|
|
|
render: function render() {
|
|
parent.render.call(this);
|
|
this.camera.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
|
this.camera.target.y = 500 * Math.cos(this.phi);
|
|
this.camera.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
|
this.camera.lookAt(this.camera.target);
|
|
|
|
if (!this.VRMode) {
|
|
this.renderer.render(this.scene, this.camera);
|
|
} else {
|
|
var viewPortWidth = this.width / 2,
|
|
viewPortHeight = this.height;
|
|
if (typeof vrHMD !== 'undefined') {
|
|
this.cameraL.projectionMatrix = util.fovToProjection(this.eyeFOVL, true, this.camera.near, this.camera.far);
|
|
this.cameraR.projectionMatrix = util.fovToProjection(this.eyeFOVR, true, this.camera.near, this.camera.far);
|
|
} else {
|
|
var lonL = this.lon + this.settings.VRGapDegree;
|
|
var lonR = this.lon - this.settings.VRGapDegree;
|
|
|
|
var thetaL = THREE.Math.degToRad(lonL);
|
|
var thetaR = THREE.Math.degToRad(lonR);
|
|
|
|
var targetL = util.deepCopy(this.camera.target);
|
|
targetL.x = 500 * Math.sin(this.phi) * Math.cos(thetaL);
|
|
targetL.z = 500 * Math.sin(this.phi) * Math.sin(thetaL);
|
|
this.cameraL.lookAt(targetL);
|
|
|
|
var targetR = util.deepCopy(this.camera.target);
|
|
targetR.x = 500 * Math.sin(this.phi) * Math.cos(thetaR);
|
|
targetR.z = 500 * Math.sin(this.phi) * Math.sin(thetaR);
|
|
this.cameraR.lookAt(targetR);
|
|
}
|
|
// render left eye
|
|
this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.render(this.scene, this.cameraL);
|
|
|
|
// render right eye
|
|
this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.render(this.scene, this.cameraR);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
*
|
|
* (c) Wensheng Yan <yanwsh@gmail.com>
|
|
* Date: 10/21/16
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
var ThreeDCanvas = function ThreeDCanvas(baseComponent, THREE) {
|
|
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
|
|
var parent = BaseCanvas(baseComponent, THREE, settings);
|
|
return util.extend(parent, {
|
|
constructor: function init(player, options) {
|
|
parent.constructor.call(this, player, options);
|
|
//only show left part by default
|
|
this.VRMode = false;
|
|
//define scene
|
|
this.scene = new THREE.Scene();
|
|
|
|
var aspectRatio = this.width / this.height;
|
|
//define camera
|
|
this.cameraL = new THREE.PerspectiveCamera(options.initFov, aspectRatio, 1, 2000);
|
|
this.cameraL.target = new THREE.Vector3(0, 0, 0);
|
|
|
|
this.cameraR = new THREE.PerspectiveCamera(options.initFov, aspectRatio / 2, 1, 2000);
|
|
this.cameraR.position.set(1000, 0, 0);
|
|
this.cameraR.target = new THREE.Vector3(1000, 0, 0);
|
|
|
|
var geometryL = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
|
var geometryR = new THREE.SphereBufferGeometry(500, 60, 40).toNonIndexed();
|
|
|
|
var uvsL = geometryL.attributes.uv.array;
|
|
var normalsL = geometryL.attributes.normal.array;
|
|
for (var i = 0; i < normalsL.length / 3; i++) {
|
|
uvsL[i * 2 + 1] = uvsL[i * 2 + 1] / 2;
|
|
}
|
|
|
|
var uvsR = geometryR.attributes.uv.array;
|
|
var normalsR = geometryR.attributes.normal.array;
|
|
for (var i = 0; i < normalsR.length / 3; i++) {
|
|
uvsR[i * 2 + 1] = uvsR[i * 2 + 1] / 2 + 0.5;
|
|
}
|
|
|
|
geometryL.scale(-1, 1, 1);
|
|
geometryR.scale(-1, 1, 1);
|
|
|
|
this.meshL = new THREE.Mesh(geometryL, new THREE.MeshBasicMaterial({ map: this.texture }));
|
|
|
|
this.meshR = new THREE.Mesh(geometryR, new THREE.MeshBasicMaterial({ map: this.texture }));
|
|
this.meshR.position.set(1000, 0, 0);
|
|
|
|
this.scene.add(this.meshL);
|
|
|
|
if (options.callback) options.callback();
|
|
},
|
|
|
|
handleResize: function handleResize() {
|
|
parent.handleResize.call(this);
|
|
var aspectRatio = this.width / this.height;
|
|
if (!this.VRMode) {
|
|
this.cameraL.aspect = aspectRatio;
|
|
this.cameraL.updateProjectionMatrix();
|
|
} else {
|
|
aspectRatio /= 2;
|
|
this.cameraL.aspect = aspectRatio;
|
|
this.cameraR.aspect = aspectRatio;
|
|
this.cameraL.updateProjectionMatrix();
|
|
this.cameraR.updateProjectionMatrix();
|
|
}
|
|
},
|
|
|
|
handleMouseWheel: function handleMouseWheel(event) {
|
|
parent.handleMouseWheel(event);
|
|
// WebKit
|
|
if (event.wheelDeltaY) {
|
|
this.cameraL.fov -= event.wheelDeltaY * 0.05;
|
|
// Opera / Explorer 9
|
|
} else if (event.wheelDelta) {
|
|
this.cameraL.fov -= event.wheelDelta * 0.05;
|
|
// Firefox
|
|
} else if (event.detail) {
|
|
this.cameraL.fov += event.detail * 1.0;
|
|
}
|
|
this.cameraL.fov = Math.min(this.settings.maxFov, this.cameraL.fov);
|
|
this.cameraL.fov = Math.max(this.settings.minFov, this.cameraL.fov);
|
|
this.cameraL.updateProjectionMatrix();
|
|
if (this.VRMode) {
|
|
this.cameraR.fov = this.cameraL.fov;
|
|
this.cameraR.updateProjectionMatrix();
|
|
}
|
|
},
|
|
|
|
enableVR: function enableVR() {
|
|
this.VRMode = true;
|
|
this.scene.add(this.meshR);
|
|
this.handleResize();
|
|
},
|
|
|
|
disableVR: function disableVR() {
|
|
this.VRMode = false;
|
|
this.scene.remove(this.meshR);
|
|
this.handleResize();
|
|
},
|
|
|
|
render: function render() {
|
|
parent.render.call(this);
|
|
this.cameraL.target.x = 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
|
this.cameraL.target.y = 500 * Math.cos(this.phi);
|
|
this.cameraL.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
|
this.cameraL.lookAt(this.cameraL.target);
|
|
|
|
if (this.VRMode) {
|
|
var viewPortWidth = this.width / 2,
|
|
viewPortHeight = this.height;
|
|
this.cameraR.target.x = 1000 + 500 * Math.sin(this.phi) * Math.cos(this.theta);
|
|
this.cameraR.target.y = 500 * Math.cos(this.phi);
|
|
this.cameraR.target.z = 500 * Math.sin(this.phi) * Math.sin(this.theta);
|
|
this.cameraR.lookAt(this.cameraR.target);
|
|
|
|
// render left eye
|
|
this.renderer.setViewport(0, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.setScissor(0, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.render(this.scene, this.cameraL);
|
|
|
|
// render right eye
|
|
this.renderer.setViewport(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.setScissor(viewPortWidth, 0, viewPortWidth, viewPortHeight);
|
|
this.renderer.render(this.scene, this.cameraR);
|
|
} else {
|
|
this.renderer.render(this.scene, this.cameraL);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
|
|
return typeof obj;
|
|
} : function (obj) {
|
|
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var get = function get(object, property, receiver) {
|
|
if (object === null) object = Function.prototype;
|
|
var desc = Object.getOwnPropertyDescriptor(object, property);
|
|
|
|
if (desc === undefined) {
|
|
var parent = Object.getPrototypeOf(object);
|
|
|
|
if (parent === null) {
|
|
return undefined;
|
|
} else {
|
|
return get(parent, property, receiver);
|
|
}
|
|
} else if ("value" in desc) {
|
|
return desc.value;
|
|
} else {
|
|
var getter = desc.get;
|
|
|
|
if (getter === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
return getter.call(receiver);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var set = function set(object, property, value, receiver) {
|
|
var desc = Object.getOwnPropertyDescriptor(object, property);
|
|
|
|
if (desc === undefined) {
|
|
var parent = Object.getPrototypeOf(object);
|
|
|
|
if (parent !== null) {
|
|
set(parent, property, value, receiver);
|
|
}
|
|
} else if ("value" in desc && desc.writable) {
|
|
desc.value = value;
|
|
} else {
|
|
var setter = desc.set;
|
|
|
|
if (setter !== undefined) {
|
|
setter.call(receiver, value);
|
|
}
|
|
}
|
|
|
|
return value;
|
|
};
|
|
|
|
/**
|
|
* Created by yanwsh on 4/4/16.
|
|
*/
|
|
|
|
var Notice = function Notice(baseComponent) {
|
|
var element = document.createElement('div');
|
|
element.className = "vjs-video-notice-label";
|
|
|
|
return {
|
|
constructor: function init(player, options) {
|
|
if (_typeof(options.NoticeMessage) == "object") {
|
|
element = options.NoticeMessage;
|
|
options.el = options.NoticeMessage;
|
|
} else if (typeof options.NoticeMessage == "string") {
|
|
element.innerHTML = options.NoticeMessage;
|
|
options.el = element;
|
|
}
|
|
|
|
baseComponent.call(this, player, options);
|
|
},
|
|
|
|
el: function el() {
|
|
return element;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Created by wensheng.yan on 5/23/16.
|
|
*/
|
|
var HelperCanvas = function HelperCanvas(baseComponent) {
|
|
var element = document.createElement('canvas');
|
|
element.className = "vjs-video-helper-canvas";
|
|
return {
|
|
constructor: function init(player, options) {
|
|
this.videoElement = options.video;
|
|
this.width = options.width;
|
|
this.height = options.height;
|
|
|
|
element.width = this.width;
|
|
element.height = this.height;
|
|
element.style.display = "none";
|
|
options.el = element;
|
|
|
|
this.context = element.getContext('2d');
|
|
this.context.drawImage(this.videoElement, 0, 0, this.width, this.height);
|
|
baseComponent.call(this, player, options);
|
|
},
|
|
|
|
getContext: function getContext() {
|
|
return this.context;
|
|
},
|
|
|
|
update: function update() {
|
|
this.context.drawImage(this.videoElement, 0, 0, this.width, this.height);
|
|
},
|
|
|
|
el: function el() {
|
|
return element;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Created by yanwsh on 8/13/16.
|
|
*/
|
|
|
|
var VRButton = function VRButton(ButtonComponent) {
|
|
return {
|
|
constructor: function init(player, options) {
|
|
ButtonComponent.call(this, player, options);
|
|
},
|
|
|
|
buildCSSClass: function buildCSSClass() {
|
|
return "vjs-VR-control " + ButtonComponent.prototype.buildCSSClass.call(this);
|
|
},
|
|
|
|
handleClick: function handleClick() {
|
|
var canvas = this.player().getChild("Canvas");
|
|
!canvas.VRMode ? canvas.enableVR() : canvas.disableVR();
|
|
canvas.VRMode ? this.addClass("enable") : this.removeClass("enable");
|
|
canvas.VRMode ? this.player().trigger('VRModeOn') : this.player().trigger('VRModeOff');
|
|
},
|
|
|
|
controlText_: "VR"
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Created by yanwsh on 4/3/16.
|
|
*/
|
|
var runOnMobile = typeof window !== "undefined" ? util.mobileAndTabletcheck() : false;
|
|
|
|
// Default options for the plugin.
|
|
var defaults$1 = {
|
|
clickAndDrag: runOnMobile,
|
|
showNotice: true,
|
|
NoticeMessage: "Please use your mouse drag and drop the video.",
|
|
autoHideNotice: 3000,
|
|
//limit the video size when user scroll.
|
|
scrollable: true,
|
|
initFov: 75,
|
|
maxFov: 105,
|
|
minFov: 51,
|
|
//initial position for the video
|
|
initLat: 0,
|
|
initLon: -180,
|
|
//A float value back to center when mouse out the canvas. The higher, the faster.
|
|
returnStepLat: 0.5,
|
|
returnStepLon: 2,
|
|
backToVerticalCenter: !runOnMobile,
|
|
backToHorizonCenter: !runOnMobile,
|
|
clickToToggle: false,
|
|
|
|
//limit viewable zoom
|
|
minLat: -85,
|
|
maxLat: 85,
|
|
|
|
minLon: -Infinity,
|
|
maxLon: Infinity,
|
|
|
|
videoType: "equirectangular",
|
|
|
|
rotateX: 0,
|
|
rotateY: 0,
|
|
rotateZ: 0,
|
|
|
|
autoMobileOrientation: false,
|
|
mobileVibrationValue: runOnMobile && util.isIos() ? 0.022 : 1,
|
|
|
|
VREnable: true,
|
|
VRGapDegree: 2.5,
|
|
|
|
closePanorama: false,
|
|
|
|
helperCanvas: {},
|
|
|
|
dualFish: {
|
|
width: 1920,
|
|
height: 1080,
|
|
circle1: {
|
|
x: 0.240625,
|
|
y: 0.553704,
|
|
rx: 0.23333,
|
|
ry: 0.43148,
|
|
coverX: 0.913,
|
|
coverY: 0.9
|
|
},
|
|
circle2: {
|
|
x: 0.757292,
|
|
y: 0.553704,
|
|
rx: 0.232292,
|
|
ry: 0.4296296,
|
|
coverX: 0.913,
|
|
coverY: 0.9308
|
|
}
|
|
}
|
|
};
|
|
|
|
function playerResize(player) {
|
|
var canvas = player.getChild('Canvas');
|
|
return function () {
|
|
player.el().style.width = window.innerWidth + "px";
|
|
player.el().style.height = window.innerHeight + "px";
|
|
canvas.handleResize();
|
|
};
|
|
}
|
|
|
|
function fullscreenOnIOS(player, clickFn) {
|
|
var resizeFn = playerResize(player);
|
|
player.controlBar.fullscreenToggle.off("tap", clickFn);
|
|
player.controlBar.fullscreenToggle.on("tap", function fullscreen() {
|
|
var canvas = player.getChild('Canvas');
|
|
if (!player.isFullscreen()) {
|
|
//set to fullscreen
|
|
player.isFullscreen(true);
|
|
player.enterFullWindow();
|
|
resizeFn();
|
|
window.addEventListener("devicemotion", resizeFn);
|
|
} else {
|
|
player.isFullscreen(false);
|
|
player.exitFullWindow();
|
|
player.el().style.width = "";
|
|
player.el().style.height = "";
|
|
canvas.handleResize();
|
|
window.removeEventListener("devicemotion", resizeFn);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Function to invoke when the player is ready.
|
|
*
|
|
* This is a great place for your plugin to initialize itself. When this
|
|
* function is called, the player will have its DOM and child components
|
|
* in place.
|
|
*
|
|
* @function onPlayerReady
|
|
* @param {Player} player
|
|
* @param {Object} [options={}]
|
|
*/
|
|
var onPlayerReady = function onPlayerReady(player, options, settings) {
|
|
player.addClass('vjs-panorama');
|
|
if (!Detector.webgl) {
|
|
PopupNotification(player, {
|
|
NoticeMessage: Detector.getWebGLErrorMessage(),
|
|
autoHideNotice: options.autoHideNotice
|
|
});
|
|
if (options.callback) {
|
|
options.callback();
|
|
}
|
|
return;
|
|
}
|
|
player.addChild('Canvas', util.deepCopy(options));
|
|
var canvas = player.getChild('Canvas');
|
|
if (runOnMobile) {
|
|
var videoElement = settings.getTech(player);
|
|
if (util.isRealIphone()) {
|
|
var makeVideoPlayableInline = require('iphone-inline-video');
|
|
//ios 10 support play video inline
|
|
videoElement.setAttribute("playsinline", "");
|
|
makeVideoPlayableInline(videoElement, true);
|
|
}
|
|
if (util.isIos()) {
|
|
fullscreenOnIOS(player, settings.getFullscreenToggleClickFn(player));
|
|
}
|
|
player.addClass("vjs-panorama-mobile-inline-video");
|
|
player.removeClass("vjs-using-native-controls");
|
|
canvas.playOnMobile();
|
|
}
|
|
if (options.showNotice) {
|
|
player.on("playing", function () {
|
|
PopupNotification(player, util.deepCopy(options));
|
|
});
|
|
}
|
|
if (options.VREnable) {
|
|
player.controlBar.addChild('VRButton', {}, player.controlBar.children().length - 1);
|
|
}
|
|
canvas.hide();
|
|
player.on("play", function () {
|
|
canvas.show();
|
|
});
|
|
player.on("fullscreenchange", function () {
|
|
canvas.handleResize();
|
|
});
|
|
if (options.callback) options.callback();
|
|
};
|
|
|
|
var PopupNotification = function PopupNotification(player) {
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
NoticeMessage: ""
|
|
};
|
|
|
|
var notice = player.addChild('Notice', options);
|
|
|
|
if (options.autoHideNotice > 0) {
|
|
setTimeout(function () {
|
|
notice.addClass("vjs-video-notice-fadeOut");
|
|
var transitionEvent = util.whichTransitionEvent();
|
|
var hide = function hide() {
|
|
notice.hide();
|
|
notice.removeClass("vjs-video-notice-fadeOut");
|
|
notice.off(transitionEvent, hide);
|
|
};
|
|
notice.on(transitionEvent, hide);
|
|
}, options.autoHideNotice);
|
|
}
|
|
};
|
|
|
|
var plugin$1 = function plugin$1() {
|
|
var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
|
|
/**
|
|
* A video.js plugin.
|
|
*
|
|
* In the plugin function, the value of `this` is a video.js `Player`
|
|
* instance. You cannot rely on the player being in a "ready" state here,
|
|
* depending on how the plugin is invoked. This may or may not be important
|
|
* to you; if not, remove the wait for "ready"!
|
|
*
|
|
* @function panorama
|
|
* @param {Object} [options={}]
|
|
* An object of options left to the plugin author to define.
|
|
*/
|
|
var videoTypes = ["equirectangular", "fisheye", "3dVideo", "dual_fisheye"];
|
|
var panorama = function panorama(options) {
|
|
var _this = this;
|
|
|
|
if (settings.mergeOption) options = settings.mergeOption(defaults$1, options);
|
|
if (typeof settings._init === "undefined" || typeof settings._init !== "function") {
|
|
console.error("plugin must implement init function().");
|
|
return;
|
|
}
|
|
if (videoTypes.indexOf(options.videoType) == -1) options.videoType = defaults$1.videoType;
|
|
settings._init(options);
|
|
/* implement callback function when videojs is ready */
|
|
this.ready(function () {
|
|
onPlayerReady(_this, options, settings);
|
|
});
|
|
};
|
|
|
|
// Include the version number.
|
|
panorama.VERSION = '0.1.7';
|
|
|
|
return panorama;
|
|
};
|
|
|
|
function getTech(player) {
|
|
return player.tech({ IWillNotUseThisInPlugins: true }).el();
|
|
}
|
|
|
|
function getFullscreenToggleClickFn(player) {
|
|
return player.controlBar.fullscreenToggle.handleClick;
|
|
}
|
|
|
|
if (typeof window !== "undefined") {
|
|
var component = videojs.getComponent('Component');
|
|
|
|
var notice = Notice(component);
|
|
videojs.registerComponent('Notice', videojs.extend(component, notice));
|
|
|
|
var helperCanvas = HelperCanvas(component);
|
|
videojs.registerComponent('HelperCanvas', videojs.extend(component, helperCanvas));
|
|
|
|
var button = videojs.getComponent("Button");
|
|
var vrBtn = VRButton(button);
|
|
videojs.registerComponent('VRButton', videojs.extend(button, vrBtn));
|
|
|
|
// Register the plugin with video.js.
|
|
videojs.plugin('panorama', plugin$1({
|
|
_init: function _init(options) {
|
|
var canvas = options.videoType !== "3dVideo" ? Canvas(component, THREE$1, {
|
|
getTech: getTech
|
|
}) : ThreeDCanvas(component, THREE$1, {
|
|
getTech: getTech
|
|
});
|
|
videojs.registerComponent('Canvas', videojs.extend(component, canvas));
|
|
},
|
|
mergeOption: function mergeOption(defaults, options) {
|
|
return videojs.mergeOptions(defaults, options);
|
|
},
|
|
getTech: getTech,
|
|
getFullscreenToggleClickFn: getFullscreenToggleClickFn
|
|
}));
|
|
}
|
|
|
|
var plugin_es6 = function (player, options) {
|
|
return player.panorama(options);
|
|
};
|
|
|
|
export default plugin_es6;
|