@bylqwjc/media-editor-image 1.0.26

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.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +48 -0
  3. package/dist/chunk-5TBO732O.js +1 -0
  4. package/dist/index-CU3vkvDR.d.ts +44 -0
  5. package/dist/index.css +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +36 -0
  8. package/dist/lazy.css +1 -0
  9. package/dist/lazy.d.ts +8 -0
  10. package/dist/lazy.js +1 -0
  11. package/node_modules/@media-editor/core/LICENSE +21 -0
  12. package/node_modules/@media-editor/core/README.md +14 -0
  13. package/node_modules/@media-editor/core/dist/browser.cjs +1 -0
  14. package/node_modules/@media-editor/core/dist/browser.d.ts +117 -0
  15. package/node_modules/@media-editor/core/dist/browser.js +1 -0
  16. package/node_modules/@media-editor/core/dist/chunk-7D4QE3R2.js +1 -0
  17. package/node_modules/@media-editor/core/dist/chunk-7PSQLYXL.js +1 -0
  18. package/node_modules/@media-editor/core/dist/chunk-FAFKY4LX.js +1 -0
  19. package/node_modules/@media-editor/core/dist/chunk-VDEZTXEA.js +1 -0
  20. package/node_modules/@media-editor/core/dist/engine.cjs +1 -0
  21. package/node_modules/@media-editor/core/dist/engine.d.ts +663 -0
  22. package/node_modules/@media-editor/core/dist/engine.js +1 -0
  23. package/node_modules/@media-editor/core/dist/filerobot.cjs +1 -0
  24. package/node_modules/@media-editor/core/dist/filerobot.d.ts +88 -0
  25. package/node_modules/@media-editor/core/dist/filerobot.js +1 -0
  26. package/node_modules/@media-editor/core/dist/index.cjs +1 -0
  27. package/node_modules/@media-editor/core/dist/index.d.ts +250 -0
  28. package/node_modules/@media-editor/core/dist/index.js +1 -0
  29. package/node_modules/@media-editor/core/dist/platform-presets-Ca2LbKQ3.d.ts +80 -0
  30. package/node_modules/@media-editor/core/dist/state-D2oM5s1a.d.ts +2098 -0
  31. package/node_modules/@media-editor/core/node_modules/zod/LICENSE +21 -0
  32. package/node_modules/@media-editor/core/node_modules/zod/README.md +208 -0
  33. package/node_modules/@media-editor/core/node_modules/zod/index.cjs +1 -0
  34. package/node_modules/@media-editor/core/node_modules/zod/index.d.cts +4 -0
  35. package/node_modules/@media-editor/core/node_modules/zod/index.js +1 -0
  36. package/node_modules/@media-editor/core/node_modules/zod/package.json +76 -0
  37. package/node_modules/@media-editor/core/node_modules/zod/v3/ZodError.cjs +1 -0
  38. package/node_modules/@media-editor/core/node_modules/zod/v3/ZodError.d.cts +164 -0
  39. package/node_modules/@media-editor/core/node_modules/zod/v3/ZodError.js +1 -0
  40. package/node_modules/@media-editor/core/node_modules/zod/v3/errors.cjs +1 -0
  41. package/node_modules/@media-editor/core/node_modules/zod/v3/errors.d.cts +5 -0
  42. package/node_modules/@media-editor/core/node_modules/zod/v3/errors.js +1 -0
  43. package/node_modules/@media-editor/core/node_modules/zod/v3/external.cjs +1 -0
  44. package/node_modules/@media-editor/core/node_modules/zod/v3/external.d.cts +6 -0
  45. package/node_modules/@media-editor/core/node_modules/zod/v3/external.js +1 -0
  46. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/enumUtil.cjs +1 -0
  47. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
  48. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/enumUtil.js +1 -0
  49. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/errorUtil.cjs +1 -0
  50. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
  51. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/errorUtil.js +1 -0
  52. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/parseUtil.cjs +1 -0
  53. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
  54. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/parseUtil.js +1 -0
  55. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/partialUtil.cjs +1 -0
  56. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
  57. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/partialUtil.js +1 -0
  58. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/typeAliases.cjs +1 -0
  59. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
  60. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/typeAliases.js +1 -0
  61. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/util.cjs +1 -0
  62. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/util.d.cts +85 -0
  63. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/util.js +1 -0
  64. package/node_modules/@media-editor/core/node_modules/zod/v3/index.cjs +1 -0
  65. package/node_modules/@media-editor/core/node_modules/zod/v3/index.d.cts +4 -0
  66. package/node_modules/@media-editor/core/node_modules/zod/v3/index.js +1 -0
  67. package/node_modules/@media-editor/core/node_modules/zod/v3/locales/en.cjs +1 -0
  68. package/node_modules/@media-editor/core/node_modules/zod/v3/locales/en.d.cts +3 -0
  69. package/node_modules/@media-editor/core/node_modules/zod/v3/locales/en.js +1 -0
  70. package/node_modules/@media-editor/core/node_modules/zod/v3/standard-schema.cjs +1 -0
  71. package/node_modules/@media-editor/core/node_modules/zod/v3/standard-schema.d.cts +102 -0
  72. package/node_modules/@media-editor/core/node_modules/zod/v3/standard-schema.js +1 -0
  73. package/node_modules/@media-editor/core/node_modules/zod/v3/types.cjs +1 -0
  74. package/node_modules/@media-editor/core/node_modules/zod/v3/types.d.cts +1031 -0
  75. package/node_modules/@media-editor/core/node_modules/zod/v3/types.js +1 -0
  76. package/node_modules/@media-editor/core/package.json +42 -0
  77. package/package.json +34 -0
