@pixi/core
Version:
Core PixiJS
176 lines (173 loc) • 5.63 kB
JavaScript
import { Ticker } from '@pixi/ticker';
import { BaseImageResource } from './BaseImageResource.mjs';
const _VideoResource = class extends BaseImageResource {
constructor(source, options) {
options = options || {};
if (!(source instanceof HTMLVideoElement)) {
const videoElement = document.createElement("video");
videoElement.setAttribute("preload", "auto");
videoElement.setAttribute("webkit-playsinline", "");
videoElement.setAttribute("playsinline", "");
if (typeof source === "string") {
source = [source];
}
const firstSrc = source[0].src || source[0];
BaseImageResource.crossOrigin(videoElement, firstSrc, options.crossorigin);
for (let i = 0; i < source.length; ++i) {
const sourceElement = document.createElement("source");
let { src, mime } = source[i];
src = src || source[i];
const baseSrc = src.split("?").shift().toLowerCase();
const ext = baseSrc.slice(baseSrc.lastIndexOf(".") + 1);
mime = mime || _VideoResource.MIME_TYPES[ext] || `video/${ext}`;
sourceElement.src = src;
sourceElement.type = mime;
videoElement.appendChild(sourceElement);
}
source = videoElement;
}
super(source);
this.noSubImage = true;
this._autoUpdate = true;
this._isConnectedToTicker = false;
this._updateFPS = options.updateFPS || 0;
this._msToNextUpdate = 0;
this.autoPlay = options.autoPlay !== false;
this._load = null;
this._resolve = null;
this._onCanPlay = this._onCanPlay.bind(this);
this._onError = this._onError.bind(this);
if (options.autoLoad !== false) {
this.load();
}
}
update(_deltaTime = 0) {
if (!this.destroyed) {
const elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate;
this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);
if (!this._updateFPS || this._msToNextUpdate <= 0) {
super.update();
this._msToNextUpdate = this._updateFPS ? Math.floor(1e3 / this._updateFPS) : 0;
}
}
}
load() {
if (this._load) {
return this._load;
}
const source = this.source;
if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height) {
source.complete = true;
}
source.addEventListener("play", this._onPlayStart.bind(this));
source.addEventListener("pause", this._onPlayStop.bind(this));
if (!this._isSourceReady()) {
source.addEventListener("canplay", this._onCanPlay);
source.addEventListener("canplaythrough", this._onCanPlay);
source.addEventListener("error", this._onError, true);
} else {
this._onCanPlay();
}
this._load = new Promise((resolve) => {
if (this.valid) {
resolve(this);
} else {
this._resolve = resolve;
source.load();
}
});
return this._load;
}
_onError(event) {
this.source.removeEventListener("error", this._onError, true);
this.onError.emit(event);
}
_isSourcePlaying() {
const source = this.source;
return !source.paused && !source.ended && this._isSourceReady();
}
_isSourceReady() {
const source = this.source;
return source.readyState > 2;
}
_onPlayStart() {
if (!this.valid) {
this._onCanPlay();
}
if (this.autoUpdate && !this._isConnectedToTicker) {
Ticker.shared.add(this.update, this);
this._isConnectedToTicker = true;
}
}
_onPlayStop() {
if (this._isConnectedToTicker) {
Ticker.shared.remove(this.update, this);
this._isConnectedToTicker = false;
}
}
_onCanPlay() {
const source = this.source;
source.removeEventListener("canplay", this._onCanPlay);
source.removeEventListener("canplaythrough", this._onCanPlay);
const valid = this.valid;
this.resize(source.videoWidth, source.videoHeight);
if (!valid && this._resolve) {
this._resolve(this);
this._resolve = null;
}
if (this._isSourcePlaying()) {
this._onPlayStart();
} else if (this.autoPlay) {
source.play();
}
}
dispose() {
if (this._isConnectedToTicker) {
Ticker.shared.remove(this.update, this);
this._isConnectedToTicker = false;
}
const source = this.source;
if (source) {
source.removeEventListener("error", this._onError, true);
source.pause();
source.src = "";
source.load();
}
super.dispose();
}
get autoUpdate() {
return this._autoUpdate;
}
set autoUpdate(value) {
if (value !== this._autoUpdate) {
this._autoUpdate = value;
if (!this._autoUpdate && this._isConnectedToTicker) {
Ticker.shared.remove(this.update, this);
this._isConnectedToTicker = false;
} else if (this._autoUpdate && !this._isConnectedToTicker && this._isSourcePlaying()) {
Ticker.shared.add(this.update, this);
this._isConnectedToTicker = true;
}
}
}
get updateFPS() {
return this._updateFPS;
}
set updateFPS(value) {
if (value !== this._updateFPS) {
this._updateFPS = value;
}
}
static test(source, extension) {
return globalThis.HTMLVideoElement && source instanceof HTMLVideoElement || _VideoResource.TYPES.includes(extension);
}
};
let VideoResource = _VideoResource;
VideoResource.TYPES = ["mp4", "m4v", "webm", "ogg", "ogv", "h264", "avi", "mov"];
VideoResource.MIME_TYPES = {
ogv: "video/ogg",
mov: "video/quicktime",
m4v: "video/mp4"
};
export { VideoResource };
//# sourceMappingURL=VideoResource.mjs.map