UNPKG

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