1 | "use strict";
|
2 | var ticker = require("@pixi/ticker"), BaseImageResource = require("./BaseImageResource.js");
|
3 | const _VideoResource = class _VideoResource2 extends BaseImageResource.BaseImageResource {
|
4 | |
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | constructor(source, options) {
|
18 | if (options = options || {}, !(source instanceof HTMLVideoElement)) {
|
19 | const videoElement = document.createElement("video");
|
20 | options.autoLoad !== !1 && videoElement.setAttribute("preload", "auto"), options.playsinline !== !1 && (videoElement.setAttribute("webkit-playsinline", ""), videoElement.setAttribute("playsinline", "")), options.muted === !0 && (videoElement.setAttribute("muted", ""), videoElement.muted = !0), options.loop === !0 && videoElement.setAttribute("loop", ""), options.autoPlay !== !1 && videoElement.setAttribute("autoplay", ""), typeof source == "string" && (source = [source]);
|
21 | const firstSrc = source[0].src || source[0];
|
22 | BaseImageResource.BaseImageResource.crossOrigin(videoElement, firstSrc, options.crossorigin);
|
23 | for (let i = 0; i < source.length; ++i) {
|
24 | const sourceElement = document.createElement("source");
|
25 | let { src, mime } = source[i];
|
26 | if (src = src || source[i], src.startsWith("data:"))
|
27 | mime = src.slice(5, src.indexOf(";"));
|
28 | else if (!src.startsWith("blob:")) {
|
29 | const baseSrc = src.split("?").shift().toLowerCase(), ext = baseSrc.slice(baseSrc.lastIndexOf(".") + 1);
|
30 | mime = mime || _VideoResource2.MIME_TYPES[ext] || `video/${ext}`;
|
31 | }
|
32 | sourceElement.src = src, mime && (sourceElement.type = mime), videoElement.appendChild(sourceElement);
|
33 | }
|
34 | source = videoElement;
|
35 | }
|
36 | super(source), this.noSubImage = !0, this._autoUpdate = !0, this._isConnectedToTicker = !1, this._updateFPS = options.updateFPS || 0, this._msToNextUpdate = 0, this.autoPlay = options.autoPlay !== !1, this._videoFrameRequestCallback = this._videoFrameRequestCallback.bind(this), this._videoFrameRequestCallbackHandle = null, this._load = null, this._resolve = null, this._reject = null, this._onCanPlay = this._onCanPlay.bind(this), this._onError = this._onError.bind(this), this._onPlayStart = this._onPlayStart.bind(this), this._onPlayStop = this._onPlayStop.bind(this), this._onSeeked = this._onSeeked.bind(this), options.autoLoad !== !1 && this.load();
|
37 | }
|
38 | |
39 |
|
40 |
|
41 |
|
42 | update(_deltaTime = 0) {
|
43 | if (!this.destroyed) {
|
44 | if (this._updateFPS) {
|
45 | const elapsedMS = ticker.Ticker.shared.elapsedMS * this.source.playbackRate;
|
46 | this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);
|
47 | }
|
48 | (!this._updateFPS || this._msToNextUpdate <= 0) && (super.update(
|
49 |
|
50 | ), this._msToNextUpdate = this._updateFPS ? Math.floor(1e3 / this._updateFPS) : 0);
|
51 | }
|
52 | }
|
53 | _videoFrameRequestCallback() {
|
54 | this.update(), this.destroyed ? this._videoFrameRequestCallbackHandle = null : this._videoFrameRequestCallbackHandle = this.source.requestVideoFrameCallback(
|
55 | this._videoFrameRequestCallback
|
56 | );
|
57 | }
|
58 | |
59 |
|
60 |
|
61 |
|
62 | load() {
|
63 | if (this._load)
|
64 | return this._load;
|
65 | const source = this.source;
|
66 | return (source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height && (source.complete = !0), source.addEventListener("play", this._onPlayStart), source.addEventListener("pause", this._onPlayStop), source.addEventListener("seeked", this._onSeeked), this._isSourceReady() ? this._onCanPlay() : (source.addEventListener("canplay", this._onCanPlay), source.addEventListener("canplaythrough", this._onCanPlay), source.addEventListener("error", this._onError, !0)), this._load = new Promise((resolve, reject) => {
|
67 | this.valid ? resolve(this) : (this._resolve = resolve, this._reject = reject, source.load());
|
68 | }), this._load;
|
69 | }
|
70 | |
71 |
|
72 |
|
73 |
|
74 | _onError(event) {
|
75 | this.source.removeEventListener("error", this._onError, !0), this.onError.emit(event), this._reject && (this._reject(event), this._reject = null, this._resolve = null);
|
76 | }
|
77 | |
78 |
|
79 |
|
80 |
|
81 | _isSourcePlaying() {
|
82 | const source = this.source;
|
83 | return !source.paused && !source.ended;
|
84 | }
|
85 | |
86 |
|
87 |
|
88 |
|
89 | _isSourceReady() {
|
90 | return this.source.readyState > 2;
|
91 | }
|
92 |
|
93 | _onPlayStart() {
|
94 | this.valid || this._onCanPlay(), this._configureAutoUpdate();
|
95 | }
|
96 |
|
97 | _onPlayStop() {
|
98 | this._configureAutoUpdate();
|
99 | }
|
100 |
|
101 | _onSeeked() {
|
102 | this._autoUpdate && !this._isSourcePlaying() && (this._msToNextUpdate = 0, this.update(), this._msToNextUpdate = 0);
|
103 | }
|
104 |
|
105 | _onCanPlay() {
|
106 | const source = this.source;
|
107 | source.removeEventListener("canplay", this._onCanPlay), source.removeEventListener("canplaythrough", this._onCanPlay);
|
108 | const valid = this.valid;
|
109 | this._msToNextUpdate = 0, this.update(), this._msToNextUpdate = 0, !valid && this._resolve && (this._resolve(this), this._resolve = null, this._reject = null), this._isSourcePlaying() ? this._onPlayStart() : this.autoPlay && source.play();
|
110 | }
|
111 |
|
112 | dispose() {
|
113 | this._configureAutoUpdate();
|
114 | const source = this.source;
|
115 | source && (source.removeEventListener("play", this._onPlayStart), source.removeEventListener("pause", this._onPlayStop), source.removeEventListener("seeked", this._onSeeked), source.removeEventListener("canplay", this._onCanPlay), source.removeEventListener("canplaythrough", this._onCanPlay), source.removeEventListener("error", this._onError, !0), source.pause(), source.src = "", source.load()), super.dispose();
|
116 | }
|
117 |
|
118 | get autoUpdate() {
|
119 | return this._autoUpdate;
|
120 | }
|
121 | set autoUpdate(value) {
|
122 | value !== this._autoUpdate && (this._autoUpdate = value, this._configureAutoUpdate());
|
123 | }
|
124 | |
125 |
|
126 |
|
127 |
|
128 |
|
129 | get updateFPS() {
|
130 | return this._updateFPS;
|
131 | }
|
132 | set updateFPS(value) {
|
133 | value !== this._updateFPS && (this._updateFPS = value, this._configureAutoUpdate());
|
134 | }
|
135 | _configureAutoUpdate() {
|
136 | this._autoUpdate && this._isSourcePlaying() ? !this._updateFPS && this.source.requestVideoFrameCallback ? (this._isConnectedToTicker && (ticker.Ticker.shared.remove(this.update, this), this._isConnectedToTicker = !1, this._msToNextUpdate = 0), this._videoFrameRequestCallbackHandle === null && (this._videoFrameRequestCallbackHandle = this.source.requestVideoFrameCallback(
|
137 | this._videoFrameRequestCallback
|
138 | ))) : (this._videoFrameRequestCallbackHandle !== null && (this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle), this._videoFrameRequestCallbackHandle = null), this._isConnectedToTicker || (ticker.Ticker.shared.add(this.update, this), this._isConnectedToTicker = !0, this._msToNextUpdate = 0)) : (this._videoFrameRequestCallbackHandle !== null && (this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle), this._videoFrameRequestCallbackHandle = null), this._isConnectedToTicker && (ticker.Ticker.shared.remove(this.update, this), this._isConnectedToTicker = !1, this._msToNextUpdate = 0));
|
139 | }
|
140 | |
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 | static test(source, extension) {
|
147 | return globalThis.HTMLVideoElement && source instanceof HTMLVideoElement || _VideoResource2.TYPES.includes(extension);
|
148 | }
|
149 | };
|
150 | _VideoResource.TYPES = ["mp4", "m4v", "webm", "ogg", "ogv", "h264", "avi", "mov"], |
151 |
|
152 |
|
153 |
|
154 | _VideoResource.MIME_TYPES = {
|
155 | ogv: "video/ogg",
|
156 | mov: "video/quicktime",
|
157 | m4v: "video/mp4"
|
158 | };
|
159 | let VideoResource = _VideoResource;
|
160 | exports.VideoResource = VideoResource;
|
161 |
|