@video-editor/renderer 0.0.1-beta.30 → 0.0.1-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +944 -700
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import { createValidator as
|
|
2
|
-
import { toRaw as
|
|
3
|
-
import { AudioClip as
|
|
4
|
-
import { file as
|
|
5
|
-
import { Application as
|
|
6
|
-
async function
|
|
7
|
-
const t = new
|
|
8
|
-
return await t.init({ resizeTo: window, backgroundAlpha: 0, ...
|
|
1
|
+
import { createValidator as Wt, createResourceManager as Yt, getResourceKey as W } from "@video-editor/protocol";
|
|
2
|
+
import { toRaw as Xt, isRef as Jt, shallowRef as vt, unref as Mt, ref as gt, computed as Ht, effectScope as Qt, watch as Z } from "@vue/reactivity";
|
|
3
|
+
import { AudioClip as Tt, renderTxt2ImgBitmap as Zt, MP4Clip as K, Combinator as bt, OffscreenSprite as nt } from "@webav/av-cliper";
|
|
4
|
+
import { file as te } from "opfs-tools";
|
|
5
|
+
import { Application as kt, Sprite as V, Texture as G, Graphics as Ct, Container as ee } from "pixi.js";
|
|
6
|
+
async function oe(e) {
|
|
7
|
+
const t = new kt();
|
|
8
|
+
return await t.init({ resizeTo: window, backgroundAlpha: 0, ...e }), t;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
const
|
|
12
|
-
if (!
|
|
13
|
-
return { width:
|
|
14
|
-
const
|
|
15
|
-
switch (
|
|
10
|
+
function ie(e, t, o, i, n) {
|
|
11
|
+
const a = t || i, c = o || n;
|
|
12
|
+
if (!a || !c)
|
|
13
|
+
return { width: i, height: n };
|
|
14
|
+
const u = a / c, d = i / n;
|
|
15
|
+
switch (e) {
|
|
16
16
|
case "none":
|
|
17
|
-
return { width:
|
|
17
|
+
return { width: a, height: c };
|
|
18
18
|
case "cover":
|
|
19
|
-
return
|
|
19
|
+
return u > d ? { width: n * u, height: n } : { width: i, height: i / u };
|
|
20
20
|
case "stretch":
|
|
21
|
-
return { width:
|
|
21
|
+
return { width: i, height: n };
|
|
22
22
|
default:
|
|
23
|
-
return
|
|
23
|
+
return u > d ? { width: i, height: i / u } : { width: n * u, height: n };
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
const
|
|
28
|
-
u,
|
|
29
|
-
r,
|
|
26
|
+
function re(e, t, o, i, n) {
|
|
27
|
+
const a = "fillMode" in e ? e.fillMode : void 0, { width: c, height: u } = ie(
|
|
30
28
|
a,
|
|
29
|
+
i,
|
|
30
|
+
n,
|
|
31
31
|
t,
|
|
32
|
-
|
|
33
|
-
),
|
|
32
|
+
o
|
|
33
|
+
), d = "transform" in e ? e.transform : void 0, [y, h] = d?.position ?? [0, 0], [w, M] = d?.scale ?? [1, 1], p = d?.rotation?.[2] ?? 0, v = c * w, m = u * M, g = t / 2 + y * t / 2, R = o / 2 - h * o / 2;
|
|
34
34
|
return {
|
|
35
|
-
width:
|
|
36
|
-
height:
|
|
37
|
-
centerX:
|
|
35
|
+
width: v,
|
|
36
|
+
height: m,
|
|
37
|
+
centerX: g,
|
|
38
38
|
centerY: R,
|
|
39
|
-
rotationRad:
|
|
39
|
+
rotationRad: p / 180 * Math.PI
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function ne(e) {
|
|
43
43
|
const t = /* @__PURE__ */ new Set();
|
|
44
|
-
for (const
|
|
45
|
-
for (const
|
|
46
|
-
|
|
44
|
+
for (const o of e.tracks)
|
|
45
|
+
for (const i of o.children)
|
|
46
|
+
i.url && t.add(i.url);
|
|
47
47
|
return t;
|
|
48
48
|
}
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
function Rt(e, t) {
|
|
50
|
+
const o = [];
|
|
51
|
+
return e.tracks.forEach((i, n) => {
|
|
52
|
+
i.children.forEach((a, c) => {
|
|
53
|
+
a.startTime <= t && t < a.endTime && o.push({ segment: a, trackIndex: n, childIndex: c });
|
|
54
54
|
});
|
|
55
|
-
}),
|
|
56
|
-
const
|
|
57
|
-
return h !==
|
|
55
|
+
}), o.sort((i, n) => {
|
|
56
|
+
const a = e.tracks[i.trackIndex], c = e.tracks[n.trackIndex], u = a?.trackType === "frames" && a.isMain, d = c?.trackType === "frames" && c.isMain, y = e.tracks.length, h = u ? 0 : y - i.trackIndex, w = d ? 0 : y - n.trackIndex;
|
|
57
|
+
return h !== w ? h - w : i.trackIndex === n.trackIndex ? i.childIndex - n.childIndex : i.trackIndex - n.trackIndex;
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
|
-
function
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}, { once: !0 })) :
|
|
60
|
+
function ae(e, t, o, i) {
|
|
61
|
+
const n = ce(t), a = e instanceof V && e.texture.width || o, c = e instanceof V && e.texture.height || i, u = re(t, o, i, a, c);
|
|
62
|
+
e instanceof V ? (e.anchor.set(0.5), e.width = u.width, e.height = u.height, e.position.set(u.centerX, u.centerY), e.rotation = u.rotationRad, e.texture.source?.addEventListener?.("error", () => {
|
|
63
|
+
e.texture = G.from(se(o, i));
|
|
64
|
+
}, { once: !0 })) : e instanceof Ct && (e.clear(), e.rect(0, 0, u.width, u.height).fill({ color: At("url" in t && typeof t.url == "string" ? t.url : t.segmentType), alpha: Et(t) ? n : 0.35 }), e.pivot.set(u.width / 2, u.height / 2), e.position.set(u.centerX, u.centerY), e.rotation = u.rotationRad), e.alpha = n;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
const
|
|
68
|
-
return
|
|
66
|
+
function tt(e, t) {
|
|
67
|
+
const o = new Ct();
|
|
68
|
+
return o.rect(0, 0, 10, 10).fill({ color: At(t ?? e), alpha: 1 }), o;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
return `data:image/svg+xml;base64,${btoa(
|
|
70
|
+
function se(e, t, o) {
|
|
71
|
+
const i = `<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${t}"><rect width="100%" height="100%" fill="#0f172a" fill-opacity="0.8"/></svg>`;
|
|
72
|
+
return `data:image/svg+xml;base64,${btoa(i)}`;
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function At(e) {
|
|
75
75
|
let t = 0;
|
|
76
|
-
for (let
|
|
77
|
-
t =
|
|
76
|
+
for (let o = 0; o < e.length; o++)
|
|
77
|
+
t = e.charCodeAt(o) + ((t << 5) - t);
|
|
78
78
|
return t & 16777215;
|
|
79
79
|
}
|
|
80
|
-
function
|
|
81
|
-
const t =
|
|
80
|
+
function it(e) {
|
|
81
|
+
const t = e.tracks.flatMap((o) => o.children.map((i) => i.endTime));
|
|
82
82
|
return t.length ? Math.max(...t) : 0;
|
|
83
83
|
}
|
|
84
|
-
function
|
|
85
|
-
return Math.min(Math.max(
|
|
84
|
+
function et(e, t, o) {
|
|
85
|
+
return Math.min(Math.max(e, t), o);
|
|
86
86
|
}
|
|
87
|
-
function
|
|
88
|
-
const t =
|
|
87
|
+
function St(e) {
|
|
88
|
+
const t = Xt(e);
|
|
89
89
|
return JSON.parse(JSON.stringify(t));
|
|
90
90
|
}
|
|
91
|
-
function
|
|
92
|
-
return "opacity" in
|
|
91
|
+
function Et(e) {
|
|
92
|
+
return "opacity" in e;
|
|
93
93
|
}
|
|
94
|
-
function
|
|
95
|
-
return
|
|
94
|
+
function ce(e) {
|
|
95
|
+
return Et(e) && typeof e.opacity == "number" ? e.opacity : 1;
|
|
96
96
|
}
|
|
97
|
-
class
|
|
97
|
+
class ue {
|
|
98
98
|
protocol;
|
|
99
99
|
clips = /* @__PURE__ */ new Map();
|
|
100
100
|
loadingClips = /* @__PURE__ */ new Map();
|
|
@@ -104,6 +104,8 @@ class oe {
|
|
|
104
104
|
mp4States = /* @__PURE__ */ new Map();
|
|
105
105
|
audioGains = /* @__PURE__ */ new Map();
|
|
106
106
|
mp4Gains = /* @__PURE__ */ new Map();
|
|
107
|
+
audioElements = /* @__PURE__ */ new Map();
|
|
108
|
+
useMediaElementForAudio = !0;
|
|
107
109
|
ctx;
|
|
108
110
|
lastTime = 0;
|
|
109
111
|
constructor(t) {
|
|
@@ -112,113 +114,121 @@ class oe {
|
|
|
112
114
|
setProtocol(t) {
|
|
113
115
|
this.protocol = t;
|
|
114
116
|
}
|
|
115
|
-
async sync(t,
|
|
116
|
-
if (!
|
|
117
|
+
async sync(t, o) {
|
|
118
|
+
if (!o) {
|
|
117
119
|
this.stopAll(), this.lastTime = t;
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
120
122
|
this.ctx.state === "suspended" && await this.ctx.resume().catch(() => {
|
|
121
123
|
}), Math.abs(t - this.lastTime) > 1e3 && this.stopAll(), this.lastTime = t;
|
|
122
|
-
const
|
|
123
|
-
for (const { segment: c } of
|
|
124
|
+
const i = Rt(this.protocol, t), n = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
|
|
125
|
+
for (const { segment: c } of i)
|
|
124
126
|
if (c.segmentType === "audio") {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
+
const u = this.audioKey(c.id);
|
|
128
|
+
n.add(u), this.useMediaElementForAudio ? this.syncAudioElement(c, t) : this.ensureAudioLoop(c, t);
|
|
127
129
|
} else if (c.segmentType === "frames" && "type" in c && c.type === "video") {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
+
const u = this.videoKey(c.id);
|
|
131
|
+
a.add(u);
|
|
130
132
|
}
|
|
131
|
-
for (const [c,
|
|
132
|
-
if (!
|
|
133
|
-
|
|
134
|
-
for (const
|
|
133
|
+
for (const [c, u] of this.audioLoops)
|
|
134
|
+
if (!n.has(c)) {
|
|
135
|
+
u.stop();
|
|
136
|
+
for (const d of u.sources)
|
|
135
137
|
try {
|
|
136
|
-
|
|
138
|
+
d.stop(), d.disconnect();
|
|
137
139
|
} catch {
|
|
138
140
|
}
|
|
139
141
|
this.audioLoops.delete(c), this.audioLoopContexts.delete(c), this.audioGains.delete(c);
|
|
140
142
|
}
|
|
141
|
-
for (const [c,
|
|
142
|
-
if (!
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
for (const [c, u] of this.audioElements)
|
|
144
|
+
if (!n.has(c)) {
|
|
145
|
+
try {
|
|
146
|
+
u.el.pause(), u.pendingPlay = void 0, u.lastTimelineMs = void 0, u.lastSourceSec = void 0, u.lastSeekTimelineMs = void 0;
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
this.findSegmentInProtocol(u.segmentId) || (this.destroyAudioElement(u.el), this.audioElements.delete(c));
|
|
150
|
+
}
|
|
151
|
+
for (const [c, u] of this.mp4Loops)
|
|
152
|
+
if (!a.has(c)) {
|
|
153
|
+
u.stop();
|
|
154
|
+
for (const d of u.sources)
|
|
145
155
|
try {
|
|
146
|
-
|
|
156
|
+
d.stop(), d.disconnect();
|
|
147
157
|
} catch {
|
|
148
158
|
}
|
|
149
159
|
this.mp4Loops.delete(c), this.mp4States.delete(c), this.mp4Gains.delete(c);
|
|
150
160
|
}
|
|
151
161
|
for (const c of this.mp4States.keys())
|
|
152
|
-
!
|
|
162
|
+
!a.has(c) && !this.mp4Loops.has(c) && (this.mp4States.delete(c), this.mp4Gains.delete(c));
|
|
153
163
|
}
|
|
154
164
|
/**
|
|
155
165
|
* Play audio frames from MP4 video directly.
|
|
156
166
|
* Called by renderer after it gets audio data from clip.tick()
|
|
157
167
|
*/
|
|
158
|
-
playMp4AudioFrames(t,
|
|
159
|
-
if (!
|
|
168
|
+
playMp4AudioFrames(t, o, i) {
|
|
169
|
+
if (!o || o.length === 0 || !o[0]?.length)
|
|
160
170
|
return;
|
|
161
|
-
const
|
|
171
|
+
const n = this.videoKey(t), a = this.getSegmentVolume(t), c = this.getOrCreateGain(this.mp4Gains, n, a);
|
|
162
172
|
this.ctx.state === "suspended" && this.ctx.resume().catch(() => {
|
|
163
173
|
});
|
|
164
|
-
let
|
|
165
|
-
|
|
174
|
+
let u = this.mp4States.get(n);
|
|
175
|
+
u || (u = {
|
|
166
176
|
loop: { stop: () => {
|
|
167
177
|
}, sources: [], isStopped: () => !1 },
|
|
168
178
|
startUs: 0,
|
|
169
179
|
startCtxTime: this.ctx.currentTime,
|
|
170
180
|
fps: 30,
|
|
171
181
|
nextStartAt: 0
|
|
172
|
-
}, this.mp4States.set(
|
|
182
|
+
}, this.mp4States.set(n, u)), u.nextStartAt = this.playFrames(o, i, u.nextStartAt ?? 0, c, u.loop.sources);
|
|
173
183
|
}
|
|
174
184
|
/**
|
|
175
185
|
* Reset MP4 audio playback state (call when seeking or pausing)
|
|
176
186
|
*/
|
|
177
187
|
resetMp4Audio(t) {
|
|
178
|
-
const
|
|
179
|
-
|
|
188
|
+
const o = this.videoKey(t), i = this.mp4States.get(o);
|
|
189
|
+
i && (i.nextStartAt = 0);
|
|
180
190
|
}
|
|
181
191
|
/**
|
|
182
192
|
* Stop and clean up MP4 audio for a video segment
|
|
183
193
|
*/
|
|
184
194
|
stopMp4Audio(t) {
|
|
185
|
-
const
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
for (const
|
|
195
|
+
const o = this.videoKey(t), i = this.mp4States.get(o);
|
|
196
|
+
if (i) {
|
|
197
|
+
i.loop.stop();
|
|
198
|
+
for (const n of i.loop.sources)
|
|
189
199
|
try {
|
|
190
|
-
|
|
200
|
+
n.stop(), n.disconnect();
|
|
191
201
|
} catch {
|
|
192
202
|
}
|
|
193
|
-
this.mp4Loops.delete(
|
|
203
|
+
this.mp4Loops.delete(o), this.mp4States.delete(o), this.mp4Gains.delete(o);
|
|
194
204
|
}
|
|
195
205
|
}
|
|
196
206
|
/**
|
|
197
207
|
* @deprecated Use playMp4AudioFrames instead
|
|
198
208
|
*/
|
|
199
|
-
ensureMp4Audio(t,
|
|
200
|
-
const
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
const h = (this.ctx.currentTime -
|
|
204
|
-
if (Math.abs(
|
|
209
|
+
ensureMp4Audio(t, o, i, n) {
|
|
210
|
+
const a = this.videoKey(t), c = this.getSegmentVolume(t), u = this.getOrCreateGain(this.mp4Gains, a, c), d = this.mp4States.get(a);
|
|
211
|
+
if (d) {
|
|
212
|
+
u.gain.value = Math.max(0, c);
|
|
213
|
+
const h = (this.ctx.currentTime - d.startCtxTime) * 1e6, w = d.startUs + h;
|
|
214
|
+
if (Math.abs(w - i) < 15e4 && d.fps === n)
|
|
205
215
|
return;
|
|
206
|
-
|
|
207
|
-
for (const
|
|
216
|
+
d.loop.stop();
|
|
217
|
+
for (const M of d.loop.sources)
|
|
208
218
|
try {
|
|
209
|
-
|
|
219
|
+
M.stop(), M.disconnect();
|
|
210
220
|
} catch {
|
|
211
221
|
}
|
|
212
|
-
this.mp4Loops.delete(
|
|
222
|
+
this.mp4Loops.delete(a), this.mp4States.delete(a);
|
|
213
223
|
}
|
|
214
224
|
this.ctx.state === "suspended" && this.ctx.resume().catch(() => {
|
|
215
225
|
});
|
|
216
|
-
const
|
|
217
|
-
this.mp4Loops.set(
|
|
218
|
-
loop:
|
|
219
|
-
startUs:
|
|
226
|
+
const y = this.startMp4Loop(o, i, n, u);
|
|
227
|
+
this.mp4Loops.set(a, y), this.mp4States.set(a, {
|
|
228
|
+
loop: y,
|
|
229
|
+
startUs: i,
|
|
220
230
|
startCtxTime: this.ctx.currentTime,
|
|
221
|
-
fps:
|
|
231
|
+
fps: n
|
|
222
232
|
});
|
|
223
233
|
}
|
|
224
234
|
destroy() {
|
|
@@ -226,22 +236,30 @@ class oe {
|
|
|
226
236
|
for (const t of this.clips.values())
|
|
227
237
|
t.clip.destroy();
|
|
228
238
|
this.clips.clear();
|
|
239
|
+
for (const t of this.audioElements.values())
|
|
240
|
+
this.destroyAudioElement(t.el);
|
|
241
|
+
this.audioElements.clear();
|
|
229
242
|
}
|
|
230
243
|
stopAll() {
|
|
244
|
+
for (const t of this.audioElements.values())
|
|
245
|
+
try {
|
|
246
|
+
t.el.pause(), t.pendingPlay = void 0, t.lastTimelineMs = void 0, t.lastSourceSec = void 0, t.lastSeekTimelineMs = void 0;
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
231
249
|
for (const t of this.audioLoops.values()) {
|
|
232
250
|
t.stop();
|
|
233
|
-
for (const
|
|
251
|
+
for (const o of t.sources)
|
|
234
252
|
try {
|
|
235
|
-
|
|
253
|
+
o.stop(0), o.disconnect();
|
|
236
254
|
} catch {
|
|
237
255
|
}
|
|
238
256
|
t.sources.length = 0;
|
|
239
257
|
}
|
|
240
258
|
for (const t of this.mp4Loops.values()) {
|
|
241
259
|
t.stop();
|
|
242
|
-
for (const
|
|
260
|
+
for (const o of t.sources)
|
|
243
261
|
try {
|
|
244
|
-
|
|
262
|
+
o.stop(0), o.disconnect();
|
|
245
263
|
} catch {
|
|
246
264
|
}
|
|
247
265
|
t.sources.length = 0;
|
|
@@ -258,122 +276,183 @@ class oe {
|
|
|
258
276
|
}
|
|
259
277
|
this.audioLoops.clear(), this.audioLoopContexts.clear(), this.audioGains.clear(), this.mp4Loops.clear(), this.mp4States.clear(), this.mp4Gains.clear();
|
|
260
278
|
}
|
|
261
|
-
async ensureAudioLoop(t,
|
|
262
|
-
const
|
|
263
|
-
if (!
|
|
279
|
+
async ensureAudioLoop(t, o) {
|
|
280
|
+
const i = this.audioKey(t.id), n = await this.loadClip(t);
|
|
281
|
+
if (!n)
|
|
264
282
|
return;
|
|
265
|
-
const
|
|
266
|
-
this.applyFadeToGain(t,
|
|
267
|
-
const h = this.audioLoops.get(
|
|
283
|
+
const a = t.fromTime ?? 0, c = this.normalizePlayRate(t.playRate), u = o - t.startTime, d = a + u * c, y = this.getOrCreateGain(this.audioGains, i, t.volume);
|
|
284
|
+
this.applyFadeToGain(t, u, y);
|
|
285
|
+
const h = this.audioLoops.get(i);
|
|
268
286
|
if (h && !h.isStopped())
|
|
269
287
|
return;
|
|
270
|
-
h && (this.audioLoops.delete(
|
|
271
|
-
const
|
|
272
|
-
this.audioLoops.set(
|
|
288
|
+
h && (this.audioLoops.delete(i), this.audioLoopContexts.delete(i));
|
|
289
|
+
const M = (t.endTime - t.startTime) * c, p = a + M, v = this.startAudioLoop(n.clip, Math.max(0, d) * 1e3, y, c, p * 1e3);
|
|
290
|
+
this.audioLoops.set(i, v), this.audioLoopContexts.set(i, {
|
|
273
291
|
segment: t,
|
|
274
292
|
startedAt: this.ctx.currentTime,
|
|
275
|
-
segmentRelativeMs:
|
|
293
|
+
segmentRelativeMs: u
|
|
276
294
|
});
|
|
277
295
|
}
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
296
|
+
syncAudioElement(t, o) {
|
|
297
|
+
const i = this.audioKey(t.id), n = this.getOrCreateAudioElementState(i, t), a = o - t.startTime, c = this.normalizePlayRate(t.playRate), u = t.fromTime ?? 0, d = u + a * c, h = Math.max(0, t.endTime - t.startTime) * c, w = u + h, M = Math.max(0, w) / 1e3, p = Number.isFinite(n.el.duration) ? Math.max(0, n.el.duration) : void 0, v = p === void 0 ? M : Math.min(M, p), m = Math.max(0, Math.min(d / 1e3, v)), g = d / 1e3 >= v - 0.01;
|
|
298
|
+
Math.abs(n.el.playbackRate - c) > 1e-3 && (n.el.playbackRate = c);
|
|
299
|
+
const R = this.computeSegmentVolume(t, a);
|
|
300
|
+
Math.abs(n.el.volume - R) > 1e-3 && (n.el.volume = R);
|
|
301
|
+
const P = 0.24, A = 500, E = 300, b = -40, q = n.lastTimelineMs, D = n.lastSourceSec, z = q === void 0 ? 0 : o - q;
|
|
302
|
+
let O = !1;
|
|
303
|
+
if (q === void 0)
|
|
304
|
+
O = !0;
|
|
305
|
+
else if (z < b || z > E)
|
|
306
|
+
O = !0;
|
|
307
|
+
else if (D !== void 0) {
|
|
308
|
+
const F = D + z * c / 1e3, Y = Math.abs(F - m), _ = n.lastSeekTimelineMs === void 0 || o - n.lastSeekTimelineMs >= A;
|
|
309
|
+
Y > P && _ && (O = !0);
|
|
310
|
+
}
|
|
311
|
+
if (O && Math.abs(n.el.currentTime - m) > 0.06)
|
|
312
|
+
try {
|
|
313
|
+
n.el.currentTime = m, n.lastSeekTimelineMs = o;
|
|
314
|
+
} catch {
|
|
315
|
+
}
|
|
316
|
+
if (n.lastTimelineMs = o, n.lastSourceSec = m, g) {
|
|
317
|
+
if (!n.el.paused)
|
|
318
|
+
try {
|
|
319
|
+
n.el.pause();
|
|
320
|
+
} catch {
|
|
321
|
+
}
|
|
322
|
+
n.pendingPlay = void 0;
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (n.el.paused && !n.pendingPlay) {
|
|
326
|
+
const F = n.el.play();
|
|
327
|
+
F && typeof F.then == "function" && (n.pendingPlay = F.catch(() => {
|
|
328
|
+
}).finally(() => {
|
|
329
|
+
n.pendingPlay = void 0;
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
applyFadeToGain(t, o, i) {
|
|
334
|
+
i.gain.value = this.computeSegmentVolume(t, o);
|
|
335
|
+
}
|
|
336
|
+
startMp4Loop(t, o, i, n) {
|
|
337
|
+
let a = !1, c = o, u = 0, d = !0;
|
|
338
|
+
const y = Math.round(1e3 / Math.max(i || 30, 1) * 1e3), h = this.getClipSampleRate(t), w = [], M = window.setInterval(async () => {
|
|
339
|
+
if (a)
|
|
289
340
|
return;
|
|
290
|
-
const { audio:
|
|
291
|
-
if (c +=
|
|
341
|
+
const { audio: p, state: v } = await t.tick(Math.round(c));
|
|
342
|
+
if (c += y, v === "done")
|
|
292
343
|
return;
|
|
293
|
-
if (
|
|
294
|
-
|
|
344
|
+
if (d) {
|
|
345
|
+
d = !1;
|
|
295
346
|
return;
|
|
296
347
|
}
|
|
297
|
-
(
|
|
298
|
-
}, Math.round(1e3 / Math.max(
|
|
348
|
+
(p?.[0]?.length ?? 0) !== 0 && (u = this.playFrames(p, h, u, n, w));
|
|
349
|
+
}, Math.round(1e3 / Math.max(i || 30, 1)));
|
|
299
350
|
return {
|
|
300
|
-
sources:
|
|
351
|
+
sources: w,
|
|
301
352
|
stop: () => {
|
|
302
|
-
|
|
353
|
+
a = !0, window.clearInterval(M);
|
|
303
354
|
},
|
|
304
|
-
isStopped: () =>
|
|
355
|
+
isStopped: () => a
|
|
305
356
|
};
|
|
306
357
|
}
|
|
307
|
-
startAudioLoop(t,
|
|
308
|
-
let c = !1,
|
|
309
|
-
const h = this.getClipSampleRate(t),
|
|
358
|
+
startAudioLoop(t, o, i, n = 1, a) {
|
|
359
|
+
let c = !1, u = o, d = 0, y = !1;
|
|
360
|
+
const h = this.getClipSampleRate(t), w = [], p = Math.round(1e5 * n), v = async () => {
|
|
310
361
|
if (c)
|
|
311
362
|
return;
|
|
312
|
-
if (
|
|
363
|
+
if (y || (o > 0 && await t.tick(o), y = !0), u += p, a !== void 0 && u > a) {
|
|
313
364
|
c = !0;
|
|
314
365
|
return;
|
|
315
366
|
}
|
|
316
|
-
const { audio:
|
|
367
|
+
const { audio: m, state: g } = await t.tick(u);
|
|
317
368
|
if (c)
|
|
318
369
|
return;
|
|
319
|
-
if (
|
|
370
|
+
if (g === "done") {
|
|
320
371
|
c = !0;
|
|
321
372
|
return;
|
|
322
373
|
}
|
|
323
|
-
if ((
|
|
374
|
+
if ((m?.[0]?.length ?? 0) === 0) {
|
|
324
375
|
c = !0;
|
|
325
376
|
return;
|
|
326
377
|
}
|
|
327
|
-
|
|
328
|
-
l = this.playFrames(E, h, l, r, m), c || setTimeout(() => k(), 0);
|
|
378
|
+
d = this.playFrames(m, h, d, i, w, n), c || setTimeout(() => v(), 0);
|
|
329
379
|
};
|
|
330
|
-
return
|
|
331
|
-
sources:
|
|
380
|
+
return v(), {
|
|
381
|
+
sources: w,
|
|
332
382
|
stop: () => {
|
|
333
383
|
c = !0;
|
|
334
384
|
},
|
|
335
|
-
|
|
385
|
+
// Treat loop as active while there are still scheduled sources playing.
|
|
386
|
+
isStopped: () => c && w.length === 0
|
|
336
387
|
};
|
|
337
388
|
}
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
return r <= 0 ? t : t.map((a) => {
|
|
341
|
-
const u = new Float32Array(r);
|
|
342
|
-
for (let c = 0; c < r; c++) {
|
|
343
|
-
const d = c * i, l = Math.floor(d), p = Math.min(l + 1, a.length - 1), h = d - l;
|
|
344
|
-
u[c] = a[l] * (1 - h) + a[p] * h;
|
|
345
|
-
}
|
|
346
|
-
return u;
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
playFrames(t, i, r, a, u) {
|
|
350
|
-
const c = Math.max(t.length, 1), d = t[0]?.length ?? 0;
|
|
389
|
+
playFrames(t, o, i, n, a, c = 1) {
|
|
390
|
+
const u = Math.max(t.length, 1), d = t[0]?.length ?? 0;
|
|
351
391
|
if (d === 0)
|
|
352
|
-
return
|
|
353
|
-
const
|
|
354
|
-
for (let
|
|
355
|
-
const
|
|
356
|
-
|
|
392
|
+
return i;
|
|
393
|
+
const y = this.ctx.createBuffer(u, d, o);
|
|
394
|
+
for (let p = 0; p < u; p++) {
|
|
395
|
+
const v = t[p] ?? new Float32Array(d);
|
|
396
|
+
y.copyToChannel(new Float32Array(v), p);
|
|
357
397
|
}
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
398
|
+
const h = this.ctx.createBufferSource();
|
|
399
|
+
h.buffer = y;
|
|
400
|
+
const w = Math.max(0.1, c);
|
|
401
|
+
h.playbackRate.value = w, h.connect(n);
|
|
402
|
+
const M = Math.max(this.ctx.currentTime, i);
|
|
403
|
+
if (h.start(M), a) {
|
|
404
|
+
a.push(h);
|
|
405
|
+
const p = y.duration / w * 1e3;
|
|
364
406
|
setTimeout(() => {
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
},
|
|
407
|
+
const v = a.indexOf(h);
|
|
408
|
+
v > -1 && a.splice(v, 1);
|
|
409
|
+
}, p + 100);
|
|
410
|
+
}
|
|
411
|
+
return M + y.duration / w;
|
|
412
|
+
}
|
|
413
|
+
getOrCreateGain(t, o, i) {
|
|
414
|
+
const n = t.get(o);
|
|
415
|
+
if (n)
|
|
416
|
+
return typeof i == "number" && (n.gain.value = this.normalizeVolume(i)), n;
|
|
417
|
+
const a = this.ctx.createGain();
|
|
418
|
+
return a.gain.value = this.normalizeVolume(i), a.connect(this.ctx.destination), t.set(o, a), a;
|
|
419
|
+
}
|
|
420
|
+
getOrCreateAudioElementState(t, o) {
|
|
421
|
+
const i = this.audioElements.get(t);
|
|
422
|
+
if (i)
|
|
423
|
+
return i.url !== o.url && (i.el.pause(), i.el.src = o.url, i.el.currentTime = 0, i.url = o.url, i.pendingPlay = void 0, i.lastTimelineMs = void 0, i.lastSourceSec = void 0, i.lastSeekTimelineMs = void 0), i;
|
|
424
|
+
const n = new Audio(o.url);
|
|
425
|
+
n.preload = "auto", n.loop = !1, n.volume = this.normalizeVolume(o.volume), n.playbackRate = this.normalizePlayRate(o.playRate);
|
|
426
|
+
const a = {
|
|
427
|
+
segmentId: o.id,
|
|
428
|
+
url: o.url,
|
|
429
|
+
el: n
|
|
430
|
+
};
|
|
431
|
+
return this.audioElements.set(t, a), a;
|
|
432
|
+
}
|
|
433
|
+
destroyAudioElement(t) {
|
|
434
|
+
try {
|
|
435
|
+
t.pause();
|
|
436
|
+
} catch {
|
|
437
|
+
}
|
|
438
|
+
t.removeAttribute("src");
|
|
439
|
+
try {
|
|
440
|
+
t.load();
|
|
441
|
+
} catch {
|
|
368
442
|
}
|
|
369
|
-
return h + l.duration;
|
|
370
443
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
444
|
+
normalizePlayRate(t) {
|
|
445
|
+
return typeof t != "number" || !Number.isFinite(t) ? 1 : Math.max(0.1, Math.min(100, t));
|
|
446
|
+
}
|
|
447
|
+
normalizeVolume(t) {
|
|
448
|
+
return typeof t != "number" || !Number.isFinite(t) ? 1 : Math.max(0, Math.min(1, t));
|
|
449
|
+
}
|
|
450
|
+
computeSegmentVolume(t, o) {
|
|
451
|
+
const i = this.normalizeVolume(t.volume), n = Math.max(0, t.endTime - t.startTime), a = Math.max(0, t.fadeInDuration ?? 0), c = Math.max(0, t.fadeOutDuration ?? 0);
|
|
452
|
+
let u = 1;
|
|
453
|
+
a > 0 && o < a && (u = Math.max(0, o / a));
|
|
454
|
+
const d = n - o;
|
|
455
|
+
return c > 0 && d < c && (u = Math.min(u, Math.max(0, d / c))), i * u;
|
|
377
456
|
}
|
|
378
457
|
audioKey(t) {
|
|
379
458
|
return `audio:${t}`;
|
|
@@ -382,639 +461,639 @@ class oe {
|
|
|
382
461
|
return `video:${t}`;
|
|
383
462
|
}
|
|
384
463
|
async loadClip(t) {
|
|
385
|
-
const
|
|
464
|
+
const o = this.clips.get(t.id);
|
|
465
|
+
if (o)
|
|
466
|
+
return o;
|
|
467
|
+
const i = this.loadingClips.get(t.id);
|
|
386
468
|
if (i)
|
|
387
469
|
return i;
|
|
388
|
-
const
|
|
389
|
-
if (r)
|
|
390
|
-
return r;
|
|
391
|
-
const a = (async () => {
|
|
470
|
+
const n = (async () => {
|
|
392
471
|
try {
|
|
393
|
-
const
|
|
394
|
-
if (!
|
|
472
|
+
const a = await fetch(t.url);
|
|
473
|
+
if (!a.body) {
|
|
395
474
|
this.loadingClips.delete(t.id);
|
|
396
475
|
return;
|
|
397
476
|
}
|
|
398
|
-
const c = new
|
|
477
|
+
const c = new Tt(a.body), u = { clip: c, ready: c.ready };
|
|
399
478
|
if (await c.ready, !this.findSegmentInProtocol(t.id)) {
|
|
400
479
|
c.destroy(), this.loadingClips.delete(t.id);
|
|
401
480
|
return;
|
|
402
481
|
}
|
|
403
|
-
return this.clips.set(t.id,
|
|
404
|
-
} catch (
|
|
405
|
-
console.error(`[AudioManager] Failed to load audio ${t.url}`,
|
|
482
|
+
return this.clips.set(t.id, u), this.loadingClips.delete(t.id), u;
|
|
483
|
+
} catch (a) {
|
|
484
|
+
console.error(`[AudioManager] Failed to load audio ${t.url}`, a), this.loadingClips.delete(t.id);
|
|
406
485
|
return;
|
|
407
486
|
}
|
|
408
487
|
})();
|
|
409
|
-
return this.loadingClips.set(t.id,
|
|
488
|
+
return this.loadingClips.set(t.id, n), n;
|
|
410
489
|
}
|
|
411
490
|
findSegmentInProtocol(t) {
|
|
412
|
-
for (const
|
|
413
|
-
for (const
|
|
414
|
-
if (
|
|
491
|
+
for (const o of this.protocol.tracks)
|
|
492
|
+
for (const i of o.children)
|
|
493
|
+
if (i.id === t) return !0;
|
|
415
494
|
return !1;
|
|
416
495
|
}
|
|
417
496
|
getSegmentVolume(t) {
|
|
418
|
-
for (const
|
|
419
|
-
for (const
|
|
420
|
-
if (
|
|
497
|
+
for (const o of this.protocol.tracks)
|
|
498
|
+
for (const i of o.children) {
|
|
499
|
+
if (i.id !== t)
|
|
421
500
|
continue;
|
|
422
|
-
const
|
|
423
|
-
return
|
|
501
|
+
const n = i.volume;
|
|
502
|
+
return this.normalizeVolume(n);
|
|
424
503
|
}
|
|
425
504
|
return 1;
|
|
426
505
|
}
|
|
427
506
|
getClipSampleRate(t) {
|
|
428
|
-
const
|
|
429
|
-
if (!
|
|
507
|
+
const o = t.meta;
|
|
508
|
+
if (!o)
|
|
430
509
|
return 48e3;
|
|
431
|
-
const
|
|
432
|
-
if (typeof
|
|
433
|
-
return
|
|
434
|
-
const
|
|
435
|
-
return typeof
|
|
510
|
+
const i = o.audioSampleRate;
|
|
511
|
+
if (typeof i == "number" && i > 0)
|
|
512
|
+
return i;
|
|
513
|
+
const n = o.sampleRate;
|
|
514
|
+
return typeof n == "number" && n > 0 ? n : 48e3;
|
|
436
515
|
}
|
|
437
516
|
}
|
|
438
|
-
const
|
|
439
|
-
let
|
|
440
|
-
function
|
|
441
|
-
$.delete(
|
|
517
|
+
const le = 100, $ = /* @__PURE__ */ new Map();
|
|
518
|
+
let de = le;
|
|
519
|
+
function fe(e, t) {
|
|
520
|
+
$.delete(e), $.set(e, t);
|
|
442
521
|
}
|
|
443
|
-
function
|
|
444
|
-
for (; $.size >
|
|
445
|
-
const [
|
|
446
|
-
$.delete(
|
|
522
|
+
function he() {
|
|
523
|
+
for (; $.size > de; ) {
|
|
524
|
+
const [e, t] = $.entries().next().value;
|
|
525
|
+
$.delete(e), t.close?.();
|
|
447
526
|
}
|
|
448
527
|
}
|
|
449
|
-
function
|
|
450
|
-
return
|
|
528
|
+
function pe(e) {
|
|
529
|
+
return e.map((t) => t.content).filter(Boolean).join(`
|
|
451
530
|
`);
|
|
452
531
|
}
|
|
453
|
-
function
|
|
454
|
-
const t = Array.isArray(
|
|
455
|
-
`font-size: ${
|
|
456
|
-
`font-weight: ${
|
|
457
|
-
`font-style: ${
|
|
458
|
-
`color: ${
|
|
532
|
+
function me(e) {
|
|
533
|
+
const t = Array.isArray(e.fontFamily) ? e.fontFamily.join(", ") : e.fontFamily, o = e.fontSize ?? 32, i = e.fontWeight ?? "normal", n = e.fontStyle ?? "normal", a = e.fill ?? "#ffffff", c = e.align ?? "left", u = [
|
|
534
|
+
`font-size: ${o}px`,
|
|
535
|
+
`font-weight: ${i}`,
|
|
536
|
+
`font-style: ${n}`,
|
|
537
|
+
`color: ${a}`,
|
|
459
538
|
`text-align: ${c}`,
|
|
460
539
|
"white-space: pre-wrap"
|
|
461
540
|
];
|
|
462
|
-
if (t &&
|
|
463
|
-
const
|
|
464
|
-
|
|
541
|
+
if (t && u.push(`font-family: ${t}`), typeof e.letterSpacing == "number" && u.push(`letter-spacing: ${e.letterSpacing}px`), typeof e.leading == "number" && u.push(`line-height: ${e.leading}px`), e.background?.color && u.push(`background: ${e.background.color}`), e.stroke?.color && typeof e.stroke.width == "number" && u.push(`-webkit-text-stroke: ${e.stroke.width}px ${e.stroke.color}`), e.underline && u.push("text-decoration: underline"), e.dropShadow?.color && typeof e.dropShadow.distance == "number") {
|
|
542
|
+
const d = (e.dropShadow.angle ?? 45) * (Math.PI / 180), y = Math.cos(d) * e.dropShadow.distance, h = Math.sin(d) * e.dropShadow.distance, w = e.dropShadow.blur ?? 0;
|
|
543
|
+
u.push(`text-shadow: ${y}px ${h}px ${w}px ${e.dropShadow.color}`);
|
|
465
544
|
}
|
|
466
|
-
return
|
|
545
|
+
return u.join("; ");
|
|
467
546
|
}
|
|
468
|
-
async function
|
|
469
|
-
const
|
|
470
|
-
if (
|
|
471
|
-
return
|
|
472
|
-
const
|
|
473
|
-
return $.set(
|
|
547
|
+
async function ye(e, t) {
|
|
548
|
+
const o = `${t}::${e}`, i = $.get(o);
|
|
549
|
+
if (i)
|
|
550
|
+
return fe(o, i), i;
|
|
551
|
+
const n = await Zt(e, t);
|
|
552
|
+
return $.set(o, n), he(), n;
|
|
474
553
|
}
|
|
475
|
-
const
|
|
476
|
-
async function
|
|
477
|
-
const t =
|
|
478
|
-
t.verify(
|
|
479
|
-
),
|
|
480
|
-
|
|
481
|
-
const c =
|
|
482
|
-
let A,
|
|
483
|
-
async function
|
|
484
|
-
const
|
|
485
|
-
|
|
554
|
+
const we = "/video-editor-res";
|
|
555
|
+
async function ve(e) {
|
|
556
|
+
const t = Wt(), o = Jt(e.protocol) ? e.protocol : vt(e.protocol), i = vt(
|
|
557
|
+
t.verify(St(Mt(o)))
|
|
558
|
+
), n = e.app ?? await oe(e.appOptions), a = new ee();
|
|
559
|
+
n.stage.addChild(a);
|
|
560
|
+
const c = Yt({ dir: e.resourceDir }), u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Set(), w = /* @__PURE__ */ new Set(), M = e.videoSourceMode ?? "auto", p = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), m = gt(0), g = gt(!1), R = Ht(() => it(i.value)), P = new ue(i.value);
|
|
561
|
+
let A, E = 0, b = 0;
|
|
562
|
+
async function q(r) {
|
|
563
|
+
const l = b, { protocol: s, at: f, layer: S } = r, x = Kt(s, f), T = Rt(s, x), k = r.app.renderer.width, C = r.app.renderer.height;
|
|
564
|
+
P.sync(f, g.value);
|
|
486
565
|
const I = [];
|
|
487
|
-
for (const { segment:
|
|
488
|
-
if (
|
|
566
|
+
for (const { segment: N } of T) {
|
|
567
|
+
if (l !== b)
|
|
489
568
|
return;
|
|
490
|
-
const
|
|
491
|
-
if (
|
|
569
|
+
const L = await r.getDisplay(N);
|
|
570
|
+
if (l !== b)
|
|
492
571
|
return;
|
|
493
|
-
if (
|
|
494
|
-
if (
|
|
572
|
+
if (L && !L.destroyed) {
|
|
573
|
+
if (ae(L, N, k, C), Gt(N) && await H(N, x), l !== b)
|
|
495
574
|
return;
|
|
496
|
-
I.push(
|
|
575
|
+
I.push(L);
|
|
497
576
|
}
|
|
498
577
|
}
|
|
499
|
-
if (
|
|
578
|
+
if (l !== b)
|
|
500
579
|
return;
|
|
501
|
-
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
const
|
|
506
|
-
app:
|
|
507
|
-
layer:
|
|
508
|
-
protocol:
|
|
509
|
-
at:
|
|
510
|
-
getDisplay:
|
|
511
|
-
})),
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
() =>
|
|
515
|
-
(
|
|
580
|
+
S.removeChildren();
|
|
581
|
+
const U = I.filter(Boolean);
|
|
582
|
+
U.length && S.addChild(...U), l === b && r.app.render();
|
|
583
|
+
}
|
|
584
|
+
const D = Me(() => q({
|
|
585
|
+
app: n,
|
|
586
|
+
layer: a,
|
|
587
|
+
protocol: i.value,
|
|
588
|
+
at: m.value,
|
|
589
|
+
getDisplay: Lt
|
|
590
|
+
})), z = Qt();
|
|
591
|
+
z.run(() => {
|
|
592
|
+
Z(
|
|
593
|
+
() => Mt(o),
|
|
594
|
+
(r) => {
|
|
516
595
|
try {
|
|
517
|
-
|
|
518
|
-
} catch (
|
|
519
|
-
console.error("[renderer] invalid protocol update",
|
|
596
|
+
i.value = t.verify(St(r));
|
|
597
|
+
} catch (l) {
|
|
598
|
+
console.error("[renderer] invalid protocol update", l);
|
|
520
599
|
return;
|
|
521
600
|
}
|
|
522
|
-
|
|
601
|
+
P.setProtocol(i.value), b += 1, _(), e.warmUpResources !== !1 && F(i.value), Y(i.value), O(), e.manualRender || D();
|
|
523
602
|
},
|
|
524
603
|
{ deep: !0, immediate: !0 }
|
|
525
|
-
),
|
|
526
|
-
|
|
527
|
-
}),
|
|
604
|
+
), e.manualRender || Z(m, () => {
|
|
605
|
+
O(), D();
|
|
606
|
+
}), Z(R, () => O());
|
|
528
607
|
});
|
|
529
|
-
function
|
|
530
|
-
const
|
|
531
|
-
|
|
608
|
+
function O() {
|
|
609
|
+
const r = R.value;
|
|
610
|
+
r <= 0 ? m.value = 0 : m.value > r ? m.value = r : m.value < 0 && (m.value = 0);
|
|
532
611
|
}
|
|
533
|
-
function
|
|
534
|
-
for (const
|
|
535
|
-
|
|
612
|
+
function F(r) {
|
|
613
|
+
for (const l of ne(r))
|
|
614
|
+
u.has(l) || (u.add(l), mt(l) !== "video" && ft(l) && c.add(l).catch(() => {
|
|
536
615
|
}));
|
|
537
616
|
}
|
|
538
|
-
function
|
|
539
|
-
const
|
|
540
|
-
for (const
|
|
541
|
-
for (const f of
|
|
542
|
-
|
|
543
|
-
for (const [
|
|
544
|
-
|
|
545
|
-
for (const [
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
function
|
|
549
|
-
|
|
550
|
-
for (const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
for (const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
}
|
|
557
|
-
function
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
function
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
function
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
function
|
|
567
|
-
if (!
|
|
617
|
+
function Y(r) {
|
|
618
|
+
const l = /* @__PURE__ */ new Set();
|
|
619
|
+
for (const s of r.tracks)
|
|
620
|
+
for (const f of s.children)
|
|
621
|
+
l.add(f.id);
|
|
622
|
+
for (const [s, f] of d)
|
|
623
|
+
l.has(s) || (f.destroy(), d.delete(s));
|
|
624
|
+
for (const [s, f] of p)
|
|
625
|
+
l.has(s) || (ht(f), p.delete(s));
|
|
626
|
+
}
|
|
627
|
+
function _() {
|
|
628
|
+
a.removeChildren();
|
|
629
|
+
for (const r of d.values())
|
|
630
|
+
r.destroy();
|
|
631
|
+
d.clear(), y.clear();
|
|
632
|
+
for (const r of p.values())
|
|
633
|
+
ht(r);
|
|
634
|
+
p.clear();
|
|
635
|
+
}
|
|
636
|
+
function ct() {
|
|
637
|
+
g.value || (g.value = !0, E = performance.now(), A = requestAnimationFrame(ut));
|
|
638
|
+
}
|
|
639
|
+
function X() {
|
|
640
|
+
g.value = !1, A !== void 0 && cancelAnimationFrame(A), A = void 0, P.sync(m.value, !1), e.freezeOnPause !== !1 && qt();
|
|
641
|
+
}
|
|
642
|
+
function ut() {
|
|
643
|
+
lt(), g.value && (A = requestAnimationFrame(ut));
|
|
644
|
+
}
|
|
645
|
+
function lt(r) {
|
|
646
|
+
if (!g.value && r === void 0)
|
|
568
647
|
return;
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
648
|
+
const l = performance.now(), s = r ?? (E ? l - E : 0);
|
|
649
|
+
E = l, s !== 0 && (m.value = et(
|
|
650
|
+
m.value + s,
|
|
572
651
|
0,
|
|
573
652
|
R.value || Number.POSITIVE_INFINITY
|
|
574
|
-
), R.value > 0 &&
|
|
653
|
+
), R.value > 0 && m.value >= R.value && X());
|
|
575
654
|
}
|
|
576
|
-
function
|
|
577
|
-
|
|
655
|
+
function Ut(r) {
|
|
656
|
+
m.value = et(r, 0, R.value || Number.POSITIVE_INFINITY);
|
|
578
657
|
}
|
|
579
|
-
async function
|
|
580
|
-
|
|
658
|
+
async function Ot(r) {
|
|
659
|
+
m.value = et(r, 0, R.value || Number.POSITIVE_INFINITY), await D();
|
|
581
660
|
}
|
|
582
|
-
async function
|
|
583
|
-
const
|
|
661
|
+
async function Lt(r) {
|
|
662
|
+
const l = d.get(r.id);
|
|
663
|
+
if (l)
|
|
664
|
+
return l;
|
|
665
|
+
const s = y.get(r.id);
|
|
584
666
|
if (s)
|
|
585
667
|
return s;
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
return
|
|
598
|
-
if ("type" in e && e.type === "video" && ct(e.url)) {
|
|
599
|
-
const n = await Et(e);
|
|
600
|
-
return n || Y(e.segmentType, e.url);
|
|
668
|
+
const f = Vt(r);
|
|
669
|
+
y.set(r.id, f);
|
|
670
|
+
const S = await f;
|
|
671
|
+
return S && d.set(r.id, S), y.delete(r.id), S;
|
|
672
|
+
}
|
|
673
|
+
async function Vt(r) {
|
|
674
|
+
if (r.segmentType === "frames" || r.segmentType === "sticker") {
|
|
675
|
+
if (!r.url)
|
|
676
|
+
return tt(r.segmentType);
|
|
677
|
+
if ("type" in r && r.type === "video" && yt(r.url)) {
|
|
678
|
+
const s = await zt(r);
|
|
679
|
+
return s || tt(r.segmentType, r.url);
|
|
601
680
|
}
|
|
602
|
-
const
|
|
603
|
-
return
|
|
681
|
+
const l = await Dt(r.url);
|
|
682
|
+
return l ? new V(l) : tt(r.segmentType, r.url);
|
|
604
683
|
}
|
|
605
|
-
if (
|
|
606
|
-
return await
|
|
607
|
-
|
|
684
|
+
if (r.segmentType === "text")
|
|
685
|
+
return await $t(r);
|
|
686
|
+
r.segmentType === "effect" || r.segmentType;
|
|
608
687
|
}
|
|
609
|
-
async function
|
|
610
|
-
const
|
|
611
|
-
if (!
|
|
688
|
+
async function $t(r) {
|
|
689
|
+
const l = pe(r.texts);
|
|
690
|
+
if (!l)
|
|
612
691
|
return;
|
|
613
|
-
const [
|
|
614
|
-
if (!
|
|
692
|
+
const [s] = r.texts;
|
|
693
|
+
if (!s)
|
|
615
694
|
return;
|
|
616
|
-
const f = await
|
|
617
|
-
return new
|
|
695
|
+
const f = await ye(l, me(s)), S = G.from(f);
|
|
696
|
+
return new V(S);
|
|
618
697
|
}
|
|
619
|
-
async function
|
|
620
|
-
const
|
|
621
|
-
if (!
|
|
698
|
+
async function Dt(r) {
|
|
699
|
+
const l = r.startsWith("data:"), s = /^https?:\/\//.test(r);
|
|
700
|
+
if (!l && !s)
|
|
622
701
|
try {
|
|
623
|
-
await c.add(
|
|
624
|
-
const f = await c.get(
|
|
702
|
+
await c.add(r);
|
|
703
|
+
const f = await c.get(r);
|
|
625
704
|
if (f instanceof HTMLImageElement)
|
|
626
|
-
return
|
|
705
|
+
return G.from(f);
|
|
627
706
|
} catch {
|
|
628
707
|
}
|
|
629
|
-
return await
|
|
630
|
-
}
|
|
631
|
-
async function
|
|
632
|
-
const
|
|
633
|
-
if (
|
|
634
|
-
return
|
|
635
|
-
const
|
|
636
|
-
if (
|
|
637
|
-
if (!
|
|
638
|
-
throw new Error(`[renderer] MP4Clip unsupported for ${
|
|
639
|
-
const
|
|
640
|
-
console.warn("[renderer] failed to load video via <video>",
|
|
708
|
+
return await jt(r);
|
|
709
|
+
}
|
|
710
|
+
async function zt(r) {
|
|
711
|
+
const l = p.get(r.id);
|
|
712
|
+
if (l)
|
|
713
|
+
return l.sprite;
|
|
714
|
+
const s = W(r.url), f = M !== "element", S = M !== "mp4clip";
|
|
715
|
+
if (s && h.has(s)) {
|
|
716
|
+
if (!S)
|
|
717
|
+
throw new Error(`[renderer] MP4Clip unsupported for ${r.url}`);
|
|
718
|
+
const x = await B(r.url).catch((T) => {
|
|
719
|
+
console.warn("[renderer] failed to load video via <video>", r.url, T);
|
|
641
720
|
});
|
|
642
|
-
return
|
|
721
|
+
return x ? (p.set(r.id, x), x.sprite) : void 0;
|
|
643
722
|
}
|
|
644
723
|
if (f) {
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
throw
|
|
724
|
+
const x = await pt(r.url).catch((T) => {
|
|
725
|
+
if (s && J(T) && h.add(s), (!s || !w.has(s)) && (s && w.add(s), console.warn("[renderer] failed to load video via MP4Clip", r.url, T)), !S)
|
|
726
|
+
throw T;
|
|
648
727
|
});
|
|
649
|
-
if (
|
|
650
|
-
return console.info("[renderer] video source: mp4clip",
|
|
728
|
+
if (x)
|
|
729
|
+
return console.info("[renderer] video source: mp4clip", r.url), p.set(r.id, x), x.sprite;
|
|
651
730
|
}
|
|
652
|
-
if (
|
|
653
|
-
const
|
|
654
|
-
console.warn("[renderer] failed to load video via <video>",
|
|
731
|
+
if (S) {
|
|
732
|
+
const x = await B(r.url).catch((T) => {
|
|
733
|
+
console.warn("[renderer] failed to load video via <video>", r.url, T);
|
|
655
734
|
});
|
|
656
|
-
if (
|
|
657
|
-
return console.info("[renderer] video source: element",
|
|
735
|
+
if (x)
|
|
736
|
+
return console.info("[renderer] video source: element", r.url), p.set(r.id, x), x.sprite;
|
|
658
737
|
}
|
|
659
738
|
}
|
|
660
|
-
function
|
|
661
|
-
if (!(
|
|
739
|
+
function J(r) {
|
|
740
|
+
if (!(r instanceof Error))
|
|
662
741
|
return !1;
|
|
663
|
-
const
|
|
664
|
-
return
|
|
742
|
+
const l = r.message || "";
|
|
743
|
+
return l.includes("stream is done") || l.includes("not emit ready") || l.includes("tick video timeout");
|
|
665
744
|
}
|
|
666
|
-
async function
|
|
667
|
-
const
|
|
668
|
-
if (
|
|
745
|
+
async function H(r, l) {
|
|
746
|
+
const s = p.get(r.id);
|
|
747
|
+
if (s)
|
|
669
748
|
try {
|
|
670
|
-
const f =
|
|
671
|
-
if (
|
|
672
|
-
const
|
|
673
|
-
if (!
|
|
749
|
+
const f = r.fromTime ?? 0, S = Math.max(0, l - r.startTime + f), x = Math.floor(S * 1e3);
|
|
750
|
+
if (s.kind === "frozen") {
|
|
751
|
+
const k = W(r.url);
|
|
752
|
+
if (!k)
|
|
674
753
|
return;
|
|
675
|
-
const
|
|
676
|
-
return
|
|
754
|
+
const C = await Nt(r.url, k, { sprite: s.sprite, oldTexture: s.texture });
|
|
755
|
+
return C ? (p.set(r.id, C), await H(r, l)) : void 0;
|
|
677
756
|
}
|
|
678
|
-
if (
|
|
757
|
+
if (s.kind === "mp4clip")
|
|
679
758
|
try {
|
|
680
|
-
const
|
|
681
|
-
if (
|
|
682
|
-
const
|
|
683
|
-
|
|
759
|
+
const k = await s.clip.tick(x);
|
|
760
|
+
if (k.video) {
|
|
761
|
+
const C = s.canvas.getContext("2d");
|
|
762
|
+
C && (C.drawImage(k.video, 0, 0, s.canvas.width, s.canvas.height), wt(s.texture)), k.video.close();
|
|
684
763
|
}
|
|
685
|
-
if (
|
|
686
|
-
const
|
|
687
|
-
|
|
764
|
+
if (g.value && k.audio && k.audio.length > 0) {
|
|
765
|
+
const C = s.clip.meta?.audioSampleRate ?? 48e3;
|
|
766
|
+
P.playMp4AudioFrames(r.id, k.audio, C);
|
|
688
767
|
}
|
|
689
768
|
return;
|
|
690
|
-
} catch (
|
|
691
|
-
const
|
|
692
|
-
if (
|
|
693
|
-
const I = await
|
|
694
|
-
console.warn("[renderer] failed to fallback to <video> after MP4Clip error",
|
|
769
|
+
} catch (k) {
|
|
770
|
+
const C = W(r.url);
|
|
771
|
+
if (C && J(k) && (h.add(C), s.clip.destroy(), M !== "mp4clip")) {
|
|
772
|
+
const I = await B(r.url, { sprite: s.sprite, oldTexture: s.texture }).catch((U) => {
|
|
773
|
+
console.warn("[renderer] failed to fallback to <video> after MP4Clip error", r.url, U);
|
|
695
774
|
});
|
|
696
775
|
if (I)
|
|
697
|
-
return
|
|
776
|
+
return p.set(r.id, I), await H(r, l);
|
|
698
777
|
}
|
|
699
|
-
|
|
778
|
+
C && !w.has(C) && (w.add(C), console.warn("[renderer] MP4Clip tick failed", r.url, k));
|
|
700
779
|
return;
|
|
701
780
|
}
|
|
702
|
-
const
|
|
703
|
-
if (!Number.isFinite(
|
|
781
|
+
const T = S / 1e3;
|
|
782
|
+
if (!Number.isFinite(T) || s.kind !== "element")
|
|
704
783
|
return;
|
|
705
|
-
await
|
|
706
|
-
targetSec:
|
|
707
|
-
playbackRate:
|
|
708
|
-
volume:
|
|
784
|
+
await Bt(s, {
|
|
785
|
+
targetSec: T,
|
|
786
|
+
playbackRate: r.playRate ?? 1,
|
|
787
|
+
volume: r.volume ?? 1
|
|
709
788
|
});
|
|
710
789
|
} catch (f) {
|
|
711
790
|
console.warn("[renderer] update video frame failed", f);
|
|
712
791
|
}
|
|
713
792
|
}
|
|
714
|
-
async function
|
|
715
|
-
const f =
|
|
716
|
-
if (h.has(
|
|
717
|
-
if (!
|
|
718
|
-
throw new Error(`[renderer] MP4Clip unsupported for ${
|
|
719
|
-
return await
|
|
793
|
+
async function Nt(r, l, s) {
|
|
794
|
+
const f = M !== "element", S = M !== "mp4clip";
|
|
795
|
+
if (h.has(l)) {
|
|
796
|
+
if (!S)
|
|
797
|
+
throw new Error(`[renderer] MP4Clip unsupported for ${r}`);
|
|
798
|
+
return await B(r, s).catch(() => {
|
|
720
799
|
});
|
|
721
800
|
}
|
|
722
801
|
if (f) {
|
|
723
|
-
const
|
|
724
|
-
if (
|
|
725
|
-
throw
|
|
802
|
+
const x = await pt(r, s).catch((T) => {
|
|
803
|
+
if (J(T) && h.add(l), !S)
|
|
804
|
+
throw T;
|
|
726
805
|
});
|
|
727
|
-
if (
|
|
728
|
-
return
|
|
806
|
+
if (x)
|
|
807
|
+
return x;
|
|
729
808
|
}
|
|
730
|
-
if (
|
|
731
|
-
return await
|
|
809
|
+
if (S)
|
|
810
|
+
return await B(r, s).catch(() => {
|
|
732
811
|
});
|
|
733
812
|
}
|
|
734
|
-
function
|
|
735
|
-
return
|
|
813
|
+
function Gt(r) {
|
|
814
|
+
return r.segmentType === "frames" && r.type === "video" && typeof r.url == "string" && yt(r.url);
|
|
736
815
|
}
|
|
737
|
-
function
|
|
738
|
-
const
|
|
739
|
-
if (
|
|
816
|
+
function Kt(r, l) {
|
|
817
|
+
const s = it(r);
|
|
818
|
+
if (s <= 0)
|
|
740
819
|
return 0;
|
|
741
|
-
if (
|
|
742
|
-
return
|
|
743
|
-
const f = Math.max(1e3 / Math.max(
|
|
744
|
-
return Math.max(
|
|
820
|
+
if (l < s)
|
|
821
|
+
return l;
|
|
822
|
+
const f = Math.max(1e3 / Math.max(r.fps || 30, 1), 1);
|
|
823
|
+
return Math.max(s - f, 0);
|
|
745
824
|
}
|
|
746
|
-
async function
|
|
747
|
-
const
|
|
825
|
+
async function dt(r) {
|
|
826
|
+
const l = e.resourceDir ?? we;
|
|
748
827
|
try {
|
|
749
|
-
const
|
|
750
|
-
if (!
|
|
828
|
+
const s = W(r);
|
|
829
|
+
if (!s)
|
|
751
830
|
return;
|
|
752
|
-
const f =
|
|
831
|
+
const f = te(`${l}/${s}`, "r");
|
|
753
832
|
if (await f.exists())
|
|
754
833
|
return f;
|
|
755
834
|
} catch {
|
|
756
835
|
return;
|
|
757
836
|
}
|
|
758
837
|
}
|
|
759
|
-
function
|
|
760
|
-
return !(!
|
|
838
|
+
function ft(r) {
|
|
839
|
+
return !(!r || r.startsWith("data:") || r.startsWith("blob:"));
|
|
761
840
|
}
|
|
762
|
-
function
|
|
763
|
-
for (const [
|
|
764
|
-
if (
|
|
765
|
-
|
|
841
|
+
function qt() {
|
|
842
|
+
for (const [r, l] of p) {
|
|
843
|
+
if (l.kind === "mp4clip") {
|
|
844
|
+
l.clip.destroy(), p.set(r, {
|
|
766
845
|
kind: "frozen",
|
|
767
|
-
canvas:
|
|
768
|
-
texture:
|
|
769
|
-
sprite:
|
|
770
|
-
meta:
|
|
846
|
+
canvas: l.canvas,
|
|
847
|
+
texture: l.texture,
|
|
848
|
+
sprite: l.sprite,
|
|
849
|
+
meta: l.meta
|
|
771
850
|
});
|
|
772
851
|
continue;
|
|
773
852
|
}
|
|
774
|
-
|
|
853
|
+
l.kind === "element" && l.video.pause();
|
|
775
854
|
}
|
|
776
855
|
}
|
|
777
|
-
function
|
|
778
|
-
if (
|
|
779
|
-
|
|
856
|
+
function ht(r) {
|
|
857
|
+
if (r.kind === "mp4clip") {
|
|
858
|
+
r.clip.destroy();
|
|
780
859
|
return;
|
|
781
860
|
}
|
|
782
|
-
if (
|
|
861
|
+
if (r.kind === "frozen")
|
|
783
862
|
return;
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
function
|
|
789
|
-
return new Promise((f,
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
},
|
|
793
|
-
|
|
794
|
-
},
|
|
795
|
-
|
|
796
|
-
const I =
|
|
797
|
-
|
|
798
|
-
},
|
|
799
|
-
window.clearTimeout(
|
|
863
|
+
r.video.pause();
|
|
864
|
+
const l = v.get(r.video);
|
|
865
|
+
l && (URL.revokeObjectURL(l), v.delete(r.video)), r.video.removeAttribute("src"), r.video.load();
|
|
866
|
+
}
|
|
867
|
+
function Q(r, l, s = 1e3) {
|
|
868
|
+
return new Promise((f, S) => {
|
|
869
|
+
const x = window.setTimeout(() => {
|
|
870
|
+
C(), S(new Error(`Timed out waiting for media event: ${l}`));
|
|
871
|
+
}, s), T = () => {
|
|
872
|
+
C(), f();
|
|
873
|
+
}, k = () => {
|
|
874
|
+
C();
|
|
875
|
+
const I = r.error ? `${r.error.code}` : "unknown";
|
|
876
|
+
S(new Error(`Media error (${I}) while waiting for ${l}`));
|
|
877
|
+
}, C = () => {
|
|
878
|
+
window.clearTimeout(x), r.removeEventListener(l, T), r.removeEventListener("error", k);
|
|
800
879
|
};
|
|
801
|
-
|
|
880
|
+
r.addEventListener(l, T, { once: !0 }), r.addEventListener("error", k, { once: !0 });
|
|
802
881
|
});
|
|
803
882
|
}
|
|
804
|
-
async function
|
|
805
|
-
let
|
|
806
|
-
|
|
807
|
-
}),
|
|
883
|
+
async function pt(r, l) {
|
|
884
|
+
let s;
|
|
885
|
+
ft(r) && (s = await dt(r), s || (await c.add(r).catch(() => {
|
|
886
|
+
}), s = await dt(r)));
|
|
808
887
|
let f;
|
|
809
888
|
try {
|
|
810
|
-
if (
|
|
811
|
-
f = new
|
|
889
|
+
if (s)
|
|
890
|
+
f = new K(s);
|
|
812
891
|
else {
|
|
813
|
-
const I = await fetch(
|
|
892
|
+
const I = await fetch(r);
|
|
814
893
|
if (I.body)
|
|
815
|
-
f = new
|
|
894
|
+
f = new K(I.body);
|
|
816
895
|
else {
|
|
817
|
-
const
|
|
818
|
-
start(
|
|
819
|
-
|
|
896
|
+
const U = await I.arrayBuffer(), N = new ReadableStream({
|
|
897
|
+
start(L) {
|
|
898
|
+
L.enqueue(new Uint8Array(U)), L.close();
|
|
820
899
|
}
|
|
821
900
|
});
|
|
822
|
-
f = new
|
|
901
|
+
f = new K(N);
|
|
823
902
|
}
|
|
824
903
|
}
|
|
825
904
|
await f.ready;
|
|
826
|
-
const { width:
|
|
827
|
-
|
|
828
|
-
const
|
|
829
|
-
return
|
|
830
|
-
} catch (
|
|
831
|
-
throw f?.destroy(),
|
|
905
|
+
const { width: S, height: x } = f.meta, T = document.createElement("canvas");
|
|
906
|
+
T.width = S || 1, T.height = x || 1;
|
|
907
|
+
const k = G.from(T), C = l?.sprite ?? new V(k);
|
|
908
|
+
return l?.sprite && (l.sprite.texture = k, l.oldTexture?.destroy(!0)), { kind: "mp4clip", clip: f, canvas: T, texture: k, sprite: C, meta: { width: S, height: x } };
|
|
909
|
+
} catch (S) {
|
|
910
|
+
throw f?.destroy(), S;
|
|
832
911
|
}
|
|
833
912
|
}
|
|
834
|
-
function
|
|
835
|
-
const
|
|
836
|
-
return ["mp4", "m4v", "mov", "webm"].includes(
|
|
913
|
+
function mt(r) {
|
|
914
|
+
const s = r.split("#")[0].split("?")[0].split("/").pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
915
|
+
return ["mp4", "m4v", "mov", "webm"].includes(s) ? "video" : ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg", "avif"].includes(s) ? "image" : ["mp3", "wav", "aac", "m4a", "ogg", "flac"].includes(s) ? "audio" : "unknown";
|
|
837
916
|
}
|
|
838
|
-
function
|
|
839
|
-
const
|
|
840
|
-
return !(
|
|
917
|
+
function yt(r) {
|
|
918
|
+
const l = mt(r);
|
|
919
|
+
return !(l === "image" || l === "audio");
|
|
841
920
|
}
|
|
842
|
-
async function
|
|
843
|
-
const
|
|
844
|
-
|
|
921
|
+
async function B(r, l) {
|
|
922
|
+
const s = document.createElement("video");
|
|
923
|
+
s.crossOrigin = "anonymous", s.muted = !1, s.playsInline = !0, s.preload = "metadata", s.src = r, s.load();
|
|
845
924
|
try {
|
|
846
|
-
await
|
|
847
|
-
} catch (
|
|
848
|
-
|
|
849
|
-
const I =
|
|
850
|
-
throw I && (URL.revokeObjectURL(I),
|
|
925
|
+
await Q(s, "loadedmetadata", 15e3);
|
|
926
|
+
} catch (C) {
|
|
927
|
+
s.pause();
|
|
928
|
+
const I = v.get(s);
|
|
929
|
+
throw I && (URL.revokeObjectURL(I), v.delete(s)), s.removeAttribute("src"), s.load(), C;
|
|
851
930
|
}
|
|
852
|
-
const f =
|
|
853
|
-
|
|
854
|
-
const
|
|
855
|
-
return
|
|
856
|
-
}
|
|
857
|
-
async function
|
|
858
|
-
const { video:
|
|
859
|
-
|
|
860
|
-
}) :
|
|
861
|
-
const
|
|
862
|
-
if (Number.isFinite(
|
|
931
|
+
const f = s.videoWidth || 1, S = s.videoHeight || 1, x = document.createElement("canvas");
|
|
932
|
+
x.width = f, x.height = S;
|
|
933
|
+
const T = G.from(x), k = l?.sprite ?? new V(T);
|
|
934
|
+
return l?.sprite && (l.sprite.texture = T, l.oldTexture?.destroy(!0)), { kind: "element", video: s, canvas: x, texture: T, sprite: k, meta: { width: f, height: S } };
|
|
935
|
+
}
|
|
936
|
+
async function Bt(r, l) {
|
|
937
|
+
const { video: s, canvas: f, texture: S } = r;
|
|
938
|
+
s.playbackRate = Number.isFinite(l.playbackRate) && l.playbackRate > 0 ? l.playbackRate : 1, s.volume = Math.max(0, Math.min(1, l.volume ?? 1)), g.value ? s.play().catch(() => {
|
|
939
|
+
}) : s.pause();
|
|
940
|
+
const x = Number.isFinite(s.duration) && s.duration > 0 ? s.duration : null, T = x ? Math.min(l.targetSec, Math.max(x - 0.03, 0)) : l.targetSec, k = s.currentTime, C = Math.abs(k - T), I = g.value ? 0.25 : 0.03;
|
|
941
|
+
if (Number.isFinite(k) && C > I) {
|
|
863
942
|
try {
|
|
864
|
-
|
|
943
|
+
s.currentTime = T;
|
|
865
944
|
} catch {
|
|
866
945
|
}
|
|
867
|
-
await
|
|
946
|
+
await Q(s, "seeked", 250).catch(() => {
|
|
868
947
|
});
|
|
869
948
|
}
|
|
870
|
-
if (
|
|
871
|
-
}),
|
|
949
|
+
if (s.readyState < 2 && (await Q(s, "canplay", 250).catch(() => {
|
|
950
|
+
}), s.readyState < 2))
|
|
872
951
|
return;
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
}
|
|
876
|
-
function
|
|
877
|
-
return new Promise((
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
console.warn("[renderer] failed to load image",
|
|
881
|
-
},
|
|
952
|
+
const U = f.getContext("2d");
|
|
953
|
+
U && (U.drawImage(s, 0, 0, f.width, f.height), wt(S));
|
|
954
|
+
}
|
|
955
|
+
function jt(r) {
|
|
956
|
+
return new Promise((l) => {
|
|
957
|
+
const s = new Image();
|
|
958
|
+
s.crossOrigin = "anonymous", s.onload = () => l(G.from(s)), s.onerror = () => {
|
|
959
|
+
console.warn("[renderer] failed to load image", r), l(void 0);
|
|
960
|
+
}, s.src = r;
|
|
882
961
|
});
|
|
883
962
|
}
|
|
884
|
-
function
|
|
885
|
-
const
|
|
886
|
-
if ("update" in
|
|
887
|
-
|
|
963
|
+
function wt(r) {
|
|
964
|
+
const l = r.source;
|
|
965
|
+
if ("update" in l && typeof l.update == "function") {
|
|
966
|
+
l.update();
|
|
888
967
|
return;
|
|
889
968
|
}
|
|
890
|
-
typeof
|
|
969
|
+
typeof r.update == "function" && r.update();
|
|
891
970
|
}
|
|
892
|
-
function
|
|
893
|
-
|
|
971
|
+
function _t() {
|
|
972
|
+
X(), b += 1, z.stop(), _(), a.destroy({ children: !0 }), d.clear(), y.clear(), u.clear(), e.app || n.destroy(), P.destroy();
|
|
894
973
|
}
|
|
895
|
-
return
|
|
896
|
-
app:
|
|
897
|
-
layer:
|
|
898
|
-
currentTime:
|
|
974
|
+
return e.autoPlay && ct(), {
|
|
975
|
+
app: n,
|
|
976
|
+
layer: a,
|
|
977
|
+
currentTime: m,
|
|
899
978
|
duration: R,
|
|
900
|
-
isPlaying:
|
|
901
|
-
play:
|
|
902
|
-
pause:
|
|
903
|
-
tick:
|
|
904
|
-
seek:
|
|
905
|
-
renderAt:
|
|
906
|
-
destroy:
|
|
979
|
+
isPlaying: g,
|
|
980
|
+
play: ct,
|
|
981
|
+
pause: X,
|
|
982
|
+
tick: lt,
|
|
983
|
+
seek: Ut,
|
|
984
|
+
renderAt: Ot,
|
|
985
|
+
destroy: _t
|
|
907
986
|
};
|
|
908
987
|
}
|
|
909
|
-
function
|
|
910
|
-
let t = !1,
|
|
988
|
+
function Me(e) {
|
|
989
|
+
let t = !1, o = !1, i = null, n = null;
|
|
911
990
|
return async () => {
|
|
912
|
-
|
|
913
|
-
|
|
991
|
+
i || (i = new Promise((u) => {
|
|
992
|
+
n = u;
|
|
914
993
|
}));
|
|
915
|
-
const c =
|
|
916
|
-
if (
|
|
994
|
+
const c = i;
|
|
995
|
+
if (o)
|
|
917
996
|
return t = !0, c;
|
|
918
|
-
|
|
997
|
+
o = !0;
|
|
919
998
|
do
|
|
920
|
-
t = !1, await
|
|
999
|
+
t = !1, await e();
|
|
921
1000
|
while (t);
|
|
922
|
-
return
|
|
1001
|
+
return o = !1, n?.(), i = null, n = null, c;
|
|
923
1002
|
};
|
|
924
1003
|
}
|
|
925
|
-
function
|
|
926
|
-
return typeof
|
|
1004
|
+
function ge(e) {
|
|
1005
|
+
return typeof e == "object" && e !== null && "createReader" in e && "getSize" in e;
|
|
927
1006
|
}
|
|
928
|
-
function
|
|
929
|
-
return typeof ReadableStream < "u" &&
|
|
1007
|
+
function Se(e) {
|
|
1008
|
+
return typeof ReadableStream < "u" && e instanceof ReadableStream;
|
|
930
1009
|
}
|
|
931
|
-
function
|
|
932
|
-
return typeof
|
|
1010
|
+
function xe(e) {
|
|
1011
|
+
return typeof e == "string" || e instanceof Blob || ge(e) || Se(e) ? { source: e } : e;
|
|
933
1012
|
}
|
|
934
|
-
async function
|
|
935
|
-
if (typeof
|
|
936
|
-
const t = await fetch(
|
|
1013
|
+
async function xt(e) {
|
|
1014
|
+
if (typeof e == "string") {
|
|
1015
|
+
const t = await fetch(e);
|
|
937
1016
|
if (!t.body)
|
|
938
1017
|
throw new Error("concatVideos: unable to read video stream from url");
|
|
939
1018
|
return t.body;
|
|
940
1019
|
}
|
|
941
|
-
return
|
|
1020
|
+
return e instanceof Blob ? e.stream() : e;
|
|
942
1021
|
}
|
|
943
|
-
function
|
|
944
|
-
let
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
},
|
|
1022
|
+
function Te(e, t) {
|
|
1023
|
+
let o = !1;
|
|
1024
|
+
const i = () => {
|
|
1025
|
+
o || (o = !0, t());
|
|
1026
|
+
}, n = e.getReader();
|
|
948
1027
|
return new ReadableStream({
|
|
949
|
-
async pull(
|
|
950
|
-
const { done: c, value:
|
|
1028
|
+
async pull(a) {
|
|
1029
|
+
const { done: c, value: u } = await n.read();
|
|
951
1030
|
if (c) {
|
|
952
|
-
|
|
1031
|
+
i(), a.close();
|
|
953
1032
|
return;
|
|
954
1033
|
}
|
|
955
|
-
|
|
1034
|
+
a.enqueue(u);
|
|
956
1035
|
},
|
|
957
|
-
async cancel(
|
|
1036
|
+
async cancel(a) {
|
|
958
1037
|
try {
|
|
959
|
-
await
|
|
1038
|
+
await n.cancel(a);
|
|
960
1039
|
} finally {
|
|
961
|
-
|
|
1040
|
+
i();
|
|
962
1041
|
}
|
|
963
1042
|
}
|
|
964
1043
|
});
|
|
965
1044
|
}
|
|
966
|
-
async function
|
|
967
|
-
if (
|
|
1045
|
+
async function Ne(e, t = {}) {
|
|
1046
|
+
if (e.length === 0)
|
|
968
1047
|
throw new Error("concatVideos: expected at least one source");
|
|
969
1048
|
const {
|
|
970
|
-
onProgress:
|
|
971
|
-
width:
|
|
972
|
-
height:
|
|
973
|
-
...
|
|
974
|
-
} = t, c =
|
|
1049
|
+
onProgress: o,
|
|
1050
|
+
width: i,
|
|
1051
|
+
height: n,
|
|
1052
|
+
...a
|
|
1053
|
+
} = t, c = e.map(xe), [u, ...d] = c, y = await xt(u.source), h = new K(y);
|
|
975
1054
|
await h.ready;
|
|
976
|
-
const
|
|
977
|
-
if (!
|
|
1055
|
+
const w = i ?? Math.round(h.meta.width || 0), M = n ?? Math.round(h.meta.height || 0);
|
|
1056
|
+
if (!w || !M)
|
|
978
1057
|
throw h.destroy(), new Error("concatVideos: output width/height is required");
|
|
979
|
-
const
|
|
980
|
-
...
|
|
981
|
-
width:
|
|
982
|
-
height:
|
|
1058
|
+
const p = new bt({
|
|
1059
|
+
...a,
|
|
1060
|
+
width: w,
|
|
1061
|
+
height: M
|
|
983
1062
|
});
|
|
984
|
-
|
|
985
|
-
let
|
|
986
|
-
const
|
|
987
|
-
const
|
|
988
|
-
if (!Number.isFinite(
|
|
1063
|
+
o && p.on("OutputProgress", o);
|
|
1064
|
+
let v = 0;
|
|
1065
|
+
const m = async (A) => {
|
|
1066
|
+
const E = A.meta.duration;
|
|
1067
|
+
if (!Number.isFinite(E) || E <= 0)
|
|
989
1068
|
throw A.destroy(), new Error("concatVideos: invalid clip duration");
|
|
990
|
-
const
|
|
1069
|
+
const b = new nt(A);
|
|
991
1070
|
try {
|
|
992
|
-
await
|
|
1071
|
+
await b.ready, b.rect.x = 0, b.rect.y = 0, b.rect.w = w, b.rect.h = M, b.time.offset = v, b.time.duration = E, await p.addSprite(b), v += E;
|
|
993
1072
|
} finally {
|
|
994
|
-
|
|
1073
|
+
b.destroy();
|
|
995
1074
|
}
|
|
996
1075
|
};
|
|
997
1076
|
try {
|
|
998
|
-
await
|
|
999
|
-
for (const A of
|
|
1000
|
-
const
|
|
1001
|
-
await
|
|
1077
|
+
await m(h);
|
|
1078
|
+
for (const A of d) {
|
|
1079
|
+
const E = await xt(A.source), b = new K(E);
|
|
1080
|
+
await b.ready, await m(b);
|
|
1002
1081
|
}
|
|
1003
1082
|
} catch (A) {
|
|
1004
|
-
throw
|
|
1083
|
+
throw p.destroy(), A;
|
|
1005
1084
|
}
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1085
|
+
const g = v, R = p.output({ maxTime: g }), P = () => {
|
|
1086
|
+
p.destroy();
|
|
1008
1087
|
};
|
|
1009
1088
|
return {
|
|
1010
|
-
stream:
|
|
1011
|
-
width:
|
|
1012
|
-
height:
|
|
1013
|
-
durationMs: Math.round(
|
|
1014
|
-
destroy:
|
|
1089
|
+
stream: Te(R, P),
|
|
1090
|
+
width: w,
|
|
1091
|
+
height: M,
|
|
1092
|
+
durationMs: Math.round(g / 1e3),
|
|
1093
|
+
destroy: P
|
|
1015
1094
|
};
|
|
1016
1095
|
}
|
|
1017
|
-
class
|
|
1096
|
+
class at {
|
|
1018
1097
|
ready;
|
|
1019
1098
|
meta;
|
|
1020
1099
|
protocol;
|
|
@@ -1022,149 +1101,314 @@ class H {
|
|
|
1022
1101
|
renderer;
|
|
1023
1102
|
app;
|
|
1024
1103
|
destroyed = !1;
|
|
1025
|
-
constructor(t,
|
|
1026
|
-
this.protocol = t, this.options =
|
|
1027
|
-
const
|
|
1104
|
+
constructor(t, o = {}) {
|
|
1105
|
+
this.protocol = t, this.options = o;
|
|
1106
|
+
const i = o.width ?? t.width, n = o.height ?? t.height, a = it(t);
|
|
1028
1107
|
this.meta = {
|
|
1029
|
-
width:
|
|
1030
|
-
height:
|
|
1031
|
-
duration: Math.max(0, Math.round(
|
|
1108
|
+
width: i,
|
|
1109
|
+
height: n,
|
|
1110
|
+
duration: Math.max(0, Math.round(a * 1e3))
|
|
1032
1111
|
}, this.ready = this.init();
|
|
1033
1112
|
}
|
|
1034
1113
|
async init() {
|
|
1035
|
-
const t = this.options.width ?? this.protocol.width,
|
|
1036
|
-
if (!t || !
|
|
1114
|
+
const t = this.options.width ?? this.protocol.width, o = this.options.height ?? this.protocol.height;
|
|
1115
|
+
if (!t || !o)
|
|
1037
1116
|
throw new Error("ProtocolVideoClip: output width/height is required");
|
|
1038
|
-
const
|
|
1039
|
-
await
|
|
1117
|
+
const i = new kt();
|
|
1118
|
+
await i.init({
|
|
1040
1119
|
width: t,
|
|
1041
|
-
height:
|
|
1120
|
+
height: o,
|
|
1042
1121
|
backgroundAlpha: 0,
|
|
1043
1122
|
...this.options.appOptions
|
|
1044
|
-
}),
|
|
1045
|
-
const
|
|
1123
|
+
}), i.ticker.stop(), this.app = i;
|
|
1124
|
+
const n = this.options.rendererOptions ?? {}, a = await ve({
|
|
1046
1125
|
protocol: this.protocol,
|
|
1047
|
-
app:
|
|
1048
|
-
...
|
|
1126
|
+
app: i,
|
|
1127
|
+
...n,
|
|
1049
1128
|
autoPlay: !1,
|
|
1050
1129
|
freezeOnPause: !1,
|
|
1051
1130
|
manualRender: !0,
|
|
1052
|
-
videoSourceMode:
|
|
1131
|
+
videoSourceMode: n.videoSourceMode ?? "mp4clip"
|
|
1053
1132
|
});
|
|
1054
|
-
this.renderer =
|
|
1055
|
-
const c =
|
|
1133
|
+
this.renderer = a;
|
|
1134
|
+
const c = a.duration.value;
|
|
1056
1135
|
return this.meta = {
|
|
1057
|
-
width:
|
|
1058
|
-
height:
|
|
1136
|
+
width: i.renderer.width,
|
|
1137
|
+
height: i.renderer.height,
|
|
1059
1138
|
duration: Math.max(0, Math.round(c * 1e3))
|
|
1060
1139
|
}, this.meta;
|
|
1061
1140
|
}
|
|
1062
1141
|
async tick(t) {
|
|
1063
|
-
const
|
|
1142
|
+
const o = [];
|
|
1064
1143
|
if (this.destroyed)
|
|
1065
|
-
return { audio:
|
|
1144
|
+
return { audio: o, state: "done" };
|
|
1066
1145
|
if (await this.ready, !this.renderer)
|
|
1067
|
-
return { audio:
|
|
1068
|
-
const
|
|
1069
|
-
if (t >=
|
|
1070
|
-
return { audio:
|
|
1071
|
-
const
|
|
1072
|
-
return await this.renderer.renderAt(
|
|
1146
|
+
return { audio: o, state: "done" };
|
|
1147
|
+
const i = this.meta.duration;
|
|
1148
|
+
if (t >= i)
|
|
1149
|
+
return { audio: o, state: "done" };
|
|
1150
|
+
const n = Math.max(0, Math.min(t, i));
|
|
1151
|
+
return await this.renderer.renderAt(n / 1e3), {
|
|
1073
1152
|
video: new VideoFrame(this.renderer.app.canvas, {
|
|
1074
1153
|
timestamp: t
|
|
1075
1154
|
}),
|
|
1076
|
-
audio:
|
|
1155
|
+
audio: o,
|
|
1077
1156
|
state: "success"
|
|
1078
1157
|
};
|
|
1079
1158
|
}
|
|
1080
1159
|
async clone() {
|
|
1081
|
-
const t = new
|
|
1160
|
+
const t = new at(this.protocol, this.options);
|
|
1082
1161
|
return await t.ready, t;
|
|
1083
1162
|
}
|
|
1084
1163
|
destroy() {
|
|
1085
1164
|
this.destroyed || (this.destroyed = !0, this.renderer?.destroy(), this.app?.destroy(!0));
|
|
1086
1165
|
}
|
|
1087
1166
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1167
|
+
const It = 12e3;
|
|
1168
|
+
function be(e, t, o) {
|
|
1169
|
+
return new Promise((i, n) => {
|
|
1170
|
+
const a = globalThis.setTimeout(() => {
|
|
1171
|
+
n(new Error(`composeProtocol: ${o} timed out (${t}ms)`));
|
|
1172
|
+
}, t);
|
|
1173
|
+
e.then((c) => {
|
|
1174
|
+
globalThis.clearTimeout(a), i(c);
|
|
1175
|
+
}).catch((c) => {
|
|
1176
|
+
globalThis.clearTimeout(a), n(c);
|
|
1177
|
+
});
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
class st {
|
|
1181
|
+
constructor(t, o) {
|
|
1182
|
+
this.sourceClip = t, this.config = o, this.ready = this.sourceClip.ready.then((i) => {
|
|
1183
|
+
const n = Math.round(this.config.segmentDurationUs * this.config.playRate), a = Math.max(0, i.duration - this.config.fromUs);
|
|
1184
|
+
return this.clipMeta = {
|
|
1185
|
+
width: i.width,
|
|
1186
|
+
height: i.height,
|
|
1187
|
+
duration: Math.max(0, Math.min(n, a))
|
|
1188
|
+
}, this.meta;
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
ready;
|
|
1192
|
+
clipMeta = {
|
|
1193
|
+
width: 0,
|
|
1194
|
+
height: 0,
|
|
1195
|
+
duration: 0
|
|
1196
|
+
};
|
|
1197
|
+
get meta() {
|
|
1198
|
+
return { ...this.clipMeta };
|
|
1199
|
+
}
|
|
1200
|
+
async tick(t) {
|
|
1201
|
+
const o = Math.max(0, Math.round(t)), i = Math.round(o / this.config.playRate);
|
|
1202
|
+
if (i >= this.config.segmentDurationUs)
|
|
1203
|
+
return {
|
|
1204
|
+
audio: [],
|
|
1205
|
+
state: "done"
|
|
1206
|
+
};
|
|
1207
|
+
const n = this.config.fromUs + o, a = await this.sourceClip.tick(n);
|
|
1208
|
+
ke(a.video);
|
|
1209
|
+
const c = this.resolveGain(i);
|
|
1210
|
+
return {
|
|
1211
|
+
audio: Ce(a.audio ?? [], c),
|
|
1212
|
+
state: a.state
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
async clone() {
|
|
1216
|
+
const t = await this.sourceClip.clone(), o = new st(t, this.config);
|
|
1217
|
+
return await o.ready, o;
|
|
1218
|
+
}
|
|
1219
|
+
destroy() {
|
|
1220
|
+
this.sourceClip.destroy();
|
|
1221
|
+
}
|
|
1222
|
+
resolveGain(t) {
|
|
1223
|
+
let o = 1;
|
|
1224
|
+
this.config.fadeInUs > 0 && t < this.config.fadeInUs && (o = Math.max(0, t / this.config.fadeInUs));
|
|
1225
|
+
const i = this.config.segmentDurationUs - t;
|
|
1226
|
+
return this.config.fadeOutUs > 0 && i < this.config.fadeOutUs && (o = Math.min(o, Math.max(0, i / this.config.fadeOutUs))), this.config.baseVolume * o;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
function ke(e) {
|
|
1230
|
+
if (!e || typeof e != "object")
|
|
1231
|
+
return;
|
|
1232
|
+
const t = e.close;
|
|
1233
|
+
typeof t == "function" && t.call(e);
|
|
1234
|
+
}
|
|
1235
|
+
function Ce(e, t) {
|
|
1236
|
+
return !e.length || t >= 0.999 ? e : t <= 0 ? e.map((o) => new Float32Array(o.length)) : e.map((o) => {
|
|
1237
|
+
const i = new Float32Array(o.length);
|
|
1238
|
+
for (let n = 0; n < o.length; n++)
|
|
1239
|
+
i[n] = o[n] * t;
|
|
1240
|
+
return i;
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
function j(e) {
|
|
1244
|
+
return Number.isFinite(e) ? Math.max(0, Math.round(e * 1e3)) : 0;
|
|
1245
|
+
}
|
|
1246
|
+
function rt(e) {
|
|
1247
|
+
return typeof e != "number" || !Number.isFinite(e) ? 1 : Math.max(0, Math.min(1, e));
|
|
1248
|
+
}
|
|
1249
|
+
function Re(e) {
|
|
1250
|
+
return typeof e != "number" || !Number.isFinite(e) ? 1 : Math.max(0.1, Math.min(100, e));
|
|
1251
|
+
}
|
|
1252
|
+
function Ae(e) {
|
|
1253
|
+
const t = Math.max(0, e.endTime - e.startTime), o = Math.max(0, Math.min(e.fadeInDuration ?? 0, t)), i = Math.max(0, Math.min(e.fadeOutDuration ?? 0, t));
|
|
1254
|
+
return {
|
|
1255
|
+
fromUs: j(e.fromTime ?? 0),
|
|
1256
|
+
segmentDurationUs: j(t),
|
|
1257
|
+
playRate: Re(e.playRate),
|
|
1258
|
+
baseVolume: rt(e.volume),
|
|
1259
|
+
fadeInUs: j(o),
|
|
1260
|
+
fadeOutUs: j(i)
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
function Ee(e) {
|
|
1264
|
+
return e.segmentType === "audio";
|
|
1265
|
+
}
|
|
1266
|
+
function Ie(e) {
|
|
1267
|
+
return e.segmentType === "frames" && e.type === "video";
|
|
1268
|
+
}
|
|
1269
|
+
async function Pt(e, t = It) {
|
|
1270
|
+
const o = new AbortController(), i = globalThis.setTimeout(() => o.abort(), t);
|
|
1271
|
+
try {
|
|
1272
|
+
const n = await fetch(e, { signal: o.signal });
|
|
1273
|
+
if (!n.body)
|
|
1274
|
+
throw new Error(`composeProtocol: unable to read resource stream: ${e}`);
|
|
1275
|
+
return n.body;
|
|
1276
|
+
} catch (n) {
|
|
1277
|
+
throw o.signal.aborted ? new Error(`composeProtocol: loading resource timed out (${t}ms): ${e}`) : n;
|
|
1278
|
+
} finally {
|
|
1279
|
+
globalThis.clearTimeout(i);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
async function Ft(e, t) {
|
|
1283
|
+
const o = Ae(t), i = new st(e, o), n = new nt(i);
|
|
1284
|
+
try {
|
|
1285
|
+
await be(n.ready, It, "prepare audio sprite");
|
|
1286
|
+
} catch (a) {
|
|
1287
|
+
throw n.destroy(), a;
|
|
1288
|
+
}
|
|
1289
|
+
return n.time.offset = j(t.startTime), n.time.duration = o.segmentDurationUs, n.time.playbackRate = o.playRate, n;
|
|
1290
|
+
}
|
|
1291
|
+
async function Pe(e) {
|
|
1292
|
+
const t = await Pt(e.url), o = new Tt(t);
|
|
1293
|
+
return await Ft(o, e);
|
|
1294
|
+
}
|
|
1295
|
+
async function Fe(e) {
|
|
1296
|
+
const t = await Pt(e.url), o = new K(t, { audio: !0 });
|
|
1297
|
+
return await Ft(o, e);
|
|
1298
|
+
}
|
|
1299
|
+
async function Ue(e) {
|
|
1300
|
+
const t = [];
|
|
1301
|
+
for (const n of e.tracks)
|
|
1302
|
+
for (const a of n.children)
|
|
1303
|
+
if (!(a.endTime <= a.startTime)) {
|
|
1304
|
+
if (Ee(a)) {
|
|
1305
|
+
if (rt(a.volume) <= 0)
|
|
1306
|
+
continue;
|
|
1307
|
+
t.push(Pe(a));
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1310
|
+
if (Ie(a)) {
|
|
1311
|
+
if (rt(a.volume) <= 0)
|
|
1312
|
+
continue;
|
|
1313
|
+
t.push(Fe(a));
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
if (!t.length)
|
|
1317
|
+
return [];
|
|
1318
|
+
const o = await Promise.allSettled(t), i = [];
|
|
1319
|
+
for (const n of o) {
|
|
1320
|
+
if (n.status === "fulfilled") {
|
|
1321
|
+
i.push(n.value);
|
|
1322
|
+
continue;
|
|
1323
|
+
}
|
|
1324
|
+
console.warn("[compose] skip audio sprite due to load failure", n.reason);
|
|
1325
|
+
}
|
|
1326
|
+
return i;
|
|
1327
|
+
}
|
|
1328
|
+
function ot(e) {
|
|
1329
|
+
for (const t of e)
|
|
1330
|
+
t.destroy();
|
|
1331
|
+
}
|
|
1332
|
+
function Oe(e, t) {
|
|
1333
|
+
let o = !1;
|
|
1334
|
+
const i = () => {
|
|
1335
|
+
o || (o = !0, t());
|
|
1336
|
+
}, n = e.getReader();
|
|
1093
1337
|
return new ReadableStream({
|
|
1094
|
-
async pull(
|
|
1095
|
-
const { done: c, value:
|
|
1338
|
+
async pull(a) {
|
|
1339
|
+
const { done: c, value: u } = await n.read();
|
|
1096
1340
|
if (c) {
|
|
1097
|
-
|
|
1341
|
+
i(), a.close();
|
|
1098
1342
|
return;
|
|
1099
1343
|
}
|
|
1100
|
-
|
|
1344
|
+
a.enqueue(u);
|
|
1101
1345
|
},
|
|
1102
|
-
async cancel(
|
|
1346
|
+
async cancel(a) {
|
|
1103
1347
|
try {
|
|
1104
|
-
await
|
|
1348
|
+
await n.cancel(a);
|
|
1105
1349
|
} finally {
|
|
1106
|
-
|
|
1350
|
+
i();
|
|
1107
1351
|
}
|
|
1108
1352
|
}
|
|
1109
1353
|
});
|
|
1110
1354
|
}
|
|
1111
|
-
async function
|
|
1355
|
+
async function Ge(e, t = {}) {
|
|
1112
1356
|
const {
|
|
1113
|
-
width:
|
|
1114
|
-
height:
|
|
1115
|
-
fps:
|
|
1116
|
-
onProgress:
|
|
1357
|
+
width: o,
|
|
1358
|
+
height: i,
|
|
1359
|
+
fps: n,
|
|
1360
|
+
onProgress: a,
|
|
1117
1361
|
clipOptions: c,
|
|
1118
|
-
audioSprites:
|
|
1119
|
-
...
|
|
1120
|
-
} = t,
|
|
1121
|
-
if (!
|
|
1362
|
+
audioSprites: u,
|
|
1363
|
+
...d
|
|
1364
|
+
} = t, y = o ?? e.width, h = i ?? e.height;
|
|
1365
|
+
if (!y || !h)
|
|
1122
1366
|
throw new Error("composeProtocol: output width/height is required");
|
|
1123
|
-
const
|
|
1124
|
-
...
|
|
1125
|
-
audio:
|
|
1126
|
-
width:
|
|
1367
|
+
const w = n ?? e.fps, M = d.audio === !1 ? [] : typeof u == "function" ? await u(e) : await Ue(e), p = d.audio ?? (M.length > 0 ? void 0 : !1), v = new bt({
|
|
1368
|
+
...d,
|
|
1369
|
+
audio: p,
|
|
1370
|
+
width: y,
|
|
1127
1371
|
height: h,
|
|
1128
|
-
fps:
|
|
1372
|
+
fps: w
|
|
1129
1373
|
});
|
|
1130
|
-
|
|
1131
|
-
let
|
|
1374
|
+
a && v.on("OutputProgress", a);
|
|
1375
|
+
let m, g;
|
|
1132
1376
|
try {
|
|
1133
|
-
|
|
1134
|
-
width:
|
|
1377
|
+
m = new at(e, {
|
|
1378
|
+
width: y,
|
|
1135
1379
|
height: h,
|
|
1136
|
-
fps:
|
|
1380
|
+
fps: w,
|
|
1137
1381
|
...c,
|
|
1138
1382
|
rendererOptions: {
|
|
1139
1383
|
warmUpResources: !1,
|
|
1140
1384
|
...c?.rendererOptions
|
|
1141
1385
|
}
|
|
1142
|
-
}), await
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
} catch (L) {
|
|
1148
|
-
throw k.destroy(), L;
|
|
1386
|
+
}), await m.ready, g = new nt(m), await g.ready, g.time.offset = 0, g.time.duration = m.meta.duration, g.rect.x = 0, g.rect.y = 0, g.rect.w = m.meta.width, g.rect.h = m.meta.height, await v.addSprite(g, { main: !0 });
|
|
1387
|
+
for (const b of M)
|
|
1388
|
+
await v.addSprite(b);
|
|
1389
|
+
} catch (b) {
|
|
1390
|
+
throw ot(M), g?.destroy(), m?.destroy(), v.destroy(), b;
|
|
1149
1391
|
}
|
|
1150
|
-
const R =
|
|
1392
|
+
const R = m?.meta.duration ?? 0;
|
|
1151
1393
|
if (!R)
|
|
1152
|
-
throw new Error("composeProtocol: protocol has no duration");
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1394
|
+
throw ot(M), g?.destroy(), m?.destroy(), v.destroy(), new Error("composeProtocol: protocol has no duration");
|
|
1395
|
+
const P = v.output({ maxTime: R });
|
|
1396
|
+
let A = !1;
|
|
1397
|
+
const E = () => {
|
|
1398
|
+
A || (A = !0, ot(M), g?.destroy(), m?.destroy(), v.destroy());
|
|
1155
1399
|
};
|
|
1156
1400
|
return {
|
|
1157
|
-
stream:
|
|
1158
|
-
width:
|
|
1401
|
+
stream: Oe(P, E),
|
|
1402
|
+
width: y,
|
|
1159
1403
|
height: h,
|
|
1160
1404
|
durationMs: Math.round(R / 1e3),
|
|
1161
|
-
destroy:
|
|
1405
|
+
destroy: E
|
|
1162
1406
|
};
|
|
1163
1407
|
}
|
|
1164
1408
|
export {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1409
|
+
at as ProtocolVideoClip,
|
|
1410
|
+
Ge as composeProtocol,
|
|
1411
|
+
Ne as concatVideos,
|
|
1412
|
+
ve as createRenderer
|
|
1169
1413
|
};
|
|
1170
1414
|
//# sourceMappingURL=index.js.map
|