import * as THREE from 'three/webgpu';
/**
* Provide basic functionality to display video as texture.
* VideoTexture is used for creating and updating a video projected onto a Three.js texture
*
* @class
* @param {Object} containerIn - Container to create the renderer on.
* @author Alan Wu
* @return {VideoHandler}
*/
const VideoHandler = function (srcIn) {
var _this = this;
this.video = undefined;
this.videoTexture = undefined;
var src = srcIn;
var lastTime = 0;
var lastUpdate = 0;
var frameRate = 30;
var videoPlaneLoadedFlag = false;
var lastPlayPos = 0;
var currentPlayPos = 0;
var bufferingDetected = false;
var checkBuffering = function (delta, playAnimation) {
currentPlayPos = _this.video.currentTime;
// checking offset should be at most the check interval
// but allow for some margin
var offset = delta - 0.02;
// if no buffering is currently detected,
// and the position does not seem to increase
// and the _this.video isn't manually paused...
if (!bufferingDetected && currentPlayPos < lastPlayPos + offset && !_this.video.paused) {
bufferingDetected = true;
}
// if we were buffering but the _this.video has advanced,
// then there is no buffering
if (bufferingDetected && currentPlayPos > lastPlayPos + offset && !_this.video.paused) {
bufferingDetected = false;
}
lastPlayPos = currentPlayPos;
};
var initialise = function () {
if (document) {
_this.video = document.createElement('video');
_this.video.crossOrigin = 'anonymous';
_this.video.src = src;
_this.video.load();
_this.video.loop = true;
}
};
this.setMorphTime = function (time, duration) {
let actualTime = (time / duration) * _this.video.duration;
if (!Number.isFinite(actualTime)) {
actualTime = 0.0;
}
_this.video.currentTime = actualTime;
};
// videoPlaneLoaded connects the video to the video texture once it has loaded
this.getVideoDuration = function () {
return _this.video.duration;
};
this.createCanvasVideoTexture = function () {
_this.videoTexture = new THREE.VideoTexture(_this.video);
_this.videoTexture.minFilter = THREE.LinearFilter;
_this.videoTexture.magFilter = THREE.LinearFilter;
_this.video.currentTime = 0;
return _this.videoTexture;
};
this.getCurrentTime = function (duration) {
if (_this.video) return duration * (_this.video.currentTime / _this.video.duration);
else return 0;
};
this.isReadyToPlay = function () {
// video.readyState 3 means we have data to load for the current time and foreseeable future
if (_this.video && _this.video.readyState >= 3) {
return true;
}
return false;
};
//this should be handle by scene... check the sync at
initialise();
};
export { VideoHandler };