@@ -0,0 +1,663 @@
1
+ import * as zod from 'zod'
2
+ import { V as VideoEditStateT, O as OverlayT } from './state-D2oM5s1a.js'
3
+
4
+ /** 视频源元数据(File/objectURL 是运行时的事,不进引擎;引擎只认 srcIdx + 元数据) */
5
+ interface VideoSourceMeta {
6
+ duration: number
7
+ width: number
8
+ height: number
9
+ }
10
+ /** 音频源元数据 */
11
+ interface AudioSourceMeta {
12
+ duration: number
13
+ }
14
+ interface MutOpts {
15
+ /** true = 瞬时(拖拽中间帧,不入 undo 栈) */
16
+ transient?: boolean
17
+ }
18
+ type FilterKey =
19
+ | 'brightness'
20
+ | 'contrast'
21
+ | 'saturation'
22
+ | 'temperature'
23
+ | 'tint'
24
+ | 'vibrance'
25
+ | 'gamma'
26
+ | 'highlights'
27
+ | 'shadows'
28
+ | 'whites'
29
+ | 'blacks'
30
+ | 'lightSense'
31
+ | 'sharpen'
32
+ | 'clarity'
33
+ | 'grain'
34
+ | 'fade'
35
+ | 'vignette'
36
+ type VideoEditStateWithTransitions = VideoEditStateT
37
+ type EngineListener = (state: VideoEditStateT) => void
38
+ /** 导出计划:压缩后的状态 + 上传槽位映射(slot i 对应原 srcIdx = order[i]) */
39
+ interface ExportPlan {
40
+ state: VideoEditStateT
41
+ videoSrcOrder: number[]
42
+ audioSrcOrder: number[]
43
+ }
44
+ declare class VideoEditorEngine {
45
+ private history
46
+ private videoSources
47
+ private audioSources
48
+ private listeners
49
+ /** 瞬时拖拽序列的起始 base(拖拽前的提交态);null = 不在拖拽中 */
50
+ private transientBase
51
+ constructor(initial?: VideoEditStateT)
52
+ /** 当前编辑状态(引用稳定:仅在变更时换新对象,适配 useSyncExternalStore) */
53
+ getState(): VideoEditStateT
54
+ /** useSyncExternalStore 用别名 */
55
+ getSnapshot: () => VideoEditStateT
56
+ subscribe: (fn: EngineListener) => () => void
57
+ private emit
58
+ canUndo(): boolean
59
+ canRedo(): boolean
60
+ undo(): void
61
+ redo(): void
62
+ /**
63
+ * 全部变更的唯一入口。mut 接收「计算基准态」返回新态。
64
+ * 瞬时:基准恒为 transientBase(拖拽前态),replacePresent;
65
+ * 提交:基准为 transientBase ?? present;若刚结束一段瞬时,先把 present 还原回 base 再 push,
66
+ * 使整段拖拽只占一步 undo。
67
+ */
68
+ private applyMut
69
+ /**
70
+ * 登记一个视频源并入时间轴。首源:用其分辨率初始化 canvas 并重建 history(清空 undo);
71
+ * 后续源:追加整段 clip(pushHistory)。
72
+ */
73
+ registerVideoSource(meta: VideoSourceMeta): number
74
+ /** 登记一个音频源并入单音轨(整段、volume=1、追加到当前音频末尾,clamp 后 push) */
75
+ registerAudioSource(meta: AudioSourceMeta): number
76
+ getVideoSource(idx: number): VideoSourceMeta | undefined
77
+ getAudioSource(idx: number): AudioSourceMeta | undefined
78
+ /** 把已登记源再追加一段整段 clip(同源可多次引用) */
79
+ addClipFromSource(srcIdx: number): void
80
+ splitAtPlayhead(outputTime: number): void
81
+ removeClip(idx: number): void
82
+ duplicateClip(idx: number): void
83
+ reorderClips(from: number, to: number): void
84
+ /** 拖把手改 in/out 到源时刻 srcT;拖拽中传 {transient:true},松手再调一次提交 */
85
+ trimClip(idx: number, edge: 'in' | 'out', srcT: number, opts?: MutOpts): void
86
+ moveAudioClip(idx: number, startAt: number, opts?: MutOpts): void
87
+ trimAudioClip(
88
+ idx: number,
89
+ edge: 'in' | 'out',
90
+ t: number,
91
+ opts?: MutOpts,
92
+ ): void
93
+ setAudioVolume(idx: number, volume: number, opts?: MutOpts): void
94
+ removeAudioClip(idx: number): void
95
+ /** 改一条音频片段并 clamp(volume 改动不需 clamp 几何,clampGeom=false 跳过) */
96
+ private patchAudio
97
+ setCrop(crop: NonNullable<VideoEditStateT['crop']>, opts?: MutOpts): void
98
+ clearCrop(): void
99
+ setScale(scale: NonNullable<VideoEditStateT['scale']>): void
100
+ clearScale(): void
101
+ setRotation(deg: number, opts?: MutOpts): void
102
+ /** 90° 步进(顺时针正);结果钳到 [-180,180] */
103
+ rotateBy(step: number): void
104
+ flipX(): void
105
+ flipY(): void
106
+ setFilter(key: FilterKey, value: number, opts?: MutOpts): void
107
+ setFilters(partial: Partial<VideoEditStateT['filters']>, opts?: MutOpts): void
108
+ setFilterPreset(id: string | undefined): void
109
+ addOverlay(o: OverlayT): void
110
+ updateOverlay(idx: number, patch: Partial<OverlayT>, opts?: MutOpts): void
111
+ removeOverlay(idx: number): void
112
+ /**
113
+ * 通用补丁:把 partial 浅合并进状态(UI 一次改多字段,如旋转同时重置 crop)。
114
+ * - `{transient:true}`:拖拽中间帧,基于拖拽前 base 合并、replacePresent,不入栈(= 原 patchLive)。
115
+ * - 默认:一次性提交(= commit(partial))。
116
+ */
117
+ patch(partial: Partial<VideoEditStateT>, opts?: MutOpts): void
118
+ /**
119
+ * 定格当前态为一步 undo(= 原 commit):保留 present(含拖拽末值),可再合并 partial;
120
+ * 若处于瞬时序列,先把 past 接到拖拽前 base 上,使整段拖拽只占一步。
121
+ */
122
+ commit(partial?: Partial<VideoEditStateT>): void
123
+ setKeepAudio(keep: boolean): void
124
+ setPoster(time: number): void
125
+ totalDuration(): number
126
+ contentDuration(): number
127
+ /** 输出时刻 → 所属片段与源内时刻(播放头定位) */
128
+ locate(outputTime: number): {
129
+ idx: number
130
+ srcTime: number
131
+ } | null
132
+ usedVideoSources(): number[]
133
+ /**
134
+ * 生成导出计划:剔除未引用源、把 clips/audioClips 的 srcIdx 重映射到 [0..n),
135
+ * 返回压缩后的状态与上传槽位顺序(framework 按 order 取 File 上传)。
136
+ */
137
+ getExportPlan(): ExportPlan
138
+ /** 校验当前(导出)状态是否符合 schema —— 提交前兜底 */
139
+ validate(): zod.SafeParseReturnType<
140
+ {
141
+ clips: {
142
+ srcIdx: number
143
+ in: number
144
+ out: number
145
+ hidden?: boolean | undefined
146
+ locked?: boolean | undefined
147
+ }[]
148
+ canvas: {
149
+ w: number
150
+ h: number
151
+ }
152
+ rotation?: number | undefined
153
+ filterPreset?: string | undefined
154
+ audioClips?:
155
+ | {
156
+ startAt: number
157
+ srcIdx: number
158
+ in: number
159
+ out: number
160
+ volume: number
161
+ locked?: boolean | undefined
162
+ track?: number | undefined
163
+ speed?: number | undefined
164
+ muted?: boolean | undefined
165
+ fadeIn?: number | undefined
166
+ fadeOut?: number | undefined
167
+ }[]
168
+ | undefined
169
+ crop?:
170
+ | {
171
+ width: number
172
+ x: number
173
+ y: number
174
+ height: number
175
+ }
176
+ | undefined
177
+ scale?:
178
+ | {
179
+ width: number
180
+ height: number
181
+ fit: 'contain' | 'cover' | 'force'
182
+ backgroundColor?: string | undefined
183
+ }
184
+ | undefined
185
+ flipX?: boolean | undefined
186
+ flipY?: boolean | undefined
187
+ filters?:
188
+ | {
189
+ brightness?: number | undefined
190
+ contrast?: number | undefined
191
+ saturation?: number | undefined
192
+ temperature?: number | undefined
193
+ tint?: number | undefined
194
+ vibrance?: number | undefined
195
+ gamma?: number | undefined
196
+ highlights?: number | undefined
197
+ shadows?: number | undefined
198
+ whites?: number | undefined
199
+ blacks?: number | undefined
200
+ lightSense?: number | undefined
201
+ sharpen?: number | undefined
202
+ clarity?: number | undefined
203
+ grain?: number | undefined
204
+ fade?: number | undefined
205
+ vignette?: number | undefined
206
+ }
207
+ | undefined
208
+ overlays?:
209
+ | (
210
+ | {
211
+ type: 'pen'
212
+ points: number[]
213
+ color: string
214
+ width: number
215
+ rotation?: number | undefined
216
+ startAt?: number | undefined
217
+ endAt?: number | undefined
218
+ timelineTrack?: number | undefined
219
+ hidden?: boolean | undefined
220
+ locked?: boolean | undefined
221
+ }
222
+ | {
223
+ type: 'line'
224
+ color: string
225
+ width: number
226
+ x1: number
227
+ y1: number
228
+ x2: number
229
+ y2: number
230
+ rotation?: number | undefined
231
+ startAt?: number | undefined
232
+ endAt?: number | undefined
233
+ timelineTrack?: number | undefined
234
+ hidden?: boolean | undefined
235
+ locked?: boolean | undefined
236
+ }
237
+ | {
238
+ type: 'arrow'
239
+ color: string
240
+ width: number
241
+ x1: number
242
+ y1: number
243
+ x2: number
244
+ y2: number
245
+ rotation?: number | undefined
246
+ startAt?: number | undefined
247
+ endAt?: number | undefined
248
+ timelineTrack?: number | undefined
249
+ hidden?: boolean | undefined
250
+ locked?: boolean | undefined
251
+ }
252
+ | {
253
+ type: 'rect'
254
+ color: string
255
+ width: number
256
+ x: number
257
+ y: number
258
+ w: number
259
+ h: number
260
+ rotation?: number | undefined
261
+ startAt?: number | undefined
262
+ endAt?: number | undefined
263
+ timelineTrack?: number | undefined
264
+ hidden?: boolean | undefined
265
+ locked?: boolean | undefined
266
+ }
267
+ | {
268
+ type: 'ellipse'
269
+ color: string
270
+ width: number
271
+ x: number
272
+ y: number
273
+ w: number
274
+ h: number
275
+ rotation?: number | undefined
276
+ startAt?: number | undefined
277
+ endAt?: number | undefined
278
+ timelineTrack?: number | undefined
279
+ hidden?: boolean | undefined
280
+ locked?: boolean | undefined
281
+ }
282
+ | {
283
+ type: 'text'
284
+ color: string
285
+ x: number
286
+ y: number
287
+ text: string
288
+ fontSize: number
289
+ rotation?: number | undefined
290
+ startAt?: number | undefined
291
+ endAt?: number | undefined
292
+ timelineTrack?: number | undefined
293
+ hidden?: boolean | undefined
294
+ locked?: boolean | undefined
295
+ width?: number | undefined
296
+ fontFamily?: string | undefined
297
+ fontWeight?: string | undefined
298
+ italic?: boolean | undefined
299
+ underline?: boolean | undefined
300
+ strikethrough?: boolean | undefined
301
+ align?: 'left' | 'center' | 'right' | undefined
302
+ backgroundColor?: string | undefined
303
+ strokeColor?: string | undefined
304
+ borderWidth?: number | undefined
305
+ paddingX?: number | undefined
306
+ paddingY?: number | undefined
307
+ lineHeight?: number | undefined
308
+ opacity?: number | undefined
309
+ }
310
+ | {
311
+ type: 'sticker'
312
+ x: number
313
+ y: number
314
+ w: number
315
+ h: number
316
+ rotation?: number | undefined
317
+ startAt?: number | undefined
318
+ endAt?: number | undefined
319
+ timelineTrack?: number | undefined
320
+ hidden?: boolean | undefined
321
+ locked?: boolean | undefined
322
+ emoji?: string | undefined
323
+ src?: string | undefined
324
+ }
325
+ | {
326
+ type: 'adjust'
327
+ x: number
328
+ y: number
329
+ w: number
330
+ h: number
331
+ rotation?: number | undefined
332
+ startAt?: number | undefined
333
+ endAt?: number | undefined
334
+ timelineTrack?: number | undefined
335
+ hidden?: boolean | undefined
336
+ locked?: boolean | undefined
337
+ layerKind?: 'filter' | 'adjust' | undefined
338
+ filterPreset?: string | undefined
339
+ brightness?: number | undefined
340
+ contrast?: number | undefined
341
+ saturation?: number | undefined
342
+ temperature?: number | undefined
343
+ tint?: number | undefined
344
+ vibrance?: number | undefined
345
+ gamma?: number | undefined
346
+ highlights?: number | undefined
347
+ shadows?: number | undefined
348
+ whites?: number | undefined
349
+ blacks?: number | undefined
350
+ lightSense?: number | undefined
351
+ sharpen?: number | undefined
352
+ clarity?: number | undefined
353
+ grain?: number | undefined
354
+ fade?: number | undefined
355
+ vignette?: number | undefined
356
+ }
357
+ )[]
358
+ | undefined
359
+ transitions?:
360
+ | {
361
+ type?:
362
+ | 'fade'
363
+ | 'none'
364
+ | 'slide'
365
+ | 'wipe'
366
+ | 'flip'
367
+ | 'clockWipe'
368
+ | 'star'
369
+ | 'circle'
370
+ | 'rectangle'
371
+ | undefined
372
+ duration?: number | undefined
373
+ }[]
374
+ | undefined
375
+ keepAudio?: boolean | undefined
376
+ poster?:
377
+ | {
378
+ time: number
379
+ src?: string | undefined
380
+ useAsVideoCover?: boolean | undefined
381
+ preview?: string | undefined
382
+ }
383
+ | undefined
384
+ exportSettings?:
385
+ | {
386
+ width?: number | undefined
387
+ fileName?: string | undefined
388
+ format?: 'mp4' | 'mov' | 'mxf' | undefined
389
+ height?: number | undefined
390
+ frameRate?: number | undefined
391
+ bitrateMode?: 'custom' | 'auto' | undefined
392
+ videoBitrateKbps?: number | undefined
393
+ audioBitrateKbps?: number | undefined
394
+ audioCodec?: 'aac' | 'mp3' | undefined
395
+ }
396
+ | undefined
397
+ },
398
+ {
399
+ rotation: number
400
+ clips: {
401
+ srcIdx: number
402
+ in: number
403
+ out: number
404
+ hidden?: boolean | undefined
405
+ locked?: boolean | undefined
406
+ }[]
407
+ audioClips: {
408
+ startAt: number
409
+ srcIdx: number
410
+ in: number
411
+ out: number
412
+ track: number
413
+ speed: number
414
+ volume: number
415
+ fadeIn: number
416
+ fadeOut: number
417
+ locked?: boolean | undefined
418
+ muted?: boolean | undefined
419
+ }[]
420
+ canvas: {
421
+ w: number
422
+ h: number
423
+ }
424
+ flipX: boolean
425
+ flipY: boolean
426
+ filters: {
427
+ brightness: number
428
+ contrast: number
429
+ saturation: number
430
+ temperature: number
431
+ tint: number
432
+ vibrance: number
433
+ gamma: number
434
+ highlights: number
435
+ shadows: number
436
+ whites: number
437
+ blacks: number
438
+ lightSense: number
439
+ sharpen: number
440
+ clarity: number
441
+ grain: number
442
+ fade: number
443
+ vignette: number
444
+ }
445
+ transitions: {
446
+ type:
447
+ | 'fade'
448
+ | 'none'
449
+ | 'slide'
450
+ | 'wipe'
451
+ | 'flip'
452
+ | 'clockWipe'
453
+ | 'star'
454
+ | 'circle'
455
+ | 'rectangle'
456
+ duration: number
457
+ }[]
458
+ keepAudio: boolean
459
+ filterPreset?: string | undefined
460
+ crop?:
461
+ | {
462
+ width: number
463
+ x: number
464
+ y: number
465
+ height: number
466
+ }
467
+ | undefined
468
+ scale?:
469
+ | {
470
+ width: number
471
+ height: number
472
+ fit: 'contain' | 'cover' | 'force'
473
+ backgroundColor?: string | undefined
474
+ }
475
+ | undefined
476
+ overlays?:
477
+ | (
478
+ | {
479
+ type: 'pen'
480
+ points: number[]
481
+ color: string
482
+ width: number
483
+ rotation?: number | undefined
484
+ startAt?: number | undefined
485
+ endAt?: number | undefined
486
+ timelineTrack?: number | undefined
487
+ hidden?: boolean | undefined
488
+ locked?: boolean | undefined
489
+ }
490
+ | {
491
+ type: 'line'
492
+ color: string
493
+ width: number
494
+ x1: number
495
+ y1: number
496
+ x2: number
497
+ y2: number
498
+ rotation?: number | undefined
499
+ startAt?: number | undefined
500
+ endAt?: number | undefined
501
+ timelineTrack?: number | undefined
502
+ hidden?: boolean | undefined
503
+ locked?: boolean | undefined
504
+ }
505
+ | {
506
+ type: 'arrow'
507
+ color: string
508
+ width: number
509
+ x1: number
510
+ y1: number
511
+ x2: number
512
+ y2: number
513
+ rotation?: number | undefined
514
+ startAt?: number | undefined
515
+ endAt?: number | undefined
516
+ timelineTrack?: number | undefined
517
+ hidden?: boolean | undefined
518
+ locked?: boolean | undefined
519
+ }
520
+ | {
521
+ type: 'rect'
522
+ color: string
523
+ width: number
524
+ x: number
525
+ y: number
526
+ w: number
527
+ h: number
528
+ rotation?: number | undefined
529
+ startAt?: number | undefined
530
+ endAt?: number | undefined
531
+ timelineTrack?: number | undefined
532
+ hidden?: boolean | undefined
533
+ locked?: boolean | undefined
534
+ }
535
+ | {
536
+ type: 'ellipse'
537
+ color: string
538
+ width: number
539
+ x: number
540
+ y: number
541
+ w: number
542
+ h: number
543
+ rotation?: number | undefined
544
+ startAt?: number | undefined
545
+ endAt?: number | undefined
546
+ timelineTrack?: number | undefined
547
+ hidden?: boolean | undefined
548
+ locked?: boolean | undefined
549
+ }
550
+ | {
551
+ type: 'text'
552
+ color: string
553
+ x: number
554
+ y: number
555
+ text: string
556
+ fontSize: number
557
+ rotation?: number | undefined
558
+ startAt?: number | undefined
559
+ endAt?: number | undefined
560
+ timelineTrack?: number | undefined
561
+ hidden?: boolean | undefined
562
+ locked?: boolean | undefined
563
+ width?: number | undefined
564
+ fontFamily?: string | undefined
565
+ fontWeight?: string | undefined
566
+ italic?: boolean | undefined
567
+ underline?: boolean | undefined
568
+ strikethrough?: boolean | undefined
569
+ align?: 'left' | 'center' | 'right' | undefined
570
+ backgroundColor?: string | undefined
571
+ strokeColor?: string | undefined
572
+ borderWidth?: number | undefined
573
+ paddingX?: number | undefined
574
+ paddingY?: number | undefined
575
+ lineHeight?: number | undefined
576
+ opacity?: number | undefined
577
+ }
578
+ | {
579
+ type: 'sticker'
580
+ x: number
581
+ y: number
582
+ w: number
583
+ h: number
584
+ rotation?: number | undefined
585
+ startAt?: number | undefined
586
+ endAt?: number | undefined
587
+ timelineTrack?: number | undefined
588
+ hidden?: boolean | undefined
589
+ locked?: boolean | undefined
590
+ emoji?: string | undefined
591
+ src?: string | undefined
592
+ }
593
+ | {
594
+ type: 'adjust'
595
+ x: number
596
+ y: number
597
+ w: number
598
+ h: number
599
+ brightness: number
600
+ contrast: number
601
+ saturation: number
602
+ temperature: number
603
+ tint: number
604
+ vibrance: number
605
+ gamma: number
606
+ highlights: number
607
+ shadows: number
608
+ whites: number
609
+ blacks: number
610
+ lightSense: number
611
+ sharpen: number
612
+ clarity: number
613
+ grain: number
614
+ fade: number
615
+ vignette: number
616
+ rotation?: number | undefined
617
+ startAt?: number | undefined
618
+ endAt?: number | undefined
619
+ timelineTrack?: number | undefined
620
+ hidden?: boolean | undefined
621
+ locked?: boolean | undefined
622
+ layerKind?: 'filter' | 'adjust' | undefined
623
+ filterPreset?: string | undefined
624
+ }
625
+ )[]
626
+ | undefined
627
+ poster?:
628
+ | {
629
+ time: number
630
+ src?: string | undefined
631
+ useAsVideoCover?: boolean | undefined
632
+ preview?: string | undefined
633
+ }
634
+ | undefined
635
+ exportSettings?:
636
+ | {
637
+ format: 'mp4' | 'mov' | 'mxf'
638
+ frameRate: number
639
+ audioCodec: 'aac' | 'mp3'
640
+ width?: number | undefined
641
+ fileName?: string | undefined
642
+ height?: number | undefined
643
+ bitrateMode?: 'custom' | 'auto' | undefined
644
+ videoBitrateKbps?: number | undefined
645
+ audioBitrateKbps?: number | undefined
646
+ }
647
+ | undefined
648
+ }
649
+ >
650
+ /** 重置为给定状态(清空 history、源登记保留) */
651
+ reset(state?: VideoEditStateT): void
652
+ }
653
+
654
+ export {
655
+ type AudioSourceMeta,
656
+ type EngineListener,
657
+ type ExportPlan,
658
+ type FilterKey,
659
+ type MutOpts,
660
+ type VideoEditStateWithTransitions,
661
+ VideoEditorEngine,
662
+ type VideoSourceMeta,
663
+ }
@@ -0,0 +1 @@
1
+ import{createHistory as t,canUndo as s,canRedo as i,undo as e,redo as r,replacePresent as a,pushHistory as o,clampAudioClip as n,totalDuration as h,MIN_CLIP as p,splitAtOutput as l,removeClip as u,duplicateClip as c,reorderClips as d,trimClipEdge as y,contentDuration as m,locateOutput as M,usedVideoSrcIndices as f,remapSrcIndices as v}from"./chunk-7D4QE3R2.js";import{defaultVideoEditState as S,VideoEditState as C}from"./chunk-7PSQLYXL.js";function x(t){const s=Math.min(Math.max(Math.round(t),2),4096);return s%2==0?s:s-1}var A=t=>Math.min(Math.max(t,-180),180),B=class{constructor(s=S()){this.videoSources=[],this.audioSources=[],this.listeners=new Set,this.transientBase=null,this.getSnapshot=()=>this.history.present,this.subscribe=t=>(this.listeners.add(t),()=>this.listeners.delete(t)),this.history=t(s)}getState(){return this.history.present}emit(){const t=this.history.present;for(const s of this.listeners)s(t)}canUndo(){return s(this.history)}canRedo(){return i(this.history)}undo(){this.transientBase=null,this.history=e(this.history),this.emit()}redo(){this.transientBase=null,this.history=r(this.history),this.emit()}applyMut(t,s=!1){if(s)null===this.transientBase&&(this.transientBase=this.history.present),this.history=a(this.history,t(this.transientBase));else{const s=t(this.transientBase??this.history.present),i=this.transientBase?{...this.history,present:this.transientBase}:this.history;this.history=o(i,s),this.transientBase=null}this.emit()}registerVideoSource(s){const i=this.videoSources.length;this.videoSources.push(s);const e={srcIdx:i,in:0,out:s.duration};return 0===i||0===this.history.present.clips.length?(this.transientBase=null,this.history=t({...S(),clips:[e],canvas:{w:x(s.width),h:x(s.height)}}),this.emit()):this.applyMut(t=>({...t,clips:[...t.clips,e]})),i}registerAudioSource(t){const s=this.audioSources.length;return this.audioSources.push(t),this.applyMut(i=>{const e=i.audioClips.reduce((t,s)=>{const i=Math.max(0,(s.out-s.in)/Math.max(.01,s.speed??1));return Math.max(t,s.startAt+i)},0),r=n({srcIdx:s,track:0,startAt:e,in:0,out:t.duration,speed:1,volume:1,fadeIn:0,fadeOut:0},t.duration,Math.max(h(i.clips),e+p));return{...i,audioClips:[...i.audioClips.map(t=>({...t,track:0})),r]}}),s}getVideoSource(t){return this.videoSources[t]}getAudioSource(t){return this.audioSources[t]}addClipFromSource(t){const s=this.videoSources[t];s&&this.applyMut(i=>({...i,clips:[...i.clips,{srcIdx:t,in:0,out:s.duration}]}))}splitAtPlayhead(t){this.applyMut(s=>({...s,clips:l(s.clips,t)}))}removeClip(t){this.applyMut(s=>({...s,clips:u(s.clips,t)}))}duplicateClip(t){this.applyMut(s=>({...s,clips:c(s.clips,t)}))}reorderClips(t,s){this.applyMut(i=>({...i,clips:d(i.clips,t,s)}))}trimClip(t,s,i,e){this.applyMut(e=>{const r=e.clips[t];if(!r)return e;const a=this.videoSources[r.srcIdx]?.duration??r.out;return{...e,clips:y(e.clips,t,s,i,a)}},e?.transient)}moveAudioClip(t,s,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,startAt:s})),i?.transient)}trimAudioClip(t,s,i,e){this.applyMut(e=>this.patchAudio(e,t,t=>{if("in"===s){const s=i-t.in;return{...t,in:i,startAt:t.startAt+s}}return{...t,out:i}}),e?.transient)}setAudioVolume(t,s,i){this.applyMut(i=>this.patchAudio(i,t,t=>({...t,volume:s}),!1),i?.transient)}removeAudioClip(t){this.applyMut(s=>({...s,audioClips:s.audioClips.filter((s,i)=>i!==t)}))}patchAudio(t,s,i,e=!0){const r=t.audioClips[s];if(!r)return t;let a=i(r);if(e){const s=this.audioSources[r.srcIdx]?.duration??r.out;a=n(a,s,h(t.clips))}return{...t,audioClips:t.audioClips.map((t,i)=>i===s?a:t)}}setCrop(t,s){this.applyMut(s=>({...s,crop:t}),s?.transient)}clearCrop(){this.applyMut(t=>({...t,crop:void 0}))}setScale(t){this.applyMut(s=>({...s,scale:t}))}clearScale(){this.applyMut(t=>({...t,scale:void 0}))}setRotation(t,s){this.applyMut(s=>({...s,rotation:A(t)}),s?.transient)}rotateBy(t){this.applyMut(s=>{let i=s.rotation+t;return i>180&&(i-=360),i<-180&&(i+=360),{...s,rotation:A(i)}})}flipX(){this.applyMut(t=>({...t,flipX:!t.flipX}))}flipY(){this.applyMut(t=>({...t,flipY:!t.flipY}))}setFilter(t,s,i){this.applyMut(i=>({...i,filters:{...i.filters,[t]:s}}),i?.transient)}setFilters(t,s){this.applyMut(s=>({...s,filters:{...s.filters,...t}}),s?.transient)}setFilterPreset(t){this.applyMut(s=>({...s,filterPreset:t}))}addOverlay(t){this.applyMut(s=>({...s,overlays:[...s.overlays??[],t]}))}updateOverlay(t,s,i){this.applyMut(i=>{const e=i.overlays??[];return e[t]?{...i,overlays:e.map((i,e)=>e===t?{...i,...s}:i)}:i},i?.transient)}removeOverlay(t){this.applyMut(s=>({...s,overlays:(s.overlays??[]).filter((s,i)=>i!==t)}))}patch(t,s){s?.transient?(null===this.transientBase&&(this.transientBase=this.history.present),this.history=a(this.history,{...this.transientBase,...t}),this.emit()):this.commit(t)}commit(t){const s=t?{...this.history.present,...t}:this.history.present,i=this.transientBase;this.transientBase=null,this.history=o(i?{...this.history,present:i}:this.history,s),this.emit()}setKeepAudio(t){this.applyMut(s=>({...s,keepAudio:t}))}setPoster(t){this.applyMut(s=>({...s,poster:{time:Math.max(0,t)}}))}totalDuration(){return h(this.history.present.clips)}contentDuration(){const t=this.history.present;return m(t.clips,t.audioClips)}locate(t){return M(this.history.present.clips,t)}usedVideoSources(){return f(this.history.present.clips)}getExportPlan(){const t=this.history.present,s=f(t.clips),i=t.audioClips.filter(t=>!t.muted),e=[...new Set(i.map(t=>t.srcIdx))].sort((t,s)=>t-s),r=new Map(e.map((t,s)=>[t,s]));return{state:{...t,clips:v(t.clips,s),audioClips:i.map(t=>({...t,srcIdx:r.get(t.srcIdx)??0}))},videoSrcOrder:s,audioSrcOrder:e}}validate(){return C.safeParse(this.getExportPlan().state)}reset(s=S()){this.transientBase=null,this.history=t(s),this.emit()}};export{B as VideoEditorEngine};