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

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.
@@ -1,4 +1,4 @@
1
- import { V as a } from "./index-D_b1h_rS.js";
1
+ import { V as a } from "./index-BEEVxCQj.js";
2
2
  import "./index-C0eQjJkj.js";
3
3
  export {
4
4
  a as default
@@ -0,0 +1,716 @@
1
+ import { defineComponent as L, ref as P, onMounted as re, onBeforeUnmount as se, watch as F, nextTick as fe, createElementBlock as T, openBlock as y, createElementVNode as S, reactive as q, computed as U, renderSlot as p, normalizeStyle as N, createVNode as E, createCommentVNode as j, toDisplayString as O, Fragment as K, renderList as ae, watchEffect as ge, createBlock as he, createSlots as ve, withCtx as X, unref as D, normalizeProps as ee, guardReactiveProps as te } from "vue";
2
+ import { extractWaveform as le, generateThumbnails as pe, getMp4Meta as ke } from "@video-editor/protocol";
3
+ import { isVideoFramesSegment as V, isAudioSegment as ye } from "@video-editor/shared";
4
+ import { _ as G, V as be } from "./index-C0eQjJkj.js";
5
+ const Me = /* @__PURE__ */ L({
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(i) {
18
+ const f = i, d = P(null), g = P(null), b = P({ width: 0, height: 0 });
19
+ let c = null;
20
+ function k(a, l, m) {
21
+ return Math.min(Math.max(a, l), m);
22
+ }
23
+ function h(a) {
24
+ return k(Number.isFinite(a) ? a : 0, 0, 1);
25
+ }
26
+ function v() {
27
+ const a = d.value;
28
+ a && (b.value = {
29
+ width: Math.max(a.clientWidth, 0),
30
+ height: Math.max(a.clientHeight, 0)
31
+ });
32
+ }
33
+ function $() {
34
+ const a = g.value;
35
+ if (!a)
36
+ return;
37
+ const l = b.value.width, m = b.value.height;
38
+ if (l <= 0 || m <= 0)
39
+ return;
40
+ const _ = Math.min(window.devicePixelRatio || 1, 2), R = k(Math.round(l * _), 1, f.maxBufferWidth), w = k(Math.round(m * _), 1, f.maxBufferHeight);
41
+ a.width !== R && (a.width = R), a.height !== w && (a.height = w);
42
+ const W = a.getContext("2d");
43
+ if (!W)
44
+ return;
45
+ const x = R / l, I = w / m;
46
+ W.setTransform(x, 0, 0, I, 0, 0), W.clearRect(0, 0, l, m);
47
+ const M = f.peaks;
48
+ if (!M.length)
49
+ return;
50
+ const n = l / M.length;
51
+ if (!Number.isFinite(n) || n <= 0)
52
+ return;
53
+ const r = Math.min(f.barGap, Math.max(0, n - 0.1));
54
+ W.fillStyle = f.barColor;
55
+ for (let e = 0; e < M.length; e++) {
56
+ const s = e * n, t = s + n, o = s + r / 2, u = t - r / 2 - o;
57
+ if (u <= 0)
58
+ continue;
59
+ const z = Math.min(f.maxBarWidth, u), A = o + (u - z) / 2, C = h(M[e] ?? 0), H = Math.max(f.minBarHeight, C * m * 0.88), J = (m - H) / 2;
60
+ W.fillRect(A, J, z, H);
61
+ }
62
+ }
63
+ return re(() => {
64
+ v();
65
+ const a = d.value;
66
+ a && (c = new ResizeObserver(() => {
67
+ v();
68
+ }), c.observe(a));
69
+ }), se(() => {
70
+ c?.disconnect(), c = null;
71
+ }), F(
72
+ [
73
+ () => f.peaks,
74
+ () => f.barColor,
75
+ () => f.minBarHeight,
76
+ () => f.maxBarWidth,
77
+ () => f.barGap,
78
+ () => f.maxBufferWidth,
79
+ () => f.maxBufferHeight,
80
+ () => b.value.width,
81
+ () => b.value.height
82
+ ],
83
+ async () => {
84
+ await fe(), $();
85
+ },
86
+ { immediate: !0, flush: "post" }
87
+ ), (a, l) => (y(), T("div", {
88
+ ref_key: "containerRef",
89
+ ref: d,
90
+ class: "waveform-canvas-strip"
91
+ }, [
92
+ S("canvas", {
93
+ ref_key: "canvasRef",
94
+ ref: g,
95
+ class: "waveform-canvas-strip__canvas"
96
+ }, null, 512)
97
+ ], 512));
98
+ }
99
+ }), ce = /* @__PURE__ */ G(Me, [["__scopeId", "data-v-7cbe9830"]]), Te = {
100
+ key: 1,
101
+ class: "audio-segment__placeholder"
102
+ }, Se = {
103
+ key: 0,
104
+ class: "audio-segment__badge"
105
+ }, we = 1, Re = 1, $e = 4096, _e = /* @__PURE__ */ L({
106
+ name: "AudioSegment",
107
+ __name: "AudioSegment",
108
+ props: {
109
+ segment: {}
110
+ },
111
+ setup(i) {
112
+ const f = i, d = P(null), g = P(0);
113
+ let b = null;
114
+ re(() => {
115
+ d.value && (g.value = d.value.clientWidth, b = new ResizeObserver((a) => {
116
+ for (const l of a)
117
+ g.value = l.contentRect.width;
118
+ }), b.observe(d.value));
119
+ }), se(() => {
120
+ b?.disconnect();
121
+ });
122
+ const c = q({
123
+ data: null,
124
+ loading: !1,
125
+ error: null,
126
+ loadedUrl: null
127
+ });
128
+ let k = 0;
129
+ F(() => f.segment.url, (a, l) => {
130
+ a && a !== l && h(a);
131
+ }, { immediate: !0 });
132
+ async function h(a) {
133
+ if (!a || c.loadedUrl === a && c.data)
134
+ return;
135
+ const l = ++k;
136
+ c.loading = !0, c.error = null;
137
+ try {
138
+ const m = await le(a, { samples: 1e3 });
139
+ if (k !== l)
140
+ return;
141
+ c.data = m, c.loadedUrl = a, c.loading = !1;
142
+ } catch (m) {
143
+ if (k !== l)
144
+ return;
145
+ c.error = m instanceof Error ? m.message : String(m), c.loading = !1;
146
+ }
147
+ }
148
+ function v(a, l) {
149
+ if (l >= a.length)
150
+ return a;
151
+ const m = [], _ = a.length / l;
152
+ for (let R = 0; R < l; R++) {
153
+ const w = Math.floor(R * _), W = Math.max(w + 1, Math.ceil((R + 1) * _));
154
+ let x = 0;
155
+ for (let I = w; I < W; I++) {
156
+ const M = a[I] ?? 0;
157
+ M > x && (x = M);
158
+ }
159
+ m.push(x);
160
+ }
161
+ return m;
162
+ }
163
+ const $ = U(() => {
164
+ if (!c.data)
165
+ return { peaks: [], renderPeaks: [], coveragePercent: 100 };
166
+ const a = f.segment, l = c.data.duration * 1e3, m = c.data.peaks, _ = a.fromTime ?? 0, R = a.endTime - a.startTime, w = a.playRate ?? 1, W = R * w, x = Math.max(0, l - _), I = Math.min(W, x), M = R > 0 ? Math.min(100, I / w / R * 100) : 0, n = _ / l, r = (_ + I) / l, e = Math.floor(n * m.length), s = Math.ceil(r * m.length), t = m.slice(
167
+ Math.max(0, e),
168
+ Math.min(m.length, s)
169
+ );
170
+ if (!t.length)
171
+ return { peaks: [], renderPeaks: [], coveragePercent: M };
172
+ const o = g.value * (M / 100), B = o > 0 ? Math.min(
173
+ $e,
174
+ Math.max(1, Math.floor(o / (we + Re)))
175
+ ) : t.length;
176
+ return {
177
+ peaks: t,
178
+ renderPeaks: v(t, B),
179
+ coveragePercent: M
180
+ };
181
+ });
182
+ return (a, l) => (y(), T("div", {
183
+ ref_key: "containerRef",
184
+ ref: d,
185
+ class: "audio-segment"
186
+ }, [
187
+ c.data && $.value.renderPeaks.length ? p(a.$slots, "waveform", {
188
+ key: 0,
189
+ segment: i.segment,
190
+ waveform: c.data,
191
+ peaks: $.value.renderPeaks,
192
+ rawPeaks: $.value.peaks,
193
+ coveragePercent: $.value.coveragePercent
194
+ }, () => [
195
+ S("div", {
196
+ class: "audio-segment__waveform",
197
+ style: N({ width: `${$.value.coveragePercent}%` })
198
+ }, [
199
+ E(ce, {
200
+ class: "audio-segment__waveform-canvas",
201
+ peaks: $.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) : (y(), T("div", Te, [
209
+ c.loading ? p(a.$slots, "loading", {
210
+ key: 0,
211
+ segment: i.segment
212
+ }, () => [
213
+ l[0] || (l[0] = S("span", null, "加载波形…", -1))
214
+ ], !0) : c.error ? p(a.$slots, "error", {
215
+ key: 1,
216
+ segment: i.segment,
217
+ error: c.error
218
+ }, () => [
219
+ l[1] || (l[1] = S("span", null, "波形加载失败", -1))
220
+ ], !0) : p(a.$slots, "empty", {
221
+ key: 2,
222
+ segment: i.segment
223
+ }, () => [
224
+ l[2] || (l[2] = S("div", { class: "waveform-pattern" }, null, -1))
225
+ ], !0)
226
+ ])),
227
+ p(a.$slots, "overlay", { segment: i.segment }, () => [
228
+ i.segment.extra?.label ? (y(), T("span", Se, O(i.segment.extra?.label), 1)) : j("", !0)
229
+ ], !0)
230
+ ], 512));
231
+ }
232
+ }), Be = /* @__PURE__ */ G(_e, [["__scopeId", "data-v-47cbc534"]]), We = { class: "frames-segment" }, Ie = { class: "frames-segment__video-wrap" }, xe = { class: "frames-segment__video" }, Pe = {
233
+ key: 1,
234
+ class: "frames-segment__placeholder frames-segment__placeholder--video"
235
+ }, Ae = {
236
+ key: 0,
237
+ class: "frames-segment__waveform",
238
+ style: { width: "100%" }
239
+ }, Ee = {
240
+ key: 1,
241
+ class: "frames-segment__waveform-pattern"
242
+ }, ze = { class: "frames-segment__placeholder" }, Ce = {
243
+ key: 0,
244
+ class: "frames-segment__badge"
245
+ }, De = 1, Ve = 1, Fe = 4096, Ue = /* @__PURE__ */ L({
246
+ name: "FramesSegment",
247
+ __name: "FramesSegment",
248
+ props: {
249
+ segment: {}
250
+ },
251
+ setup(i) {
252
+ const f = i, d = P(null), g = P(null), b = P(1), c = P(0);
253
+ let k = null;
254
+ re(() => {
255
+ k = new ResizeObserver((n) => {
256
+ for (const r of n) {
257
+ if (r.target === d.value) {
258
+ const e = Math.max(1, Math.ceil(r.contentRect.width / 56));
259
+ b.value !== e && (b.value = e);
260
+ }
261
+ r.target === g.value && (c.value = r.contentRect.width);
262
+ }
263
+ }), d.value && k.observe(d.value), g.value && (c.value = g.value.clientWidth, k.observe(g.value));
264
+ }), se(() => {
265
+ k?.disconnect(), I();
266
+ }), F(g, (n, r) => {
267
+ k && r && k.unobserve(r), k && n && (c.value = n.clientWidth, k.observe(n));
268
+ });
269
+ const h = q({ items: [], loading: !1, error: null }), v = q({
270
+ data: null,
271
+ loading: !1,
272
+ error: null,
273
+ loadedUrl: null
274
+ });
275
+ let $ = 0, a = 0, l, m = null;
276
+ F(() => f.segment, (n, r) => {
277
+ if (!V(n))
278
+ return;
279
+ (!r || _(r, n)) && R(n, r);
280
+ }, { immediate: !0, deep: !0 }), F(() => f.segment, (n, r) => {
281
+ if (!V(n))
282
+ return;
283
+ const e = n, s = r && V(r) ? r : void 0;
284
+ e.url && e.url !== s?.url && W(e.url);
285
+ }, { immediate: !0, deep: !0 });
286
+ function _(n, r) {
287
+ return n.url !== r.url || n.startTime !== r.startTime || n.endTime !== r.endTime || n.fromTime !== r.fromTime;
288
+ }
289
+ function R(n, r) {
290
+ const e = !r || r.url !== n.url, s = !r || r.fromTime !== n.fromTime, t = e || s;
291
+ if (m = n, l && (window.clearTimeout(l), l = void 0), t) {
292
+ w(n);
293
+ return;
294
+ }
295
+ l = window.setTimeout(() => {
296
+ m && w(m), l = void 0;
297
+ }, 240);
298
+ }
299
+ async function w(n) {
300
+ if (!n.url)
301
+ return;
302
+ const r = ++$;
303
+ I(), h.loading = !0, h.error = null;
304
+ try {
305
+ const e = x(n), s = await pe(n.url, e);
306
+ if ($ !== r)
307
+ return;
308
+ const t = s.map((o) => ({
309
+ tsMs: Math.round(o.ts / 1e3),
310
+ url: URL.createObjectURL(o.img)
311
+ }));
312
+ h.items = t, h.loading = !1;
313
+ } catch (e) {
314
+ if ($ !== r)
315
+ return;
316
+ h.error = e instanceof Error ? e.message : String(e), h.loading = !1;
317
+ }
318
+ }
319
+ async function W(n) {
320
+ if (!n || v.loadedUrl === n && v.data)
321
+ return;
322
+ const r = ++a;
323
+ v.loading = !0, v.error = null;
324
+ try {
325
+ const e = await le(n, { samples: 1e3 });
326
+ if (a !== r)
327
+ return;
328
+ v.data = e, v.loadedUrl = n, v.loading = !1;
329
+ } catch (e) {
330
+ if (a !== r)
331
+ return;
332
+ v.data = null, v.error = e instanceof Error ? e.message : String(e), v.loading = !1;
333
+ }
334
+ }
335
+ function x(n) {
336
+ const r = Math.max(n.fromTime ?? 0, 0) * 1e3, e = Math.max(n.endTime - n.startTime, 1), s = r + e * 1e3, o = Math.max(Math.floor((s - r) / 8), 2e5);
337
+ return { start: r, end: s, step: o };
338
+ }
339
+ function I() {
340
+ h.items.forEach((n) => URL.revokeObjectURL(n.url)), h.items = [];
341
+ }
342
+ const M = U(() => {
343
+ if (!V(f.segment))
344
+ return { peaks: [], coveragePercent: 100 };
345
+ if (!v.data)
346
+ return { peaks: [], coveragePercent: 100 };
347
+ const n = f.segment, r = Math.max(n.endTime - n.startTime, 0);
348
+ if (r <= 0)
349
+ return { peaks: [], coveragePercent: 100 };
350
+ const e = Math.max(c.value, 1), s = Math.min(
351
+ Fe,
352
+ Math.max(1, Math.floor(e / (De + Ve)))
353
+ ), t = v.data.duration * 1e3, o = v.data.peaks;
354
+ if (!Number.isFinite(t) || t <= 0 || o.length === 0)
355
+ return { peaks: new Array(s).fill(0), coveragePercent: 100 };
356
+ const B = Math.max(n.fromTime ?? 0, 0), u = Math.max(n.playRate ?? 1, 1e-4), z = r * u, A = [];
357
+ for (let C = 0; C < s; C++) {
358
+ const H = B + z * C / s, J = B + z * (C + 1) / s;
359
+ if (H >= t || J <= 0) {
360
+ A.push(0);
361
+ continue;
362
+ }
363
+ const de = Math.max(H, 0), me = Math.min(J, t), oe = Math.floor(de / t * o.length), ue = Math.max(oe + 1, Math.ceil(me / t * o.length));
364
+ let Q = 0;
365
+ for (let Z = oe; Z < ue; Z++) {
366
+ const ie = o[Z] ?? 0;
367
+ ie > Q && (Q = ie);
368
+ }
369
+ A.push(Q);
370
+ }
371
+ return { peaks: A, coveragePercent: 100 };
372
+ });
373
+ return (n, r) => (y(), T("div", We, [
374
+ i.segment.type === "image" ? p(n.$slots, "image", {
375
+ key: 0,
376
+ segment: i.segment,
377
+ style: N({ backgroundImage: i.segment.url ? `url(${i.segment.url})` : "" })
378
+ }, () => [
379
+ S("div", {
380
+ ref_key: "containerRef",
381
+ ref: d,
382
+ class: "frames-segment__image"
383
+ }, [
384
+ (y(!0), T(K, null, ae(b.value, (e) => (y(), T("div", {
385
+ key: e,
386
+ class: "frames-segment__image-item",
387
+ style: N({ backgroundImage: i.segment.url ? `url(${i.segment.url})` : "" })
388
+ }, null, 4))), 128))
389
+ ], 512)
390
+ ], !0) : i.segment.type === "video" ? p(n.$slots, "video", {
391
+ key: 1,
392
+ segment: i.segment,
393
+ thumbnails: h.items,
394
+ waveformPeaks: M.value.peaks,
395
+ waveformCoveragePercent: M.value.coveragePercent
396
+ }, () => [
397
+ S("div", Ie, [
398
+ S("div", xe, [
399
+ h.items.length ? (y(!0), T(K, { key: 0 }, ae(h.items, (e) => (y(), T("div", {
400
+ key: `${i.segment.id}-${e.tsMs}`,
401
+ class: "frames-segment__thumb",
402
+ style: N({ backgroundImage: `url(${e.url})` })
403
+ }, null, 4))), 128)) : (y(), T("div", Pe, [
404
+ h.loading ? p(n.$slots, "loading", {
405
+ key: 0,
406
+ segment: i.segment
407
+ }, () => [
408
+ r[0] || (r[0] = S("span", null, "抽帧中…", -1))
409
+ ], !0) : h.error ? p(n.$slots, "error", {
410
+ key: 1,
411
+ segment: i.segment,
412
+ error: h.error
413
+ }, () => [
414
+ r[1] || (r[1] = S("span", null, "生成失败", -1))
415
+ ], !0) : p(n.$slots, "empty", {
416
+ key: 2,
417
+ segment: i.segment
418
+ }, () => [
419
+ r[2] || (r[2] = S("span", null, "未生成缩略图", -1))
420
+ ], !0)
421
+ ]))
422
+ ]),
423
+ S("div", {
424
+ ref_key: "waveformRef",
425
+ ref: g,
426
+ class: "frames-segment__waveform-strip"
427
+ }, [
428
+ M.value.peaks.length ? (y(), T("div", Ae, [
429
+ E(ce, {
430
+ class: "frames-segment__waveform-canvas",
431
+ peaks: M.value.peaks,
432
+ "bar-color": "#3f3f46",
433
+ "min-bar-height": 3,
434
+ "max-bar-width": 4,
435
+ "bar-gap": 1
436
+ }, null, 8, ["peaks"])
437
+ ])) : (y(), T("div", Ee))
438
+ ], 512)
439
+ ])
440
+ ], !0) : p(n.$slots, "fallback", {
441
+ key: 2,
442
+ segment: i.segment
443
+ }, () => [
444
+ S("div", ze, [
445
+ S("span", null, O(i.segment.type), 1)
446
+ ])
447
+ ], !0),
448
+ p(n.$slots, "overlay", { segment: i.segment }, () => [
449
+ i.segment.extra?.label ? (y(), T("span", Ce, O(i.segment.extra?.label), 1)) : j("", !0)
450
+ ], !0)
451
+ ]));
452
+ }
453
+ }), Oe = /* @__PURE__ */ G(Ue, [["__scopeId", "data-v-fed75c7c"]]), He = { class: "segment-base" }, Ne = { class: "segment-base__content" }, je = { class: "segment-base__pill segment-base__pill--primary" }, Le = { class: "segment-base__pill segment-base__pill--muted" }, Ge = {
454
+ key: 0,
455
+ class: "segment-base__badge"
456
+ }, Je = /* @__PURE__ */ L({
457
+ name: "SegmentBase",
458
+ __name: "SegmentBase",
459
+ props: {
460
+ segment: {},
461
+ trackType: {},
462
+ accentColor: { default: "#222226" }
463
+ },
464
+ setup(i) {
465
+ const f = i, d = U(() => {
466
+ const g = f.segment?.extra?.label;
467
+ return typeof g == "string" ? g : null;
468
+ });
469
+ return (g, b) => (y(), T("div", He, [
470
+ S("div", Ne, [
471
+ S("span", je, O(i.trackType), 1),
472
+ S("span", Le, O(i.segment.segmentType), 1)
473
+ ]),
474
+ d.value ? (y(), T("span", Ge, O(d.value), 1)) : j("", !0)
475
+ ]));
476
+ }
477
+ }), Y = /* @__PURE__ */ G(Je, [["__scopeId", "data-v-d386af72"]]), Xe = { class: "ve-editor-segment__preview" }, ne = "#222226", Ye = 0.4, qe = /* @__PURE__ */ L({
478
+ name: "VideoEditorTimeline",
479
+ __name: "index",
480
+ props: {
481
+ protocol: { default: null },
482
+ currentTime: {},
483
+ zoom: {},
484
+ snapStep: { default: 0 },
485
+ selectedSegmentId: { default: null },
486
+ trackTypes: { default: void 0 },
487
+ disableInteraction: { type: Boolean, default: !1 }
488
+ },
489
+ emits: ["update:currentTime", "update:zoom", "update:selectedSegmentId", "segmentClick", "segmentDragEnd", "segmentResizeEnd", "add-segment"],
490
+ setup(i, { emit: f }) {
491
+ const d = i, g = f, b = P(d.selectedSegmentId ?? null);
492
+ F(() => d.selectedSegmentId, (e) => {
493
+ b.value = e ?? null;
494
+ });
495
+ const c = {
496
+ frames: ne,
497
+ audio: "#0ea5e9",
498
+ text: "#16a34a",
499
+ sticker: "#f97316",
500
+ effect: "#a855f7",
501
+ filter: "#64748b"
502
+ }, k = U(() => {
503
+ if (!d.protocol?.tracks?.length)
504
+ return [];
505
+ const s = (d.trackTypes?.length ? d.protocol.tracks.filter((u) => d.trackTypes?.includes(u.trackType)) : d.protocol.tracks).slice(), t = s.find((u) => u.trackType === "frames" && u.isMain === !0), o = s.filter((u) => !(u.trackType === "audio" || u === t)), B = s.filter((u) => u.trackType === "audio");
506
+ return [
507
+ ...o,
508
+ ...t ? [t] : [],
509
+ ...B
510
+ ];
511
+ }), h = q(/* @__PURE__ */ new Map()), v = /* @__PURE__ */ new Map();
512
+ function $(e) {
513
+ if (!e || h.has(e) || v.has(e))
514
+ return;
515
+ const s = (async () => {
516
+ try {
517
+ const t = await ke(e);
518
+ h.set(e, t.durationMs);
519
+ } catch {
520
+ }
521
+ })().finally(() => {
522
+ v.delete(e);
523
+ });
524
+ v.set(e, s);
525
+ }
526
+ const a = U(() => k.value.map((e, s) => {
527
+ const t = c[e.trackType] || ne, o = m(t, Ye), B = e.trackType === "frames" && e.isMain === !0;
528
+ return {
529
+ id: e.trackId || `${e.trackType}-${s}`,
530
+ label: e.trackType,
531
+ type: e.trackType,
532
+ color: t,
533
+ isMain: B,
534
+ payload: e,
535
+ segments: e.children.map((u) => ({
536
+ ...V(u) ? { fromTime: u.fromTime ?? 0, sourceDurationMs: h.get(u.url) } : ye(u) ? { fromTime: u.fromTime ?? 0 } : {},
537
+ id: u.id,
538
+ start: u.startTime,
539
+ end: u.endTime,
540
+ type: u.segmentType,
541
+ color: o,
542
+ payload: u
543
+ }))
544
+ };
545
+ }));
546
+ ge(() => {
547
+ for (const e of k.value)
548
+ for (const s of e.children)
549
+ V(s) && $(s.url);
550
+ });
551
+ const l = U(() => {
552
+ if (!d.protocol?.tracks?.length)
553
+ return 0;
554
+ const e = d.protocol.tracks.flatMap((s) => s.children.map((t) => t.endTime));
555
+ return e.length ? Math.max(...e) : 0;
556
+ });
557
+ function m(e, s) {
558
+ const t = e.replace("#", "");
559
+ if (!(t.length === 3 || t.length === 6))
560
+ return e;
561
+ const o = t.length === 3 ? t.split("").map((A) => A + A).join("") : t, B = Number.parseInt(o.slice(0, 2), 16), u = Number.parseInt(o.slice(2, 4), 16), z = Number.parseInt(o.slice(4, 6), 16);
562
+ return `rgba(${B}, ${u}, ${z}, ${s})`;
563
+ }
564
+ function _(e) {
565
+ return e && typeof e == "object" && "segmentType" in e ? e : null;
566
+ }
567
+ function R(e) {
568
+ const s = e.payload;
569
+ if (s)
570
+ return s;
571
+ if (d.protocol)
572
+ return d.protocol.tracks.find((t) => t.trackId === e.id);
573
+ }
574
+ function w(e) {
575
+ b.value = e, g("update:selectedSegmentId", e);
576
+ }
577
+ function W(e) {
578
+ const s = _(e.segment.payload), t = R(e.track);
579
+ s && (w(s.id), t && g("segmentClick", { segment: s, track: t }));
580
+ }
581
+ function x(e) {
582
+ w(e.segment.id);
583
+ }
584
+ function I(e) {
585
+ g("segmentDragEnd", e);
586
+ }
587
+ function M(e) {
588
+ w(e.segment.id);
589
+ }
590
+ function n(e) {
591
+ g("segmentResizeEnd", e);
592
+ }
593
+ function r({ track: e, startTime: s, endTime: t, event: o }) {
594
+ const B = e.payload;
595
+ B && g("add-segment", { track: B, startTime: s, endTime: t, event: o });
596
+ }
597
+ return (e, s) => (y(), he(be, {
598
+ tracks: a.value,
599
+ duration: l.value,
600
+ "current-time": i.currentTime,
601
+ zoom: i.zoom,
602
+ fps: i.protocol?.fps || 30,
603
+ "snap-step": i.snapStep,
604
+ "selected-segment-id": b.value ?? null,
605
+ "disable-interaction": i.disableInteraction,
606
+ "onUpdate:currentTime": s[0] || (s[0] = (t) => g("update:currentTime", t)),
607
+ "onUpdate:zoom": s[1] || (s[1] = (t) => g("update:zoom", t)),
608
+ onSegmentClick: W,
609
+ onSegmentDragStart: x,
610
+ onSegmentDragEnd: I,
611
+ onSegmentResizeStart: M,
612
+ onSegmentResizeEnd: n,
613
+ onBackgroundClick: s[2] || (s[2] = (t) => w(null)),
614
+ onAddSegment: r
615
+ }, ve({
616
+ segment: X(({ layout: t }) => [
617
+ (y(!0), T(K, null, ae([_(t.segment.payload)], (o) => (y(), T(K, {
618
+ key: o?.id || t.segment.id
619
+ }, [
620
+ o ? (y(), T("div", {
621
+ key: 0,
622
+ class: "ve-editor-segment",
623
+ style: N({ "--ve-segment-accent": t.track.color || ne })
624
+ }, [
625
+ S("div", Xe, [
626
+ o.segmentType === "frames" ? p(e.$slots, "segment-frames", {
627
+ key: 0,
628
+ segment: o,
629
+ layout: t
630
+ }, () => [
631
+ E(D(Oe), { segment: o }, null, 8, ["segment"])
632
+ ], !0) : o.segmentType === "text" ? p(e.$slots, "segment-text", {
633
+ key: 1,
634
+ segment: o,
635
+ layout: t
636
+ }, () => [
637
+ E(D(Y), {
638
+ segment: o,
639
+ "track-type": t.track.type || "unknown",
640
+ "accent-color": t.track.color
641
+ }, null, 8, ["segment", "track-type", "accent-color"])
642
+ ], !0) : o.segmentType === "sticker" ? p(e.$slots, "segment-sticker", {
643
+ key: 2,
644
+ segment: o,
645
+ layout: t
646
+ }, () => [
647
+ E(D(Y), {
648
+ segment: o,
649
+ "track-type": t.track.type || "unknown",
650
+ "accent-color": t.track.color
651
+ }, null, 8, ["segment", "track-type", "accent-color"])
652
+ ], !0) : o.segmentType === "audio" ? p(e.$slots, "segment-audio", {
653
+ key: 3,
654
+ segment: o,
655
+ layout: t
656
+ }, () => [
657
+ E(D(Be), {
658
+ segment: o
659
+ }, null, 8, ["segment"])
660
+ ], !0) : o.segmentType === "effect" ? p(e.$slots, "segment-effect", {
661
+ key: 4,
662
+ segment: o,
663
+ layout: t
664
+ }, () => [
665
+ E(D(Y), {
666
+ segment: o,
667
+ "track-type": t.track.type || "unknown",
668
+ "accent-color": t.track.color
669
+ }, null, 8, ["segment", "track-type", "accent-color"])
670
+ ], !0) : o.segmentType === "filter" ? p(e.$slots, "segment-filter", {
671
+ key: 5,
672
+ segment: o,
673
+ layout: t
674
+ }, () => [
675
+ E(D(Y), {
676
+ segment: o,
677
+ "track-type": t.track.type || "unknown",
678
+ "accent-color": t.track.color
679
+ }, null, 8, ["segment", "track-type", "accent-color"])
680
+ ], !0) : j("", !0)
681
+ ])
682
+ ], 4)) : j("", !0)
683
+ ], 64))), 128))
684
+ ]),
685
+ _: 2
686
+ }, [
687
+ e.$slots.toolbar ? {
688
+ name: "toolbar",
689
+ fn: X((t) => [
690
+ p(e.$slots, "toolbar", ee(te(t)), void 0, !0)
691
+ ]),
692
+ key: "0"
693
+ } : void 0,
694
+ e.$slots.ruler ? {
695
+ name: "ruler",
696
+ fn: X((t) => [
697
+ p(e.$slots, "ruler", ee(te(t)), void 0, !0)
698
+ ]),
699
+ key: "1"
700
+ } : void 0,
701
+ e.$slots.playhead ? {
702
+ name: "playhead",
703
+ fn: X((t) => [
704
+ p(e.$slots, "playhead", ee(te(t)), void 0, !0)
705
+ ]),
706
+ key: "2"
707
+ } : void 0
708
+ ]), 1032, ["tracks", "duration", "current-time", "zoom", "fps", "snap-step", "selected-segment-id", "disable-interaction"]));
709
+ }
710
+ }), tt = /* @__PURE__ */ G(qe, [["__scopeId", "data-v-14600e74"]]);
711
+ export {
712
+ Be as A,
713
+ Oe as F,
714
+ Y as S,
715
+ tt as V
716
+ };
package/dist/index.d.ts CHANGED
@@ -117,6 +117,7 @@ containerRef: HTMLDivElement;
117
117
 
118
118
  declare const __VLS_component_4: DefineComponent<__VLS_Props_4, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_4> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {
119
119
  containerRef: HTMLDivElement;
120
+ waveformRef: HTMLDivElement;
120
121
  }, HTMLDivElement>;
121
122
 
122
123
  declare type __VLS_Props = {
@@ -325,6 +326,7 @@ declare function __VLS_template_3(): {
325
326
  duration: number;
326
327
  };
327
328
  peaks: number[];
329
+ rawPeaks: number[];
328
330
  coveragePercent: number;
329
331
  }): any;
330
332
  loading?(_: {
@@ -362,6 +364,8 @@ declare function __VLS_template_4(): {
362
364
  tsMs: number;
363
365
  url: string;
364
366
  }[];
367
+ waveformPeaks: any[];
368
+ waveformCoveragePercent: number;
365
369
  }): any;
366
370
  loading?(_: {
367
371
  segment: IVideoFramesSegment;
@@ -382,6 +386,7 @@ declare function __VLS_template_4(): {
382
386
  };
383
387
  refs: {
384
388
  containerRef: HTMLDivElement;
389
+ waveformRef: HTMLDivElement;
385
390
  };
386
391
  rootEl: HTMLDivElement;
387
392
  };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { V as i } from "./index-D_b1h_rS.js";
2
- import { A as s, F as d, S as V } from "./index-D_b1h_rS.js";
1
+ import { V as i } from "./index-BEEVxCQj.js";
2
+ import { A as s, F as d, S as V } from "./index-BEEVxCQj.js";
3
3
  import { V as o } from "./index-C0eQjJkj.js";
4
4
  const t = {
5
5
  install(e) {
package/dist/ui.css CHANGED
@@ -1 +1 @@
1
- :where(.ve-playhead[data-v-8e647d40]){--ve-playhead-nudge: 0px;--at-apply: absolute z-20 pointer-events-auto cursor-ew-resize h-full;transform:translate(calc(-50% - var(--ve-playhead-nudge)))}:where(.ve-playhead__icon[data-v-8e647d40]){--at-apply: text-[#222226] pointer-events-none relative z-2}:where(.ve-playhead__line[data-v-8e647d40]){--at-apply: bg-[#222226] bottom-0 w-px translate-x--50% left-50% top-2px absolute pointer-events-none}:where(.ve-ruler[data-v-30f91636]){--ve-ruler-major: 8px;--ve-ruler-minor: 4px;--at-apply: sticky top-0 left-0 right-0 bg-white z-3 border-b border-[#e5e7eb] overflow-hidden}:where(.ve-ruler .ve-ruler__ticks[data-v-30f91636]){--at-apply: relative h-full w-full box-border}:where(.ve-ruler .ve-ruler__tick[data-v-30f91636]){--at-apply: absolute top-0 h-full text-center text-[#6b7280] text-[11px]}:where(.ve-ruler .ve-ruler__line[data-v-30f91636]){--at-apply: h-[var(--ve-ruler-minor)] w-px mx-auto bg-[#cbd5e1]}:where(.ve-ruler .ve-ruler__tick--major .ve-ruler__line[data-v-30f91636]){--at-apply: relative h-[var(--ve-ruler-major)] bg-[#94a3b8]}:where(.ve-ruler .ve-ruler__label[data-v-30f91636]){--at-apply: absolute font-mono text-right whitespace-nowrap left-4px bottom-0;transform:translateY(-50%)}:where(.ve-toolbar[data-v-85ddeb0f]){--at-apply: flex items-center justify-between gap-2 px-3 py-2.5 border-b border-[#eceff3]}:where(.ve-toolbar .ve-toolbar__group[data-v-85ddeb0f]){--at-apply: inline-flex items-center gap-2}:where(.ve-toolbar .ve-zoom[data-v-85ddeb0f]){--at-apply: min-w-14 text-center text-xs text-[#222226] px-2 py-1 border border-[#e5e7eb] rounded-lg bg-white}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]){--at-apply: border border-[#d1d5db] bg-white text-[#222226] rounded-lg h-7 w-7 cursor-pointer transition-all duration-150}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]:disabled){--at-apply: cursor-not-allowed opacity-45}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]:not(:disabled):hover){--at-apply: border-[#222226] text-[#222226]}:where(.ve-toolbar .ve-toolbar__time[data-v-85ddeb0f]){--at-apply: inline-flex items-center gap-1.5 text-xs font-mono text-[#222226] ml-auto}:where(.ve-toolbar .ve-toolbar__time-divider[data-v-85ddeb0f]){--at-apply: text-[#9ca3af]}.ve-timeline__tracks[data-v-902b9363]{position:relative;z-index:1;padding-bottom:.75rem;display:flex;flex-direction:column;gap:2px;flex:1}.ve-track[data-v-902b9363]{position:relative;background-color:#f8fafc;overflow:hidden}.ve-track--main[data-v-902b9363]{background-color:#f4f4f6}.ve-track--has-selection[data-v-902b9363]{background-color:#f2f2fa!important;box-shadow:inset 0 1px #e4e4fc,inset 0 -1px #e4e4fc}.ve-track__body[data-v-902b9363]{position:relative;height:100%}.ve-segment[data-v-902b9363]{position:absolute;top:0;bottom:0;border-radius:4px;color:#0f172a;cursor:pointer;display:flex;align-items:center;overflow:hidden;transition-duration:.15s}.ve-segment__content[data-v-902b9363]{display:flex;flex-direction:column;gap:.25rem;padding:.375rem .625rem}.ve-segment__title[data-v-902b9363]{font-size:12px;font-weight:700;text-transform:capitalize}.ve-segment__time[data-v-902b9363]{font-size:11px;color:#0f172acc;font-family:monospace}.ve-segment__selection[data-v-902b9363]{position:absolute;inset:0;pointer-events:none;z-index:10}.ve-segment__handle[data-v-902b9363]{position:absolute;height:100%;width:4px;background-color:#222226;cursor:ew-resize;pointer-events:auto;border:2px solid #222226}.ve-segment__handle--left[data-v-902b9363]{left:0;top:0;border-radius:.25rem 0 0 .25rem}.ve-segment__handle--right[data-v-902b9363]{right:0;top:0;border-radius:0 .25rem .25rem 0}.ve-segment__handle-dots[data-v-902b9363]{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:.125rem;justify-content:center}.ve-segment__handle-dot[data-v-902b9363]{border-radius:9999px;background-color:#fff;width:1px;height:1px}.ve-track__add-button[data-v-902b9363]{position:absolute;top:50%;transform:translateY(-50%);margin-left:.5rem;width:2.5rem;height:2.5rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;color:#222226;background-color:#f2f2fa;cursor:pointer;transition:background-color .2s;border:1px solid #222226}.ve-track__add-button[data-v-902b9363]:hover{background-color:#e5e5e5}.ve-track__gap-add[data-v-902b9363]{position:absolute;top:0;bottom:0;height:100%;display:flex;align-items:center;justify-content:center;cursor:pointer}.ve-track__gap-add[data-v-902b9363]:hover{background-color:#efefef}.ve-track__gap-add-icon[data-v-902b9363]{display:none;color:#fff;background-color:#222226;padding:4px;border-radius:4px}.ve-track__gap-add:hover .ve-track__gap-add-icon[data-v-902b9363]{display:block}:where(.ve-timeline[data-v-4e3078d5]){--ve-primary: #222226;--at-apply: flex flex-col w-full max-w-full min-w-0 rounded-10px h-full}:where(.ve-timeline .ve-timeline__viewport[data-v-4e3078d5]){--at-apply: relative overflow-auto w-full flex-1 bg-white}:where(.ve-timeline .ve-timeline__content[data-v-4e3078d5]){--at-apply: min-h-full min-w-full}:where(.ve-timeline .ve-segment--dragging[data-v-4e3078d5]){--at-apply: absolute z-50 rounded-[4px] text-[#0f172a] cursor-pointer flex items-center overflow-hidden pointer-events-none;box-shadow:0 4px 16px #0000004d,inset 0 0 0 2px #ffffff80}:where(.ve-timeline .ve-segment--preview[data-v-4e3078d5]){--at-apply: absolute z-45 rounded-[4px] pointer-events-none;opacity:.7;box-shadow:0 2px 8px #0003,inset 0 0 0 2px #fff6}:where(.ve-timeline .ve-segment__content[data-v-4e3078d5]){--at-apply: flex flex-col gap-1 px-2.5 py-1.5}:where(.ve-timeline .ve-segment__title[data-v-4e3078d5]){--at-apply: text-[12px] font-bold capitalize}:where(.ve-timeline .ve-segment__time[data-v-4e3078d5]){--at-apply: text-[11px] text-[rgba(15,23,42,.8)] font-mono}:where(.ve-timeline .ve-segment--placeholder[data-v-4e3078d5]){--at-apply: absolute pointer-events-none rounded-[4px] z-24;background:#2222261f;border:2px solid rgba(34,34,38,.6)}:where(.ve-timeline .ve-segment--placeholder-inner[data-v-4e3078d5]){--at-apply: absolute inset-0 rounded-[2px];opacity:.2}:where(.ve-timeline .ve-snap-guide[data-v-4e3078d5]){--at-apply: absolute pointer-events-none z-20;width:1px;background:var(--ve-primary);opacity:.7}:where(.ve-timeline .ve-new-track-line[data-v-4e3078d5]){--at-apply: absolute pointer-events-none z-25;height:1px;background:var(--ve-primary);opacity:.8}:where(.audio-segment[data-v-289bc777]){--at-apply: relative flex items-center w-full h-full overflow-hidden rounded-4px;background-color:#efefef}:where(.audio-segment .audio-segment__waveform[data-v-289bc777]){--at-apply: absolute top-0 bottom-0 left-0 flex items-center justify-start gap-[1px] px-1;overflow:hidden}:where(.audio-segment .waveform-bar[data-v-289bc777]){--at-apply: flex-1;min-width:1px;max-width:4px;min-height:4px;background-color:#2b2b2b;border-radius:1px}:where(.audio-segment .audio-segment__placeholder[data-v-289bc777]){--at-apply: flex items-center justify-center w-full h-full text-xs;color:#2b2b2b;opacity:.6}:where(.audio-segment .waveform-pattern[data-v-289bc777]){width:100%;height:100%;background-image:linear-gradient(90deg,transparent 45%,#2B2B2B 45%,#2B2B2B 55%,transparent 55%);background-size:4px 100%;background-position:0 center;-webkit-mask-image:linear-gradient(to bottom,transparent 10%,black 40%,black 60%,transparent 90%);mask-image:linear-gradient(to bottom,transparent 10%,black 40%,black 60%,transparent 90%);opacity:.4}:where(.audio-segment .audio-segment__badge[data-v-289bc777]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.frames-segment[data-v-d630c479]){--at-apply: relative flex items-stretch w-full h-full overflow-hidden rounded-4px}:where(.frames-segment .frames-segment__image[data-v-d630c479]){--at-apply: flex w-full h-full overflow-hidden rounded-4px;background-color:color-mix(in srgb,var(--ve-segment-accent, #222226) 15%,transparent)}:where(.frames-segment .frames-segment__image-item[data-v-d630c479]){--at-apply: flex-shrink-0 w-14 h-full bg-cover bg-left-center bg-no-repeat}:where(.frames-segment .frames-segment__video[data-v-d630c479]){--at-apply: flex items-center w-full h-full overflow-hidden;background:#f1f5f9}:where(.frames-segment .frames-segment__thumb[data-v-d630c479]){--at-apply: flex-1 min-w-14;aspect-ratio:1 / 1;background-size:cover;background-position:center}:where(.frames-segment .frames-segment__placeholder[data-v-d630c479]){--at-apply: flex items-center justify-center w-full h-full text-[12px] rounded-4px whitespace-nowrap;color:#0f172abf;background:#0000000d}:where(.frames-segment .frames-segment__badge[data-v-d630c479]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.segment-base[data-v-d386af72]){--at-apply: relative flex items-center w-full h-full p-1.5 rounded-4px;background:#ffffff52;box-shadow:inset 0 0 0 1px #fff3}:where(.segment-base .segment-base__content[data-v-d386af72]){--at-apply: flex items-center justify-start gap-1.5 w-full}:where(.segment-base .segment-base__pill[data-v-d386af72]){--at-apply: inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-full text-[11px] font-semibold whitespace-nowrap;box-shadow:inset 0 0 0 1px #ffffff4d}:where(.segment-base .segment-base__pill--primary[data-v-d386af72]){color:var(--ve-segment-accent, #222226);background:#22222614}:where(.segment-base .segment-base__pill--muted[data-v-d386af72]){color:#0f172ab3;background:#2222260d}:where(.segment-base .segment-base__badge[data-v-d386af72]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.ve-editor-segment[data-v-1106a431]){--at-apply: relative flex flex-col gap-1.5 w-full h-full text-[#0f172a]}:where(.ve-editor-segment .ve-editor-segment__preview[data-v-1106a431]){--at-apply: flex items-stretch w-full min-h-14}
1
+ :where(.ve-playhead[data-v-8e647d40]){--ve-playhead-nudge: 0px;--at-apply: absolute z-20 pointer-events-auto cursor-ew-resize h-full;transform:translate(calc(-50% - var(--ve-playhead-nudge)))}:where(.ve-playhead__icon[data-v-8e647d40]){--at-apply: text-[#222226] pointer-events-none relative z-2}:where(.ve-playhead__line[data-v-8e647d40]){--at-apply: bg-[#222226] bottom-0 w-px translate-x--50% left-50% top-2px absolute pointer-events-none}:where(.ve-ruler[data-v-30f91636]){--ve-ruler-major: 8px;--ve-ruler-minor: 4px;--at-apply: sticky top-0 left-0 right-0 bg-white z-3 border-b border-[#e5e7eb] overflow-hidden}:where(.ve-ruler .ve-ruler__ticks[data-v-30f91636]){--at-apply: relative h-full w-full box-border}:where(.ve-ruler .ve-ruler__tick[data-v-30f91636]){--at-apply: absolute top-0 h-full text-center text-[#6b7280] text-[11px]}:where(.ve-ruler .ve-ruler__line[data-v-30f91636]){--at-apply: h-[var(--ve-ruler-minor)] w-px mx-auto bg-[#cbd5e1]}:where(.ve-ruler .ve-ruler__tick--major .ve-ruler__line[data-v-30f91636]){--at-apply: relative h-[var(--ve-ruler-major)] bg-[#94a3b8]}:where(.ve-ruler .ve-ruler__label[data-v-30f91636]){--at-apply: absolute font-mono text-right whitespace-nowrap left-4px bottom-0;transform:translateY(-50%)}:where(.ve-toolbar[data-v-85ddeb0f]){--at-apply: flex items-center justify-between gap-2 px-3 py-2.5 border-b border-[#eceff3]}:where(.ve-toolbar .ve-toolbar__group[data-v-85ddeb0f]){--at-apply: inline-flex items-center gap-2}:where(.ve-toolbar .ve-zoom[data-v-85ddeb0f]){--at-apply: min-w-14 text-center text-xs text-[#222226] px-2 py-1 border border-[#e5e7eb] rounded-lg bg-white}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]){--at-apply: border border-[#d1d5db] bg-white text-[#222226] rounded-lg h-7 w-7 cursor-pointer transition-all duration-150}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]:disabled){--at-apply: cursor-not-allowed opacity-45}:where(.ve-toolbar .ve-btn[data-v-85ddeb0f]:not(:disabled):hover){--at-apply: border-[#222226] text-[#222226]}:where(.ve-toolbar .ve-toolbar__time[data-v-85ddeb0f]){--at-apply: inline-flex items-center gap-1.5 text-xs font-mono text-[#222226] ml-auto}:where(.ve-toolbar .ve-toolbar__time-divider[data-v-85ddeb0f]){--at-apply: text-[#9ca3af]}.ve-timeline__tracks[data-v-902b9363]{position:relative;z-index:1;padding-bottom:.75rem;display:flex;flex-direction:column;gap:2px;flex:1}.ve-track[data-v-902b9363]{position:relative;background-color:#f8fafc;overflow:hidden}.ve-track--main[data-v-902b9363]{background-color:#f4f4f6}.ve-track--has-selection[data-v-902b9363]{background-color:#f2f2fa!important;box-shadow:inset 0 1px #e4e4fc,inset 0 -1px #e4e4fc}.ve-track__body[data-v-902b9363]{position:relative;height:100%}.ve-segment[data-v-902b9363]{position:absolute;top:0;bottom:0;border-radius:4px;color:#0f172a;cursor:pointer;display:flex;align-items:center;overflow:hidden;transition-duration:.15s}.ve-segment__content[data-v-902b9363]{display:flex;flex-direction:column;gap:.25rem;padding:.375rem .625rem}.ve-segment__title[data-v-902b9363]{font-size:12px;font-weight:700;text-transform:capitalize}.ve-segment__time[data-v-902b9363]{font-size:11px;color:#0f172acc;font-family:monospace}.ve-segment__selection[data-v-902b9363]{position:absolute;inset:0;pointer-events:none;z-index:10}.ve-segment__handle[data-v-902b9363]{position:absolute;height:100%;width:4px;background-color:#222226;cursor:ew-resize;pointer-events:auto;border:2px solid #222226}.ve-segment__handle--left[data-v-902b9363]{left:0;top:0;border-radius:.25rem 0 0 .25rem}.ve-segment__handle--right[data-v-902b9363]{right:0;top:0;border-radius:0 .25rem .25rem 0}.ve-segment__handle-dots[data-v-902b9363]{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:.125rem;justify-content:center}.ve-segment__handle-dot[data-v-902b9363]{border-radius:9999px;background-color:#fff;width:1px;height:1px}.ve-track__add-button[data-v-902b9363]{position:absolute;top:50%;transform:translateY(-50%);margin-left:.5rem;width:2.5rem;height:2.5rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;color:#222226;background-color:#f2f2fa;cursor:pointer;transition:background-color .2s;border:1px solid #222226}.ve-track__add-button[data-v-902b9363]:hover{background-color:#e5e5e5}.ve-track__gap-add[data-v-902b9363]{position:absolute;top:0;bottom:0;height:100%;display:flex;align-items:center;justify-content:center;cursor:pointer}.ve-track__gap-add[data-v-902b9363]:hover{background-color:#efefef}.ve-track__gap-add-icon[data-v-902b9363]{display:none;color:#fff;background-color:#222226;padding:4px;border-radius:4px}.ve-track__gap-add:hover .ve-track__gap-add-icon[data-v-902b9363]{display:block}:where(.ve-timeline[data-v-4e3078d5]){--ve-primary: #222226;--at-apply: flex flex-col w-full max-w-full min-w-0 rounded-10px h-full}:where(.ve-timeline .ve-timeline__viewport[data-v-4e3078d5]){--at-apply: relative overflow-auto w-full flex-1 bg-white}:where(.ve-timeline .ve-timeline__content[data-v-4e3078d5]){--at-apply: min-h-full min-w-full}:where(.ve-timeline .ve-segment--dragging[data-v-4e3078d5]){--at-apply: absolute z-50 rounded-[4px] text-[#0f172a] cursor-pointer flex items-center overflow-hidden pointer-events-none;box-shadow:0 4px 16px #0000004d,inset 0 0 0 2px #ffffff80}:where(.ve-timeline .ve-segment--preview[data-v-4e3078d5]){--at-apply: absolute z-45 rounded-[4px] pointer-events-none;opacity:.7;box-shadow:0 2px 8px #0003,inset 0 0 0 2px #fff6}:where(.ve-timeline .ve-segment__content[data-v-4e3078d5]){--at-apply: flex flex-col gap-1 px-2.5 py-1.5}:where(.ve-timeline .ve-segment__title[data-v-4e3078d5]){--at-apply: text-[12px] font-bold capitalize}:where(.ve-timeline .ve-segment__time[data-v-4e3078d5]){--at-apply: text-[11px] text-[rgba(15,23,42,.8)] font-mono}:where(.ve-timeline .ve-segment--placeholder[data-v-4e3078d5]){--at-apply: absolute pointer-events-none rounded-[4px] z-24;background:#2222261f;border:2px solid rgba(34,34,38,.6)}:where(.ve-timeline .ve-segment--placeholder-inner[data-v-4e3078d5]){--at-apply: absolute inset-0 rounded-[2px];opacity:.2}:where(.ve-timeline .ve-snap-guide[data-v-4e3078d5]){--at-apply: absolute pointer-events-none z-20;width:1px;background:var(--ve-primary);opacity:.7}:where(.ve-timeline .ve-new-track-line[data-v-4e3078d5]){--at-apply: absolute pointer-events-none z-25;height:1px;background:var(--ve-primary);opacity:.8}.waveform-canvas-strip[data-v-7cbe9830]{position:relative;width:100%;height:100%;overflow:hidden}.waveform-canvas-strip__canvas[data-v-7cbe9830]{position:absolute;inset:0;width:100%;height:100%;display:block}:where(.audio-segment[data-v-47cbc534]){--at-apply: relative flex items-center w-full h-full overflow-hidden rounded-4px;background-color:#efefef}:where(.audio-segment .audio-segment__waveform[data-v-47cbc534]){--at-apply: absolute top-0 bottom-0 left-0 flex items-center justify-start gap-[1px];overflow:hidden}:where(.audio-segment .audio-segment__waveform-canvas[data-v-47cbc534]){--at-apply: w-full h-full}:where(.audio-segment .audio-segment__placeholder[data-v-47cbc534]){--at-apply: flex items-center justify-center w-full h-full text-xs;color:#2b2b2b;opacity:.6}:where(.audio-segment .waveform-pattern[data-v-47cbc534]){width:100%;height:100%;background-image:linear-gradient(90deg,transparent 45%,#2B2B2B 45%,#2B2B2B 55%,transparent 55%);background-size:4px 100%;background-position:0 center;-webkit-mask-image:linear-gradient(to bottom,transparent 10%,black 40%,black 60%,transparent 90%);mask-image:linear-gradient(to bottom,transparent 10%,black 40%,black 60%,transparent 90%);opacity:.4}:where(.audio-segment .audio-segment__badge[data-v-47cbc534]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.frames-segment[data-v-fed75c7c]){--at-apply: relative flex items-stretch w-full h-full overflow-hidden rounded-4px}:where(.frames-segment .frames-segment__image[data-v-fed75c7c]){--at-apply: flex w-full h-full overflow-hidden rounded-4px;background-color:color-mix(in srgb,var(--ve-segment-accent, #222226) 15%,transparent)}:where(.frames-segment .frames-segment__image-item[data-v-fed75c7c]){--at-apply: flex-shrink-0 w-14 h-full bg-cover bg-left-center bg-no-repeat}:where(.frames-segment .frames-segment__video[data-v-fed75c7c]){--at-apply: flex items-center w-full h-full overflow-hidden;background:#f1f5f9}:where(.frames-segment .frames-segment__video-wrap[data-v-fed75c7c]){--at-apply: relative w-full h-full}:where(.frames-segment .frames-segment__thumb[data-v-fed75c7c]){--at-apply: flex-1 min-w-14;aspect-ratio:1 / 1;background-size:cover;background-position:center}:where(.frames-segment .frames-segment__waveform-strip[data-v-fed75c7c]){--at-apply: absolute left-0 right-0 bottom-0 flex items-center w-full px-1 overflow-hidden;height:16px;background:#e5e5e8;z-index:2}:where(.frames-segment .frames-segment__waveform[data-v-fed75c7c]){--at-apply: absolute top-0 bottom-0 left-0 flex items-center gap-[1px];overflow:hidden}:where(.frames-segment .frames-segment__waveform-canvas[data-v-fed75c7c]){--at-apply: w-full h-full}:where(.frames-segment .frames-segment__waveform-pattern[data-v-fed75c7c]){width:100%;height:100%;background-image:linear-gradient(90deg,transparent 45%,#52525b 45%,#52525b 55%,transparent 55%);background-size:4px 100%;background-position:0 center;-webkit-mask-image:linear-gradient(to bottom,transparent 10%,black 35%,black 65%,transparent 90%);mask-image:linear-gradient(to bottom,transparent 10%,black 35%,black 65%,transparent 90%);opacity:.4}:where(.frames-segment .frames-segment__placeholder[data-v-fed75c7c]){--at-apply: flex items-center justify-center w-full h-full text-[12px] rounded-4px whitespace-nowrap;color:#0f172abf;background:#0000000d}:where(.frames-segment .frames-segment__placeholder--video[data-v-fed75c7c]){border-radius:0}:where(.frames-segment .frames-segment__badge[data-v-fed75c7c]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.segment-base[data-v-d386af72]){--at-apply: relative flex items-center w-full h-full p-1.5 rounded-4px;background:#ffffff52;box-shadow:inset 0 0 0 1px #fff3}:where(.segment-base .segment-base__content[data-v-d386af72]){--at-apply: flex items-center justify-start gap-1.5 w-full}:where(.segment-base .segment-base__pill[data-v-d386af72]){--at-apply: inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-full text-[11px] font-semibold whitespace-nowrap;box-shadow:inset 0 0 0 1px #ffffff4d}:where(.segment-base .segment-base__pill--primary[data-v-d386af72]){color:var(--ve-segment-accent, #222226);background:#22222614}:where(.segment-base .segment-base__pill--muted[data-v-d386af72]){color:#0f172ab3;background:#2222260d}:where(.segment-base .segment-base__badge[data-v-d386af72]){--at-apply: absolute top-1.5 left-2 px-1.5 py-0.5 text-[11px] rounded-4px pointer-events-none;background:#00000040;color:#fff;transform-origin:left top;transform:scale(.9)}:where(.ve-editor-segment[data-v-14600e74]){--at-apply: relative flex flex-col gap-1.5 w-full h-full text-[#0f172a]}:where(.ve-editor-segment .ve-editor-segment__preview[data-v-14600e74]){--at-apply: flex items-stretch w-full min-h-14}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@video-editor/ui",
3
3
  "type": "module",
4
- "version": "0.0.1-beta.27",
4
+ "version": "0.0.1-beta.29",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -20,8 +20,8 @@
20
20
  "vue": "^3.5.26"
21
21
  },
22
22
  "dependencies": {
23
- "@video-editor/protocol": "0.0.1-beta.27",
24
- "@video-editor/shared": "0.0.1-beta.27"
23
+ "@video-editor/shared": "0.0.1-beta.29",
24
+ "@video-editor/protocol": "0.0.1-beta.29"
25
25
  },
26
26
  "scripts": {
27
27
  "build": "vite build",
@@ -1,508 +0,0 @@
1
- import { defineComponent as N, ref as B, onMounted as Z, onBeforeUnmount as _, reactive as K, watch as Q, computed as A, createElementBlock as f, openBlock as g, renderSlot as u, createElementVNode as y, normalizeStyle as U, Fragment as P, renderList as j, createCommentVNode as F, toDisplayString as V, watchEffect as te, createBlock as ne, createSlots as se, withCtx as L, createVNode as C, unref as E, normalizeProps as H, guardReactiveProps as Y } from "vue";
2
- import { extractWaveform as re, generateThumbnails as ae, getMp4Meta as oe } from "@video-editor/protocol";
3
- import { isVideoFramesSegment as G, isAudioSegment as le } from "@video-editor/shared";
4
- import { _ as J, V as ie } from "./index-C0eQjJkj.js";
5
- const ce = {
6
- key: 1,
7
- class: "audio-segment__placeholder"
8
- }, me = {
9
- key: 0,
10
- class: "audio-segment__badge"
11
- }, de = /* @__PURE__ */ N({
12
- name: "AudioSegment",
13
- __name: "AudioSegment",
14
- props: {
15
- segment: {}
16
- },
17
- setup(n) {
18
- const R = n, c = B(null), k = B(0);
19
- let h = null;
20
- Z(() => {
21
- c.value && (h = new ResizeObserver((i) => {
22
- for (const d of i)
23
- k.value = d.contentRect.width;
24
- }), h.observe(c.value));
25
- }), _(() => {
26
- h?.disconnect();
27
- });
28
- const o = K({
29
- data: null,
30
- loading: !1,
31
- error: null,
32
- loadedUrl: null
33
- });
34
- let $ = 0;
35
- Q(() => R.segment.url, (i, d) => {
36
- i && i !== d && b(i);
37
- }, { immediate: !0 });
38
- async function b(i) {
39
- if (!i || o.loadedUrl === i && o.data)
40
- return;
41
- const d = ++$;
42
- o.loading = !0, o.error = null;
43
- try {
44
- const p = await re(i, { samples: 1e3 });
45
- if ($ !== d)
46
- return;
47
- o.data = p, o.loadedUrl = i, o.loading = !1;
48
- } catch (p) {
49
- if ($ !== d)
50
- return;
51
- o.error = p instanceof Error ? p.message : String(p), o.loading = !1;
52
- }
53
- }
54
- const v = A(() => {
55
- if (!o.data)
56
- return { peaks: [], coveragePercent: 100 };
57
- const i = R.segment, d = o.data.duration * 1e3, p = o.data.peaks, M = i.fromTime ?? 0, w = i.endTime - i.startTime, s = i.playRate ?? 1, r = w * s, m = Math.max(0, d - M), S = Math.min(r, m), I = w > 0 ? Math.min(100, S / s / w * 100) : 0, z = M / d, W = (M + S) / d, x = Math.floor(z * p.length), e = Math.ceil(W * p.length);
58
- return { peaks: p.slice(
59
- Math.max(0, x),
60
- Math.min(p.length, e)
61
- ), coveragePercent: I };
62
- });
63
- return (i, d) => (g(), f("div", {
64
- ref_key: "containerRef",
65
- ref: c,
66
- class: "audio-segment"
67
- }, [
68
- o.data && v.value.peaks.length ? u(i.$slots, "waveform", {
69
- key: 0,
70
- segment: n.segment,
71
- waveform: o.data,
72
- peaks: v.value.peaks,
73
- coveragePercent: v.value.coveragePercent
74
- }, () => [
75
- y("div", {
76
- class: "audio-segment__waveform",
77
- style: U({ width: `${v.value.coveragePercent}%` })
78
- }, [
79
- (g(!0), f(P, null, j(v.value.peaks, (p, M) => (g(), f("div", {
80
- key: M,
81
- class: "waveform-bar",
82
- style: U({
83
- height: `${Math.max(4, p * 80)}%`
84
- })
85
- }, null, 4))), 128))
86
- ], 4)
87
- ], !0) : (g(), f("div", ce, [
88
- o.loading ? u(i.$slots, "loading", {
89
- key: 0,
90
- segment: n.segment
91
- }, () => [
92
- d[0] || (d[0] = y("span", null, "加载波形…", -1))
93
- ], !0) : o.error ? u(i.$slots, "error", {
94
- key: 1,
95
- segment: n.segment,
96
- error: o.error
97
- }, () => [
98
- d[1] || (d[1] = y("span", null, "波形加载失败", -1))
99
- ], !0) : u(i.$slots, "empty", {
100
- key: 2,
101
- segment: n.segment
102
- }, () => [
103
- d[2] || (d[2] = y("div", { class: "waveform-pattern" }, null, -1))
104
- ], !0)
105
- ])),
106
- u(i.$slots, "overlay", { segment: n.segment }, () => [
107
- n.segment.extra?.label ? (g(), f("span", me, V(n.segment.extra?.label), 1)) : F("", !0)
108
- ], !0)
109
- ], 512));
110
- }
111
- }), ue = /* @__PURE__ */ J(de, [["__scopeId", "data-v-289bc777"]]), ge = { class: "frames-segment" }, fe = { class: "frames-segment__video" }, ke = {
112
- key: 1,
113
- class: "frames-segment__placeholder"
114
- }, pe = { class: "frames-segment__placeholder" }, ye = {
115
- key: 0,
116
- class: "frames-segment__badge"
117
- }, ve = /* @__PURE__ */ N({
118
- name: "FramesSegment",
119
- __name: "FramesSegment",
120
- props: {
121
- segment: {}
122
- },
123
- setup(n) {
124
- const R = n, c = B(null), k = B(1);
125
- let h = null;
126
- Z(() => {
127
- c.value && (h = new ResizeObserver((s) => {
128
- for (const r of s) {
129
- const m = Math.max(1, Math.ceil(r.contentRect.width / 56));
130
- k.value !== m && (k.value = m);
131
- }
132
- }), h.observe(c.value));
133
- }), _(() => {
134
- h?.disconnect(), w();
135
- });
136
- const o = K({ items: [], loading: !1, error: null });
137
- let $ = 0, b, v = null;
138
- Q(() => R.segment, (s, r) => {
139
- if (!G(s))
140
- return;
141
- (!r || i(r, s)) && d(s, r);
142
- }, { immediate: !0, deep: !0 });
143
- function i(s, r) {
144
- return s.url !== r.url || s.startTime !== r.startTime || s.endTime !== r.endTime || s.fromTime !== r.fromTime;
145
- }
146
- function d(s, r) {
147
- const m = !r || r.url !== s.url, S = !r || r.fromTime !== s.fromTime, I = m || S;
148
- if (v = s, b && (window.clearTimeout(b), b = void 0), I) {
149
- p(s);
150
- return;
151
- }
152
- b = window.setTimeout(() => {
153
- v && p(v), b = void 0;
154
- }, 240);
155
- }
156
- async function p(s) {
157
- if (!s.url)
158
- return;
159
- const r = ++$;
160
- w(), o.loading = !0, o.error = null;
161
- try {
162
- const m = M(s), S = await ae(s.url, m);
163
- if ($ !== r)
164
- return;
165
- const I = S.map((z) => ({
166
- tsMs: Math.round(z.ts / 1e3),
167
- url: URL.createObjectURL(z.img)
168
- }));
169
- o.items = I, o.loading = !1;
170
- } catch (m) {
171
- if ($ !== r)
172
- return;
173
- o.error = m instanceof Error ? m.message : String(m), o.loading = !1;
174
- }
175
- }
176
- function M(s) {
177
- const r = Math.max(s.fromTime ?? 0, 0) * 1e3, m = Math.max(s.endTime - s.startTime, 1), S = r + m * 1e3, z = Math.max(Math.floor((S - r) / 8), 2e5);
178
- return { start: r, end: S, step: z };
179
- }
180
- function w() {
181
- o.items.forEach((s) => URL.revokeObjectURL(s.url)), o.items = [];
182
- }
183
- return (s, r) => (g(), f("div", ge, [
184
- n.segment.type === "image" ? u(s.$slots, "image", {
185
- key: 0,
186
- segment: n.segment,
187
- style: U({ backgroundImage: n.segment.url ? `url(${n.segment.url})` : "" })
188
- }, () => [
189
- y("div", {
190
- ref_key: "containerRef",
191
- ref: c,
192
- class: "frames-segment__image"
193
- }, [
194
- (g(!0), f(P, null, j(k.value, (m) => (g(), f("div", {
195
- key: m,
196
- class: "frames-segment__image-item",
197
- style: U({ backgroundImage: n.segment.url ? `url(${n.segment.url})` : "" })
198
- }, null, 4))), 128))
199
- ], 512)
200
- ], !0) : n.segment.type === "video" ? (g(), f(P, { key: 1 }, [
201
- o.items.length ? u(s.$slots, "video", {
202
- key: 0,
203
- segment: n.segment,
204
- thumbnails: o.items
205
- }, () => [
206
- y("div", fe, [
207
- (g(!0), f(P, null, j(o.items, (m) => (g(), f("div", {
208
- key: `${n.segment.id}-${m.tsMs}`,
209
- class: "frames-segment__thumb",
210
- style: U({ backgroundImage: `url(${m.url})` })
211
- }, null, 4))), 128))
212
- ])
213
- ], !0) : (g(), f("div", ke, [
214
- o.loading ? u(s.$slots, "loading", {
215
- key: 0,
216
- segment: n.segment
217
- }, () => [
218
- r[0] || (r[0] = y("span", null, "抽帧中…", -1))
219
- ], !0) : o.error ? u(s.$slots, "error", {
220
- key: 1,
221
- segment: n.segment,
222
- error: o.error
223
- }, () => [
224
- r[1] || (r[1] = y("span", null, "生成失败", -1))
225
- ], !0) : u(s.$slots, "empty", {
226
- key: 2,
227
- segment: n.segment
228
- }, () => [
229
- r[2] || (r[2] = y("span", null, "未生成缩略图", -1))
230
- ], !0)
231
- ]))
232
- ], 64)) : u(s.$slots, "fallback", {
233
- key: 2,
234
- segment: n.segment
235
- }, () => [
236
- y("div", pe, [
237
- y("span", null, V(n.segment.type), 1)
238
- ])
239
- ], !0),
240
- u(s.$slots, "overlay", { segment: n.segment }, () => [
241
- n.segment.extra?.label ? (g(), f("span", ye, V(n.segment.extra?.label), 1)) : F("", !0)
242
- ], !0)
243
- ]));
244
- }
245
- }), he = /* @__PURE__ */ J(ve, [["__scopeId", "data-v-d630c479"]]), Te = { class: "segment-base" }, be = { class: "segment-base__content" }, Se = { class: "segment-base__pill segment-base__pill--primary" }, $e = { class: "segment-base__pill segment-base__pill--muted" }, Me = {
246
- key: 0,
247
- class: "segment-base__badge"
248
- }, we = /* @__PURE__ */ N({
249
- name: "SegmentBase",
250
- __name: "SegmentBase",
251
- props: {
252
- segment: {},
253
- trackType: {},
254
- accentColor: { default: "#222226" }
255
- },
256
- setup(n) {
257
- const R = n, c = A(() => {
258
- const k = R.segment?.extra?.label;
259
- return typeof k == "string" ? k : null;
260
- });
261
- return (k, h) => (g(), f("div", Te, [
262
- y("div", be, [
263
- y("span", Se, V(n.trackType), 1),
264
- y("span", $e, V(n.segment.segmentType), 1)
265
- ]),
266
- c.value ? (g(), f("span", Me, V(c.value), 1)) : F("", !0)
267
- ]));
268
- }
269
- }), O = /* @__PURE__ */ J(we, [["__scopeId", "data-v-d386af72"]]), Re = { class: "ve-editor-segment__preview" }, q = "#222226", Ie = 0.4, ze = /* @__PURE__ */ N({
270
- name: "VideoEditorTimeline",
271
- __name: "index",
272
- props: {
273
- protocol: { default: null },
274
- currentTime: {},
275
- zoom: {},
276
- snapStep: { default: 0 },
277
- selectedSegmentId: { default: null },
278
- trackTypes: { default: void 0 },
279
- disableInteraction: { type: Boolean, default: !1 }
280
- },
281
- emits: ["update:currentTime", "update:zoom", "update:selectedSegmentId", "segmentClick", "segmentDragEnd", "segmentResizeEnd", "add-segment"],
282
- setup(n, { emit: R }) {
283
- const c = n, k = R, h = B(c.selectedSegmentId ?? null);
284
- Q(() => c.selectedSegmentId, (e) => {
285
- h.value = e ?? null;
286
- });
287
- const o = {
288
- frames: q,
289
- audio: "#0ea5e9",
290
- text: "#16a34a",
291
- sticker: "#f97316",
292
- effect: "#a855f7",
293
- filter: "#64748b"
294
- }, $ = A(() => {
295
- if (!c.protocol?.tracks?.length)
296
- return [];
297
- const l = (c.trackTypes?.length ? c.protocol.tracks.filter((a) => c.trackTypes?.includes(a.trackType)) : c.protocol.tracks).slice(), t = l.findIndex((a) => a.trackType === "frames" && a.isMain === !0);
298
- if (t !== -1) {
299
- const [a] = l.splice(t, 1);
300
- l.push(a);
301
- }
302
- return l;
303
- }), b = K(/* @__PURE__ */ new Map()), v = /* @__PURE__ */ new Map();
304
- function i(e) {
305
- if (!e || b.has(e) || v.has(e))
306
- return;
307
- const l = (async () => {
308
- try {
309
- const t = await oe(e);
310
- b.set(e, t.durationMs);
311
- } catch {
312
- }
313
- })().finally(() => {
314
- v.delete(e);
315
- });
316
- v.set(e, l);
317
- }
318
- const d = A(() => $.value.map((e, l) => {
319
- const t = o[e.trackType] || q, a = M(t, Ie), D = e.trackType === "frames" && e.isMain === !0;
320
- return {
321
- id: e.trackId || `${e.trackType}-${l}`,
322
- label: e.trackType,
323
- type: e.trackType,
324
- color: t,
325
- isMain: D,
326
- payload: e,
327
- segments: e.children.map((T) => ({
328
- ...G(T) ? { fromTime: T.fromTime ?? 0, sourceDurationMs: b.get(T.url) } : le(T) ? { fromTime: T.fromTime ?? 0 } : {},
329
- id: T.id,
330
- start: T.startTime,
331
- end: T.endTime,
332
- type: T.segmentType,
333
- color: a,
334
- payload: T
335
- }))
336
- };
337
- }));
338
- te(() => {
339
- for (const e of $.value)
340
- for (const l of e.children)
341
- G(l) && i(l.url);
342
- });
343
- const p = A(() => {
344
- if (!c.protocol?.tracks?.length)
345
- return 0;
346
- const e = c.protocol.tracks.flatMap((l) => l.children.map((t) => t.endTime));
347
- return e.length ? Math.max(...e) : 0;
348
- });
349
- function M(e, l) {
350
- const t = e.replace("#", "");
351
- if (!(t.length === 3 || t.length === 6))
352
- return e;
353
- const a = t.length === 3 ? t.split("").map((X) => X + X).join("") : t, D = Number.parseInt(a.slice(0, 2), 16), T = Number.parseInt(a.slice(2, 4), 16), ee = Number.parseInt(a.slice(4, 6), 16);
354
- return `rgba(${D}, ${T}, ${ee}, ${l})`;
355
- }
356
- function w(e) {
357
- return e && typeof e == "object" && "segmentType" in e ? e : null;
358
- }
359
- function s(e) {
360
- const l = e.payload;
361
- if (l)
362
- return l;
363
- if (c.protocol)
364
- return c.protocol.tracks.find((t) => t.trackId === e.id);
365
- }
366
- function r(e) {
367
- h.value = e, k("update:selectedSegmentId", e);
368
- }
369
- function m(e) {
370
- const l = w(e.segment.payload), t = s(e.track);
371
- l && (r(l.id), t && k("segmentClick", { segment: l, track: t }));
372
- }
373
- function S(e) {
374
- r(e.segment.id);
375
- }
376
- function I(e) {
377
- k("segmentDragEnd", e);
378
- }
379
- function z(e) {
380
- r(e.segment.id);
381
- }
382
- function W(e) {
383
- k("segmentResizeEnd", e);
384
- }
385
- function x({ track: e, startTime: l, endTime: t, event: a }) {
386
- const D = e.payload;
387
- D && k("add-segment", { track: D, startTime: l, endTime: t, event: a });
388
- }
389
- return (e, l) => (g(), ne(ie, {
390
- tracks: d.value,
391
- duration: p.value,
392
- "current-time": n.currentTime,
393
- zoom: n.zoom,
394
- fps: n.protocol?.fps || 30,
395
- "snap-step": n.snapStep,
396
- "selected-segment-id": h.value ?? null,
397
- "disable-interaction": n.disableInteraction,
398
- "onUpdate:currentTime": l[0] || (l[0] = (t) => k("update:currentTime", t)),
399
- "onUpdate:zoom": l[1] || (l[1] = (t) => k("update:zoom", t)),
400
- onSegmentClick: m,
401
- onSegmentDragStart: S,
402
- onSegmentDragEnd: I,
403
- onSegmentResizeStart: z,
404
- onSegmentResizeEnd: W,
405
- onBackgroundClick: l[2] || (l[2] = (t) => r(null)),
406
- onAddSegment: x
407
- }, se({
408
- segment: L(({ layout: t }) => [
409
- (g(!0), f(P, null, j([w(t.segment.payload)], (a) => (g(), f(P, {
410
- key: a?.id || t.segment.id
411
- }, [
412
- a ? (g(), f("div", {
413
- key: 0,
414
- class: "ve-editor-segment",
415
- style: U({ "--ve-segment-accent": t.track.color || q })
416
- }, [
417
- y("div", Re, [
418
- a.segmentType === "frames" ? u(e.$slots, "segment-frames", {
419
- key: 0,
420
- segment: a,
421
- layout: t
422
- }, () => [
423
- C(E(he), { segment: a }, null, 8, ["segment"])
424
- ], !0) : a.segmentType === "text" ? u(e.$slots, "segment-text", {
425
- key: 1,
426
- segment: a,
427
- layout: t
428
- }, () => [
429
- C(E(O), {
430
- segment: a,
431
- "track-type": t.track.type || "unknown",
432
- "accent-color": t.track.color
433
- }, null, 8, ["segment", "track-type", "accent-color"])
434
- ], !0) : a.segmentType === "sticker" ? u(e.$slots, "segment-sticker", {
435
- key: 2,
436
- segment: a,
437
- layout: t
438
- }, () => [
439
- C(E(O), {
440
- segment: a,
441
- "track-type": t.track.type || "unknown",
442
- "accent-color": t.track.color
443
- }, null, 8, ["segment", "track-type", "accent-color"])
444
- ], !0) : a.segmentType === "audio" ? u(e.$slots, "segment-audio", {
445
- key: 3,
446
- segment: a,
447
- layout: t
448
- }, () => [
449
- C(E(ue), {
450
- segment: a
451
- }, null, 8, ["segment"])
452
- ], !0) : a.segmentType === "effect" ? u(e.$slots, "segment-effect", {
453
- key: 4,
454
- segment: a,
455
- layout: t
456
- }, () => [
457
- C(E(O), {
458
- segment: a,
459
- "track-type": t.track.type || "unknown",
460
- "accent-color": t.track.color
461
- }, null, 8, ["segment", "track-type", "accent-color"])
462
- ], !0) : a.segmentType === "filter" ? u(e.$slots, "segment-filter", {
463
- key: 5,
464
- segment: a,
465
- layout: t
466
- }, () => [
467
- C(E(O), {
468
- segment: a,
469
- "track-type": t.track.type || "unknown",
470
- "accent-color": t.track.color
471
- }, null, 8, ["segment", "track-type", "accent-color"])
472
- ], !0) : F("", !0)
473
- ])
474
- ], 4)) : F("", !0)
475
- ], 64))), 128))
476
- ]),
477
- _: 2
478
- }, [
479
- e.$slots.toolbar ? {
480
- name: "toolbar",
481
- fn: L((t) => [
482
- u(e.$slots, "toolbar", H(Y(t)), void 0, !0)
483
- ]),
484
- key: "0"
485
- } : void 0,
486
- e.$slots.ruler ? {
487
- name: "ruler",
488
- fn: L((t) => [
489
- u(e.$slots, "ruler", H(Y(t)), void 0, !0)
490
- ]),
491
- key: "1"
492
- } : void 0,
493
- e.$slots.playhead ? {
494
- name: "playhead",
495
- fn: L((t) => [
496
- u(e.$slots, "playhead", H(Y(t)), void 0, !0)
497
- ]),
498
- key: "2"
499
- } : void 0
500
- ]), 1032, ["tracks", "duration", "current-time", "zoom", "fps", "snap-step", "selected-segment-id", "disable-interaction"]));
501
- }
502
- }), Pe = /* @__PURE__ */ J(ze, [["__scopeId", "data-v-1106a431"]]);
503
- export {
504
- ue as A,
505
- he as F,
506
- O as S,
507
- Pe as V
508
- };