@video-editor/ui 0.0.1-beta.29 → 0.0.1-beta.31

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.
@@ -0,0 +1,782 @@
1
+ import { defineComponent as X, ref as V, onMounted as ce, onBeforeUnmount as de, watch as N, nextTick as we, createElementBlock as p, openBlock as h, createElementVNode as R, reactive as Z, computed as D, renderSlot as b, normalizeStyle as J, createVNode as H, createCommentVNode as j, toDisplayString as G, Fragment as ee, renderList as le, normalizeClass as _e, withModifiers as se, watchEffect as Re, createBlock as $e, createSlots as Be, withCtx as K, unref as L, normalizeProps as re, guardReactiveProps as oe } from "vue";
2
+ import { extractWaveform as pe, generateThumbnails as Ae, getMp4Meta as ke } from "@video-editor/protocol";
3
+ import { isVideoFramesSegment as F, isAudioSegment as Ie } from "@video-editor/shared";
4
+ import { _ as Y, V as We } from "./index-C0eQjJkj.js";
5
+ const xe = /* @__PURE__ */ X({
6
+ name: "WaveformCanvasStrip",
7
+ __name: "WaveformCanvasStrip",
8
+ props: {
9
+ peaks: {},
10
+ barColor: { default: "#2B2B2B" },
11
+ minBarHeight: { default: 3 },
12
+ maxBarWidth: { default: 4 },
13
+ barGap: { default: 1 },
14
+ maxBufferWidth: { default: 2048 },
15
+ maxBufferHeight: { default: 256 }
16
+ },
17
+ setup(o) {
18
+ const v = o, i = V(null), k = V(null), M = V({ width: 0, height: 0 });
19
+ let u = null;
20
+ function A(t, l, m) {
21
+ return Math.min(Math.max(t, l), m);
22
+ }
23
+ function x(t) {
24
+ return A(Number.isFinite(t) ? t : 0, 0, 1);
25
+ }
26
+ function _() {
27
+ const t = i.value;
28
+ t && (M.value = {
29
+ width: Math.max(t.clientWidth, 0),
30
+ height: Math.max(t.clientHeight, 0)
31
+ });
32
+ }
33
+ function g() {
34
+ const t = k.value;
35
+ if (!t)
36
+ return;
37
+ const l = M.value.width, m = M.value.height;
38
+ if (l <= 0 || m <= 0)
39
+ return;
40
+ const T = Math.min(window.devicePixelRatio || 1, 2), S = A(Math.round(l * T), 1, v.maxBufferWidth), $ = A(Math.round(m * T), 1, v.maxBufferHeight);
41
+ t.width !== S && (t.width = S), t.height !== $ && (t.height = $);
42
+ const I = t.getContext("2d");
43
+ if (!I)
44
+ return;
45
+ const P = S / l, E = $ / m;
46
+ I.setTransform(P, 0, 0, E, 0, 0), I.clearRect(0, 0, l, m);
47
+ const B = v.peaks;
48
+ if (!B.length)
49
+ return;
50
+ const C = l / B.length;
51
+ if (!Number.isFinite(C) || C <= 0)
52
+ return;
53
+ const z = Math.min(v.barGap, Math.max(0, C - 0.1));
54
+ I.fillStyle = v.barColor;
55
+ for (let U = 0; U < B.length; U++) {
56
+ const e = U * C, r = e + C, n = e + z / 2, y = r - z / 2 - n;
57
+ if (y <= 0)
58
+ continue;
59
+ const f = Math.min(v.maxBarWidth, y), a = n + (y - f) / 2, s = x(B[U] ?? 0), d = Math.max(v.minBarHeight, s * m * 0.88), w = (m - d) / 2;
60
+ I.fillRect(a, w, f, d);
61
+ }
62
+ }
63
+ return ce(() => {
64
+ _();
65
+ const t = i.value;
66
+ t && (u = new ResizeObserver(() => {
67
+ _();
68
+ }), u.observe(t));
69
+ }), de(() => {
70
+ u?.disconnect(), u = null;
71
+ }), N(
72
+ [
73
+ () => v.peaks,
74
+ () => v.barColor,
75
+ () => v.minBarHeight,
76
+ () => v.maxBarWidth,
77
+ () => v.barGap,
78
+ () => v.maxBufferWidth,
79
+ () => v.maxBufferHeight,
80
+ () => M.value.width,
81
+ () => M.value.height
82
+ ],
83
+ async () => {
84
+ await we(), g();
85
+ },
86
+ { immediate: !0, flush: "post" }
87
+ ), (t, l) => (h(), p("div", {
88
+ ref_key: "containerRef",
89
+ ref: i,
90
+ class: "waveform-canvas-strip"
91
+ }, [
92
+ R("canvas", {
93
+ ref_key: "canvasRef",
94
+ ref: k,
95
+ class: "waveform-canvas-strip__canvas"
96
+ }, null, 512)
97
+ ], 512));
98
+ }
99
+ }), ye = /* @__PURE__ */ Y(xe, [["__scopeId", "data-v-7cbe9830"]]), Pe = {
100
+ key: 1,
101
+ class: "audio-segment__placeholder"
102
+ }, Ee = {
103
+ key: 0,
104
+ class: "audio-segment__badge"
105
+ }, Ce = 1, ze = 1, De = 4096, Ve = /* @__PURE__ */ X({
106
+ name: "AudioSegment",
107
+ __name: "AudioSegment",
108
+ props: {
109
+ segment: {}
110
+ },
111
+ setup(o) {
112
+ const v = o, i = V(null), k = V(0);
113
+ let M = null;
114
+ ce(() => {
115
+ i.value && (k.value = i.value.clientWidth, M = new ResizeObserver((t) => {
116
+ for (const l of t)
117
+ k.value = l.contentRect.width;
118
+ }), M.observe(i.value));
119
+ }), de(() => {
120
+ M?.disconnect();
121
+ });
122
+ const u = Z({
123
+ data: null,
124
+ loading: !1,
125
+ error: null,
126
+ loadedUrl: null
127
+ });
128
+ let A = 0;
129
+ N(() => v.segment.url, (t, l) => {
130
+ t && t !== l && x(t);
131
+ }, { immediate: !0 });
132
+ async function x(t) {
133
+ if (!t || u.loadedUrl === t && u.data)
134
+ return;
135
+ const l = ++A;
136
+ u.loading = !0, u.error = null;
137
+ try {
138
+ const m = await pe(t, { samples: 1e3 });
139
+ if (A !== l)
140
+ return;
141
+ u.data = m, u.loadedUrl = t, u.loading = !1;
142
+ } catch (m) {
143
+ if (A !== l)
144
+ return;
145
+ u.error = m instanceof Error ? m.message : String(m), u.loading = !1;
146
+ }
147
+ }
148
+ function _(t, l) {
149
+ if (l >= t.length)
150
+ return t;
151
+ const m = [], T = t.length / l;
152
+ for (let S = 0; S < l; S++) {
153
+ const $ = Math.floor(S * T), I = Math.max($ + 1, Math.ceil((S + 1) * T));
154
+ let P = 0;
155
+ for (let E = $; E < I; E++) {
156
+ const B = t[E] ?? 0;
157
+ B > P && (P = B);
158
+ }
159
+ m.push(P);
160
+ }
161
+ return m;
162
+ }
163
+ const g = D(() => {
164
+ if (!u.data)
165
+ return { peaks: [], renderPeaks: [], coveragePercent: 100 };
166
+ const t = v.segment, l = u.data.duration * 1e3, m = u.data.peaks, T = t.fromTime ?? 0, S = t.endTime - t.startTime, $ = t.playRate ?? 1, I = S * $, P = Math.max(0, l - T), E = Math.min(I, P), B = S > 0 ? Math.min(100, E / $ / S * 100) : 0, C = T / l, z = (T + E) / l, U = Math.floor(C * m.length), e = Math.ceil(z * m.length), r = m.slice(
167
+ Math.max(0, U),
168
+ Math.min(m.length, e)
169
+ );
170
+ if (!r.length)
171
+ return { peaks: [], renderPeaks: [], coveragePercent: B };
172
+ const n = k.value * (B / 100), c = n > 0 ? Math.min(
173
+ De,
174
+ Math.max(1, Math.floor(n / (Ce + ze)))
175
+ ) : r.length;
176
+ return {
177
+ peaks: r,
178
+ renderPeaks: _(r, c),
179
+ coveragePercent: B
180
+ };
181
+ });
182
+ return (t, l) => (h(), p("div", {
183
+ ref_key: "containerRef",
184
+ ref: i,
185
+ class: "audio-segment"
186
+ }, [
187
+ u.data && g.value.renderPeaks.length ? b(t.$slots, "waveform", {
188
+ key: 0,
189
+ segment: o.segment,
190
+ waveform: u.data,
191
+ peaks: g.value.renderPeaks,
192
+ rawPeaks: g.value.peaks,
193
+ coveragePercent: g.value.coveragePercent
194
+ }, () => [
195
+ R("div", {
196
+ class: "audio-segment__waveform",
197
+ style: J({ width: `${g.value.coveragePercent}%` })
198
+ }, [
199
+ H(ye, {
200
+ class: "audio-segment__waveform-canvas",
201
+ peaks: g.value.renderPeaks,
202
+ "bar-color": "#2B2B2B",
203
+ "min-bar-height": 4,
204
+ "max-bar-width": 4,
205
+ "bar-gap": 1
206
+ }, null, 8, ["peaks"])
207
+ ], 4)
208
+ ], !0) : (h(), p("div", Pe, [
209
+ u.loading ? b(t.$slots, "loading", {
210
+ key: 0,
211
+ segment: o.segment
212
+ }, () => [
213
+ l[0] || (l[0] = R("span", null, "加载波形…", -1))
214
+ ], !0) : u.error ? b(t.$slots, "error", {
215
+ key: 1,
216
+ segment: o.segment,
217
+ error: u.error
218
+ }, () => [
219
+ l[1] || (l[1] = R("span", null, "波形加载失败", -1))
220
+ ], !0) : b(t.$slots, "empty", {
221
+ key: 2,
222
+ segment: o.segment
223
+ }, () => [
224
+ l[2] || (l[2] = R("div", { class: "waveform-pattern" }, null, -1))
225
+ ], !0)
226
+ ])),
227
+ b(t.$slots, "overlay", { segment: o.segment }, () => [
228
+ o.segment.extra?.label ? (h(), p("span", Ee, G(o.segment.extra?.label), 1)) : j("", !0)
229
+ ], !0)
230
+ ], 512));
231
+ }
232
+ }), Ue = /* @__PURE__ */ Y(Ve, [["__scopeId", "data-v-47cbc534"]]), Fe = { class: "frames-segment" }, Oe = { class: "frames-segment__video-wrap" }, He = { class: "frames-segment__video" }, Ne = {
233
+ key: 1,
234
+ class: "frames-segment__placeholder frames-segment__placeholder--video"
235
+ }, je = {
236
+ key: 0,
237
+ class: "frames-segment__waveform",
238
+ style: { width: "100%" }
239
+ }, Le = {
240
+ key: 1,
241
+ class: "frames-segment__waveform-pattern"
242
+ }, Ge = { class: "frames-segment__placeholder" }, Je = {
243
+ key: 0,
244
+ class: "frames-segment__overlay"
245
+ }, Xe = {
246
+ key: 0,
247
+ class: "frames-segment__badge"
248
+ }, Ye = ["aria-label", "title"], qe = {
249
+ key: 0,
250
+ class: "frames-segment__mute-icon i-creatly-mute",
251
+ "aria-hidden": "true"
252
+ }, Ke = {
253
+ key: 1,
254
+ class: "frames-segment__mute-icon i-creatly-sound",
255
+ "aria-hidden": "true"
256
+ }, Qe = 1, Ze = 1, et = 4096, tt = /* @__PURE__ */ X({
257
+ name: "FramesSegment",
258
+ __name: "FramesSegment",
259
+ props: {
260
+ segment: {}
261
+ },
262
+ emits: ["toggle-video-mute"],
263
+ setup(o, { emit: v }) {
264
+ const i = o, k = v, M = V(null), u = V(null), A = V(1), x = V(0);
265
+ let _ = null;
266
+ ce(() => {
267
+ _ = new ResizeObserver((a) => {
268
+ for (const s of a) {
269
+ if (s.target === M.value) {
270
+ const d = Math.max(1, Math.ceil(s.contentRect.width / 56));
271
+ A.value !== d && (A.value = d);
272
+ }
273
+ s.target === u.value && (x.value = s.contentRect.width);
274
+ }
275
+ }), M.value && _.observe(M.value), u.value && (x.value = u.value.clientWidth, _.observe(u.value));
276
+ }), de(() => {
277
+ _?.disconnect(), C();
278
+ }), N(u, (a, s) => {
279
+ _ && s && _.unobserve(s), _ && a && (x.value = a.clientWidth, _.observe(a));
280
+ });
281
+ const g = Z({ items: [], loading: !1, error: null }), t = Z({
282
+ data: null,
283
+ hasAudio: null,
284
+ loading: !1,
285
+ error: null,
286
+ loadedUrl: null
287
+ });
288
+ let l = 0, m = 0, T, S = null;
289
+ N(() => i.segment, (a, s) => {
290
+ if (!F(a))
291
+ return;
292
+ (!s || $(s, a)) && I(a, s);
293
+ }, { immediate: !0, deep: !0 }), N(() => i.segment, (a, s) => {
294
+ if (!F(a))
295
+ return;
296
+ const d = a, w = s && F(s) ? s : void 0;
297
+ d.url && d.url !== w?.url && E(d.url);
298
+ }, { immediate: !0, deep: !0 });
299
+ function $(a, s) {
300
+ return a.url !== s.url || a.startTime !== s.startTime || a.endTime !== s.endTime || a.fromTime !== s.fromTime;
301
+ }
302
+ function I(a, s) {
303
+ const d = !s || s.url !== a.url, w = !s || s.fromTime !== a.fromTime, W = d || w;
304
+ if (S = a, T && (window.clearTimeout(T), T = void 0), W) {
305
+ P(a);
306
+ return;
307
+ }
308
+ T = window.setTimeout(() => {
309
+ S && P(S), T = void 0;
310
+ }, 240);
311
+ }
312
+ async function P(a) {
313
+ if (!a.url)
314
+ return;
315
+ const s = ++l;
316
+ C(), g.loading = !0, g.error = null;
317
+ try {
318
+ const d = B(a), w = await Ae(a.url, d);
319
+ if (l !== s)
320
+ return;
321
+ const W = w.map((O) => ({
322
+ tsMs: Math.round(O.ts / 1e3),
323
+ url: URL.createObjectURL(O.img)
324
+ }));
325
+ g.items = W, g.loading = !1;
326
+ } catch (d) {
327
+ if (l !== s)
328
+ return;
329
+ g.error = d instanceof Error ? d.message : String(d), g.loading = !1;
330
+ }
331
+ }
332
+ async function E(a) {
333
+ if (!a || t.loadedUrl === a && (t.data || t.hasAudio === !1))
334
+ return;
335
+ const s = ++m;
336
+ t.loadedUrl !== a && (t.data = null, t.hasAudio = null), t.loading = !0, t.error = null;
337
+ try {
338
+ const d = await ke(a);
339
+ if (m !== s)
340
+ return;
341
+ const w = (d.audioChanCount ?? 0) > 0;
342
+ if (t.hasAudio = w, !w) {
343
+ t.data = null, t.loadedUrl = a, t.loading = !1;
344
+ return;
345
+ }
346
+ const W = await pe(a, { samples: 1e3 });
347
+ if (m !== s)
348
+ return;
349
+ t.data = W, t.hasAudio = !0, t.loadedUrl = a, t.loading = !1;
350
+ } catch (d) {
351
+ if (m !== s)
352
+ return;
353
+ t.data = null, t.error = d instanceof Error ? d.message : String(d), t.loading = !1;
354
+ }
355
+ }
356
+ function B(a) {
357
+ const s = Math.max(a.fromTime ?? 0, 0) * 1e3, d = Math.max(a.endTime - a.startTime, 1), w = s + d * 1e3, O = Math.max(Math.floor((w - s) / 8), 2e5);
358
+ return { start: s, end: w, step: O };
359
+ }
360
+ function C() {
361
+ g.items.forEach((a) => URL.revokeObjectURL(a.url)), g.items = [];
362
+ }
363
+ const z = D(() => {
364
+ if (!F(i.segment))
365
+ return { peaks: [], coveragePercent: 100 };
366
+ if (!t.data)
367
+ return { peaks: [], coveragePercent: 100 };
368
+ const a = i.segment, s = Math.max(a.endTime - a.startTime, 0);
369
+ if (s <= 0)
370
+ return { peaks: [], coveragePercent: 100 };
371
+ const d = Math.max(x.value, 1), w = Math.min(
372
+ et,
373
+ Math.max(1, Math.floor(d / (Qe + Ze)))
374
+ ), W = t.data.duration * 1e3, O = t.data.peaks;
375
+ if (!Number.isFinite(W) || W <= 0 || O.length === 0)
376
+ return { peaks: new Array(w).fill(0), coveragePercent: 100 };
377
+ const ue = Math.max(a.fromTime ?? 0, 0), be = Math.max(a.playRate ?? 1, 1e-4), me = s * be, te = [];
378
+ for (let q = 0; q < w; q++) {
379
+ const fe = ue + me * q / w, ge = ue + me * (q + 1) / w;
380
+ if (fe >= W || ge <= 0) {
381
+ te.push(0);
382
+ continue;
383
+ }
384
+ const Me = Math.max(fe, 0), Te = Math.min(ge, W), he = Math.floor(Me / W * O.length), Se = Math.max(he + 1, Math.ceil(Te / W * O.length));
385
+ let ne = 0;
386
+ for (let ae = he; ae < Se; ae++) {
387
+ const ve = O[ae] ?? 0;
388
+ ve > ne && (ne = ve);
389
+ }
390
+ te.push(ne);
391
+ }
392
+ return { peaks: te, coveragePercent: 100 };
393
+ }), U = D(() => t.hasAudio !== !1), e = D(() => !!i.segment.extra?.label), r = D(() => F(i.segment) && t.hasAudio !== !1), n = V(null), c = D(() => F(i.segment) ? (i.segment.volume ?? 1) <= 0 : !1), y = D(() => n.value ?? c.value);
394
+ N(() => i.segment.id, () => {
395
+ n.value = null;
396
+ }), N(() => {
397
+ if (F(i.segment))
398
+ return i.segment.volume;
399
+ }, () => {
400
+ n.value = null;
401
+ });
402
+ function f(a) {
403
+ if (a.preventDefault(), a.stopPropagation(), !F(i.segment))
404
+ return;
405
+ const s = !y.value;
406
+ n.value = s, k("toggle-video-mute", {
407
+ segmentId: i.segment.id,
408
+ muted: s
409
+ });
410
+ }
411
+ return (a, s) => (h(), p("div", Fe, [
412
+ o.segment.type === "image" ? b(a.$slots, "image", {
413
+ key: 0,
414
+ segment: o.segment,
415
+ style: J({ backgroundImage: o.segment.url ? `url(${o.segment.url})` : "" })
416
+ }, () => [
417
+ R("div", {
418
+ ref_key: "containerRef",
419
+ ref: M,
420
+ class: "frames-segment__image"
421
+ }, [
422
+ (h(!0), p(ee, null, le(A.value, (d) => (h(), p("div", {
423
+ key: d,
424
+ class: "frames-segment__image-item",
425
+ style: J({ backgroundImage: o.segment.url ? `url(${o.segment.url})` : "" })
426
+ }, null, 4))), 128))
427
+ ], 512)
428
+ ], !0) : o.segment.type === "video" ? b(a.$slots, "video", {
429
+ key: 1,
430
+ segment: o.segment,
431
+ thumbnails: g.items,
432
+ waveformPeaks: z.value.peaks,
433
+ waveformCoveragePercent: z.value.coveragePercent
434
+ }, () => [
435
+ R("div", Oe, [
436
+ R("div", He, [
437
+ g.items.length ? (h(!0), p(ee, { key: 0 }, le(g.items, (d) => (h(), p("div", {
438
+ key: `${o.segment.id}-${d.tsMs}`,
439
+ class: "frames-segment__thumb",
440
+ style: J({ backgroundImage: `url(${d.url})` })
441
+ }, null, 4))), 128)) : (h(), p("div", Ne, [
442
+ g.loading ? b(a.$slots, "loading", {
443
+ key: 0,
444
+ segment: o.segment
445
+ }, () => [
446
+ s[2] || (s[2] = R("span", null, "抽帧中…", -1))
447
+ ], !0) : g.error ? b(a.$slots, "error", {
448
+ key: 1,
449
+ segment: o.segment,
450
+ error: g.error
451
+ }, () => [
452
+ s[3] || (s[3] = R("span", null, "生成失败", -1))
453
+ ], !0) : b(a.$slots, "empty", {
454
+ key: 2,
455
+ segment: o.segment
456
+ }, () => [
457
+ s[4] || (s[4] = R("span", null, "未生成缩略图", -1))
458
+ ], !0)
459
+ ]))
460
+ ]),
461
+ U.value ? (h(), p("div", {
462
+ key: 0,
463
+ ref_key: "waveformRef",
464
+ ref: u,
465
+ class: _e(["frames-segment__waveform-strip", { "frames-segment__waveform-strip--muted": y.value }])
466
+ }, [
467
+ z.value.peaks.length ? (h(), p("div", je, [
468
+ H(ye, {
469
+ class: "frames-segment__waveform-canvas",
470
+ peaks: z.value.peaks,
471
+ "bar-color": "#3f3f46",
472
+ "min-bar-height": 3,
473
+ "max-bar-width": 4,
474
+ "bar-gap": 1
475
+ }, null, 8, ["peaks"])
476
+ ])) : (h(), p("div", Le))
477
+ ], 2)) : j("", !0)
478
+ ])
479
+ ], !0) : b(a.$slots, "fallback", {
480
+ key: 2,
481
+ segment: o.segment
482
+ }, () => [
483
+ R("div", Ge, [
484
+ R("span", null, G(o.segment.type), 1)
485
+ ])
486
+ ], !0),
487
+ b(a.$slots, "overlay", {
488
+ segment: o.segment,
489
+ isMuted: y.value,
490
+ toggleMute: f,
491
+ showMuteButton: r.value
492
+ }, () => [
493
+ e.value || r.value ? (h(), p("div", Je, [
494
+ o.segment.extra?.label ? (h(), p("span", Xe, G(o.segment.extra?.label), 1)) : j("", !0),
495
+ r.value ? (h(), p("button", {
496
+ key: 1,
497
+ type: "button",
498
+ class: "frames-segment__mute-btn",
499
+ "aria-label": y.value ? "取消静音视频片段" : "静音视频片段",
500
+ title: y.value ? "取消静音" : "静音",
501
+ onClick: se(f, ["stop"]),
502
+ onPointerdown: s[0] || (s[0] = se(() => {
503
+ }, ["stop"])),
504
+ onDblclick: s[1] || (s[1] = se(() => {
505
+ }, ["stop"]))
506
+ }, [
507
+ y.value ? (h(), p("span", qe)) : (h(), p("span", Ke))
508
+ ], 40, Ye)) : j("", !0)
509
+ ])) : j("", !0)
510
+ ], !0)
511
+ ]));
512
+ }
513
+ }), nt = /* @__PURE__ */ Y(tt, [["__scopeId", "data-v-f389074c"]]), at = { class: "segment-base" }, st = { class: "segment-base__content" }, rt = { class: "segment-base__pill segment-base__pill--primary" }, ot = { class: "segment-base__pill segment-base__pill--muted" }, it = {
514
+ key: 0,
515
+ class: "segment-base__badge"
516
+ }, lt = /* @__PURE__ */ X({
517
+ name: "SegmentBase",
518
+ __name: "SegmentBase",
519
+ props: {
520
+ segment: {},
521
+ trackType: {},
522
+ accentColor: { default: "#222226" }
523
+ },
524
+ setup(o) {
525
+ const v = o, i = D(() => {
526
+ const k = v.segment?.extra?.label;
527
+ return typeof k == "string" ? k : null;
528
+ });
529
+ return (k, M) => (h(), p("div", at, [
530
+ R("div", st, [
531
+ R("span", rt, G(o.trackType), 1),
532
+ R("span", ot, G(o.segment.segmentType), 1)
533
+ ]),
534
+ i.value ? (h(), p("span", it, G(i.value), 1)) : j("", !0)
535
+ ]));
536
+ }
537
+ }), Q = /* @__PURE__ */ Y(lt, [["__scopeId", "data-v-d386af72"]]), ct = { class: "ve-editor-segment__preview" }, ie = "#222226", dt = 0.4, ut = /* @__PURE__ */ X({
538
+ name: "VideoEditorTimeline",
539
+ __name: "index",
540
+ props: {
541
+ protocol: { default: null },
542
+ currentTime: {},
543
+ zoom: {},
544
+ snapStep: { default: 0 },
545
+ selectedSegmentId: { default: null },
546
+ trackTypes: { default: void 0 },
547
+ disableInteraction: { type: Boolean, default: !1 }
548
+ },
549
+ emits: ["update:currentTime", "update:zoom", "update:selectedSegmentId", "segmentClick", "segmentDragEnd", "segmentResizeEnd", "videoSegmentMuteToggle", "add-segment"],
550
+ setup(o, { emit: v }) {
551
+ const i = o, k = v, M = V(i.selectedSegmentId ?? null);
552
+ N(() => i.selectedSegmentId, (e) => {
553
+ M.value = e ?? null;
554
+ });
555
+ const u = {
556
+ frames: ie,
557
+ audio: "#0ea5e9",
558
+ text: "#16a34a",
559
+ sticker: "#f97316",
560
+ effect: "#a855f7",
561
+ filter: "#64748b"
562
+ }, A = D(() => {
563
+ if (!i.protocol?.tracks?.length)
564
+ return [];
565
+ const r = (i.trackTypes?.length ? i.protocol.tracks.filter((f) => i.trackTypes?.includes(f.trackType)) : i.protocol.tracks).slice(), n = r.find((f) => f.trackType === "frames" && f.isMain === !0), c = r.filter((f) => !(f.trackType === "audio" || f === n)), y = r.filter((f) => f.trackType === "audio");
566
+ return [
567
+ ...c,
568
+ ...n ? [n] : [],
569
+ ...y
570
+ ];
571
+ }), x = Z(/* @__PURE__ */ new Map()), _ = /* @__PURE__ */ new Map();
572
+ function g(e) {
573
+ if (!e || x.has(e) || _.has(e))
574
+ return;
575
+ const r = (async () => {
576
+ try {
577
+ const n = await ke(e);
578
+ x.set(e, n.durationMs);
579
+ } catch {
580
+ }
581
+ })().finally(() => {
582
+ _.delete(e);
583
+ });
584
+ _.set(e, r);
585
+ }
586
+ const t = D(() => A.value.map((e, r) => {
587
+ const n = u[e.trackType] || ie, c = m(n, dt), y = e.trackType === "frames" && e.isMain === !0;
588
+ return {
589
+ id: e.trackId || `${e.trackType}-${r}`,
590
+ label: e.trackType,
591
+ type: e.trackType,
592
+ color: n,
593
+ isMain: y,
594
+ payload: e,
595
+ segments: e.children.map((f) => ({
596
+ ...F(f) ? { fromTime: f.fromTime ?? 0, sourceDurationMs: x.get(f.url) } : Ie(f) ? { fromTime: f.fromTime ?? 0 } : {},
597
+ id: f.id,
598
+ start: f.startTime,
599
+ end: f.endTime,
600
+ type: f.segmentType,
601
+ color: c,
602
+ payload: f
603
+ }))
604
+ };
605
+ }));
606
+ Re(() => {
607
+ for (const e of A.value)
608
+ for (const r of e.children)
609
+ F(r) && g(r.url);
610
+ });
611
+ const l = D(() => {
612
+ if (!i.protocol?.tracks?.length)
613
+ return 0;
614
+ const e = i.protocol.tracks.flatMap((r) => r.children.map((n) => n.endTime));
615
+ return e.length ? Math.max(...e) : 0;
616
+ });
617
+ function m(e, r) {
618
+ const n = e.replace("#", "");
619
+ if (!(n.length === 3 || n.length === 6))
620
+ return e;
621
+ const c = n.length === 3 ? n.split("").map((s) => s + s).join("") : n, y = Number.parseInt(c.slice(0, 2), 16), f = Number.parseInt(c.slice(2, 4), 16), a = Number.parseInt(c.slice(4, 6), 16);
622
+ return `rgba(${y}, ${f}, ${a}, ${r})`;
623
+ }
624
+ function T(e) {
625
+ return e && typeof e == "object" && "segmentType" in e ? e : null;
626
+ }
627
+ function S(e) {
628
+ const r = e.payload;
629
+ if (r)
630
+ return r;
631
+ if (i.protocol)
632
+ return i.protocol.tracks.find((n) => n.trackId === e.id);
633
+ }
634
+ function $(e) {
635
+ M.value = e, k("update:selectedSegmentId", e);
636
+ }
637
+ function I(e) {
638
+ const r = T(e.segment.payload), n = S(e.track);
639
+ r && ($(r.id), n && k("segmentClick", { segment: r, track: n }));
640
+ }
641
+ function P(e) {
642
+ $(e.segment.id);
643
+ }
644
+ function E(e) {
645
+ k("segmentDragEnd", e);
646
+ }
647
+ function B(e) {
648
+ $(e.segment.id);
649
+ }
650
+ function C(e) {
651
+ k("segmentResizeEnd", e);
652
+ }
653
+ function z({ track: e, startTime: r, endTime: n, event: c }) {
654
+ const y = e.payload;
655
+ y && k("add-segment", { track: y, startTime: r, endTime: n, event: c });
656
+ }
657
+ function U(e, r, n) {
658
+ e.id === n.segmentId && k("videoSegmentMuteToggle", { segment: e, track: r, muted: n.muted });
659
+ }
660
+ return (e, r) => (h(), $e(We, {
661
+ tracks: t.value,
662
+ duration: l.value,
663
+ "current-time": o.currentTime,
664
+ zoom: o.zoom,
665
+ fps: o.protocol?.fps || 30,
666
+ "snap-step": o.snapStep,
667
+ "selected-segment-id": M.value ?? null,
668
+ "disable-interaction": o.disableInteraction,
669
+ "onUpdate:currentTime": r[0] || (r[0] = (n) => k("update:currentTime", n)),
670
+ "onUpdate:zoom": r[1] || (r[1] = (n) => k("update:zoom", n)),
671
+ onSegmentClick: I,
672
+ onSegmentDragStart: P,
673
+ onSegmentDragEnd: E,
674
+ onSegmentResizeStart: B,
675
+ onSegmentResizeEnd: C,
676
+ onBackgroundClick: r[2] || (r[2] = (n) => $(null)),
677
+ onAddSegment: z
678
+ }, Be({
679
+ segment: K(({ layout: n }) => [
680
+ (h(!0), p(ee, null, le([T(n.segment.payload)], (c) => (h(), p(ee, {
681
+ key: c?.id || n.segment.id
682
+ }, [
683
+ c ? (h(), p("div", {
684
+ key: 0,
685
+ class: "ve-editor-segment",
686
+ style: J({ "--ve-segment-accent": n.track.color || ie })
687
+ }, [
688
+ R("div", ct, [
689
+ c.segmentType === "frames" ? b(e.$slots, "segment-frames", {
690
+ key: 0,
691
+ segment: c,
692
+ layout: n
693
+ }, () => [
694
+ H(L(nt), {
695
+ segment: c,
696
+ onToggleVideoMute: (y) => U(c, n.track.payload, y)
697
+ }, null, 8, ["segment", "onToggleVideoMute"])
698
+ ], !0) : c.segmentType === "text" ? b(e.$slots, "segment-text", {
699
+ key: 1,
700
+ segment: c,
701
+ layout: n
702
+ }, () => [
703
+ H(L(Q), {
704
+ segment: c,
705
+ "track-type": n.track.type || "unknown",
706
+ "accent-color": n.track.color
707
+ }, null, 8, ["segment", "track-type", "accent-color"])
708
+ ], !0) : c.segmentType === "sticker" ? b(e.$slots, "segment-sticker", {
709
+ key: 2,
710
+ segment: c,
711
+ layout: n
712
+ }, () => [
713
+ H(L(Q), {
714
+ segment: c,
715
+ "track-type": n.track.type || "unknown",
716
+ "accent-color": n.track.color
717
+ }, null, 8, ["segment", "track-type", "accent-color"])
718
+ ], !0) : c.segmentType === "audio" ? b(e.$slots, "segment-audio", {
719
+ key: 3,
720
+ segment: c,
721
+ layout: n
722
+ }, () => [
723
+ H(L(Ue), {
724
+ segment: c
725
+ }, null, 8, ["segment"])
726
+ ], !0) : c.segmentType === "effect" ? b(e.$slots, "segment-effect", {
727
+ key: 4,
728
+ segment: c,
729
+ layout: n
730
+ }, () => [
731
+ H(L(Q), {
732
+ segment: c,
733
+ "track-type": n.track.type || "unknown",
734
+ "accent-color": n.track.color
735
+ }, null, 8, ["segment", "track-type", "accent-color"])
736
+ ], !0) : c.segmentType === "filter" ? b(e.$slots, "segment-filter", {
737
+ key: 5,
738
+ segment: c,
739
+ layout: n
740
+ }, () => [
741
+ H(L(Q), {
742
+ segment: c,
743
+ "track-type": n.track.type || "unknown",
744
+ "accent-color": n.track.color
745
+ }, null, 8, ["segment", "track-type", "accent-color"])
746
+ ], !0) : j("", !0)
747
+ ])
748
+ ], 4)) : j("", !0)
749
+ ], 64))), 128))
750
+ ]),
751
+ _: 2
752
+ }, [
753
+ e.$slots.toolbar ? {
754
+ name: "toolbar",
755
+ fn: K((n) => [
756
+ b(e.$slots, "toolbar", re(oe(n)), void 0, !0)
757
+ ]),
758
+ key: "0"
759
+ } : void 0,
760
+ e.$slots.ruler ? {
761
+ name: "ruler",
762
+ fn: K((n) => [
763
+ b(e.$slots, "ruler", re(oe(n)), void 0, !0)
764
+ ]),
765
+ key: "1"
766
+ } : void 0,
767
+ e.$slots.playhead ? {
768
+ name: "playhead",
769
+ fn: K((n) => [
770
+ b(e.$slots, "playhead", re(oe(n)), void 0, !0)
771
+ ]),
772
+ key: "2"
773
+ } : void 0
774
+ ]), 1032, ["tracks", "duration", "current-time", "zoom", "fps", "snap-step", "selected-segment-id", "disable-interaction"]));
775
+ }
776
+ }), vt = /* @__PURE__ */ Y(ut, [["__scopeId", "data-v-acab97b9"]]);
777
+ export {
778
+ Ue as A,
779
+ nt as F,
780
+ Q as S,
781
+ vt as V
782
+ };