@omnimedia/omnitool 1.1.0-103 → 1.1.0-105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/package.json +2 -1
- package/s/timeline/parts/captions.ts +1 -0
- package/s/timeline/parts/item.ts +13 -9
- package/s/timeline/parts/transitions.ts +2 -2
- package/s/timeline/sugar/helpers.ts +26 -9
- package/s/timeline/sugar/o.ts +26 -5
- package/s/timeline/utils/checksum.ts +1 -1
- package/x/demo/demo.bundle.min.js +104 -104
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/index.html +2 -2
- package/x/tests.bundle.min.js +108 -108
- package/x/tests.bundle.min.js.map +4 -4
- package/x/tests.html +1 -1
- package/x/timeline/parts/captions.d.ts +1 -0
- package/x/timeline/parts/captions.js.map +1 -1
- package/x/timeline/parts/item.d.ts +12 -9
- package/x/timeline/parts/transitions.d.ts +2 -2
- package/x/timeline/sugar/helpers.d.ts +10 -5
- package/x/timeline/sugar/helpers.js +19 -7
- package/x/timeline/sugar/helpers.js.map +1 -1
- package/x/timeline/sugar/o.d.ts +10 -4
- package/x/timeline/sugar/o.js +19 -4
- package/x/timeline/sugar/o.js.map +1 -1
- package/x/timeline/utils/checksum.js +1 -1
- package/x/timeline/utils/checksum.js.map +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,17 @@ const timeline = omni.timeline(o => {
|
|
|
56
56
|
})
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
You can label your items:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const visual = o.sequence(
|
|
63
|
+
"Main sequence",
|
|
64
|
+
o.video(clip, {label: "Intro"}),
|
|
65
|
+
o.transition.fade(500, {label: "Fade"}),
|
|
66
|
+
o.text("Hello world", {label: "Title"})
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
59
70
|
Declarative helper style (no explicit `o` in timeline declarations):
|
|
60
71
|
|
|
61
72
|
```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnimedia/omnitool",
|
|
3
|
-
"version": "1.1.0-
|
|
3
|
+
"version": "1.1.0-105",
|
|
4
4
|
"description": "open source video processing tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Przemysław Gałęzki",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"typescript": "^5.9.3"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@awasm/noble": "^0.1.4",
|
|
35
36
|
"@e280/comrade": "^0.1.0",
|
|
36
37
|
"@e280/renraku": "^0.5.3",
|
|
37
38
|
"@e280/sly": "^0.2.5",
|
package/s/timeline/parts/item.ts
CHANGED
|
@@ -26,6 +26,10 @@ export enum Kind {
|
|
|
26
26
|
Image
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export type ItemMeta = {
|
|
30
|
+
label?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
29
33
|
export namespace Item {
|
|
30
34
|
export type TextStyle = {
|
|
31
35
|
id: Id
|
|
@@ -60,7 +64,7 @@ export namespace Item {
|
|
|
60
64
|
id: Id
|
|
61
65
|
kind: Kind.Gap
|
|
62
66
|
duration: number
|
|
63
|
-
}
|
|
67
|
+
} & ItemMeta
|
|
64
68
|
|
|
65
69
|
export type Sequence = {
|
|
66
70
|
id: Id
|
|
@@ -68,7 +72,7 @@ export namespace Item {
|
|
|
68
72
|
childrenIds: Id[]
|
|
69
73
|
spatialId?: Id
|
|
70
74
|
filterIds?: Id[]
|
|
71
|
-
}
|
|
75
|
+
} & ItemMeta
|
|
72
76
|
|
|
73
77
|
export type Stack = {
|
|
74
78
|
id: Id
|
|
@@ -76,7 +80,7 @@ export namespace Item {
|
|
|
76
80
|
childrenIds: Id[]
|
|
77
81
|
spatialId?: Id
|
|
78
82
|
filterIds?: Id[]
|
|
79
|
-
}
|
|
83
|
+
} & ItemMeta
|
|
80
84
|
|
|
81
85
|
export type Video = {
|
|
82
86
|
id: Id
|
|
@@ -87,7 +91,7 @@ export namespace Item {
|
|
|
87
91
|
spatialId?: Id
|
|
88
92
|
animationIds?: Id[]
|
|
89
93
|
filterIds?: Id[]
|
|
90
|
-
}
|
|
94
|
+
} & ItemMeta
|
|
91
95
|
|
|
92
96
|
export type Image = {
|
|
93
97
|
id: Id
|
|
@@ -97,7 +101,7 @@ export namespace Item {
|
|
|
97
101
|
spatialId?: Id
|
|
98
102
|
animationIds?: Id[]
|
|
99
103
|
filterIds?: Id[]
|
|
100
|
-
}
|
|
104
|
+
} & ItemMeta
|
|
101
105
|
|
|
102
106
|
export type Audio = {
|
|
103
107
|
id: Id
|
|
@@ -106,7 +110,7 @@ export namespace Item {
|
|
|
106
110
|
start: number
|
|
107
111
|
duration: number
|
|
108
112
|
gain?: number
|
|
109
|
-
}
|
|
113
|
+
} & ItemMeta
|
|
110
114
|
|
|
111
115
|
export type Text = {
|
|
112
116
|
id: Id
|
|
@@ -117,7 +121,7 @@ export namespace Item {
|
|
|
117
121
|
animationIds?: Id[]
|
|
118
122
|
styleId?: Id
|
|
119
123
|
filterIds?: Id[]
|
|
120
|
-
}
|
|
124
|
+
} & ItemMeta
|
|
121
125
|
|
|
122
126
|
|
|
123
127
|
export type Caption = {
|
|
@@ -134,14 +138,14 @@ export namespace Item {
|
|
|
134
138
|
animationIds?: Id[]
|
|
135
139
|
styleId?: Id
|
|
136
140
|
filterIds?: Id[]
|
|
137
|
-
}
|
|
141
|
+
} & ItemMeta
|
|
138
142
|
|
|
139
143
|
export type Transition = {
|
|
140
144
|
id: Id
|
|
141
145
|
kind: Kind.Transition
|
|
142
146
|
name: TransitionName
|
|
143
147
|
duration: number
|
|
144
|
-
}
|
|
148
|
+
} & ItemMeta
|
|
145
149
|
|
|
146
150
|
export type Any = (
|
|
147
151
|
| Sequence
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {Item} from "./item.js"
|
|
1
|
+
import type {Item, ItemMeta} from "./item.js"
|
|
2
2
|
|
|
3
3
|
export const transitionNames = [
|
|
4
4
|
"Bounce",
|
|
@@ -78,7 +78,7 @@ export type Transition = {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
export interface TransitionAction {
|
|
81
|
-
(duration: number): Item.Transition
|
|
81
|
+
(duration: number, options?: ItemMeta): Item.Transition
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
export type TransitionActions = {
|
|
@@ -10,7 +10,7 @@ import {filters, FilterParams, FilterType} from "../parts/filters.js"
|
|
|
10
10
|
import {CaptionOptions, CaptionSourceItem} from "../parts/captions.js"
|
|
11
11
|
import {Transcription} from "../../features/speech/transcribe/types.js"
|
|
12
12
|
import {AnimationPreset, PresetOptions} from "../parts/animations/types.js"
|
|
13
|
-
import {Crop, FilterableItem, Item, VisualAnimatableItem} from "../parts/item.js"
|
|
13
|
+
import {Crop, FilterableItem, Item, ItemMeta, VisualAnimatableItem} from "../parts/item.js"
|
|
14
14
|
import {animationPresets, visualAnimations} from "../parts/animations/registry.js"
|
|
15
15
|
import {Anim, AnimateAction, Interpolation, Keyframes, TrackTransform, Transform, Vec2, VisualAnimationInput, VisualAnimations} from "../types.js"
|
|
16
16
|
|
|
@@ -22,8 +22,9 @@ type BuildPresetAnimateActions = {
|
|
|
22
22
|
[TKey in AnimationPreset]: BuildPresetAnimateAction
|
|
23
23
|
}
|
|
24
24
|
type BuildTransitionActions = {
|
|
25
|
-
[TKey in TransitionName]: (duration: number) => Build<Item.Transition>
|
|
25
|
+
[TKey in TransitionName]: (duration: number, options?: ItemMeta) => Build<Item.Transition>
|
|
26
26
|
}
|
|
27
|
+
type ContainerInput = [label: string, ...items: Build[]] | Build[]
|
|
27
28
|
|
|
28
29
|
function createTimeline(): TimelineFile {
|
|
29
30
|
return {
|
|
@@ -42,12 +43,24 @@ export function timeline(root: Build): TimelineFile {
|
|
|
42
43
|
return o.timeline
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export function sequence(...
|
|
46
|
-
|
|
46
|
+
export function sequence(...input: ContainerInput): Build<Item.Sequence> {
|
|
47
|
+
const [first, ...rest] = input
|
|
48
|
+
const label = typeof first === "string" ? first : undefined
|
|
49
|
+
const items = (label ? rest : input) as Build[]
|
|
50
|
+
return o => {
|
|
51
|
+
const built = items.map(item => item(o))
|
|
52
|
+
return label ? o.sequence(label, ...built) : o.sequence(...built)
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
|
|
49
|
-
export function stack(...
|
|
50
|
-
|
|
56
|
+
export function stack(...input: ContainerInput): Build<Item.Stack> {
|
|
57
|
+
const [first, ...rest] = input
|
|
58
|
+
const label = typeof first === "string" ? first : undefined
|
|
59
|
+
const items = (label ? rest : input) as Build[]
|
|
60
|
+
return o => {
|
|
61
|
+
const built = items.map(item => item(o))
|
|
62
|
+
return label ? o.stack(label, ...built) : o.stack(...built)
|
|
63
|
+
}
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
export function video(
|
|
@@ -55,6 +68,7 @@ export function video(
|
|
|
55
68
|
options?: {
|
|
56
69
|
start?: number,
|
|
57
70
|
duration?: number
|
|
71
|
+
label?: string
|
|
58
72
|
}
|
|
59
73
|
): Build<Item.Video> {
|
|
60
74
|
return o => o.video(media, options)
|
|
@@ -64,6 +78,7 @@ export function image(
|
|
|
64
78
|
media: Media,
|
|
65
79
|
options?: {
|
|
66
80
|
duration?: number
|
|
81
|
+
label?: string
|
|
67
82
|
}
|
|
68
83
|
): Build<Item.Image> {
|
|
69
84
|
return o => o.image(media, options)
|
|
@@ -75,6 +90,7 @@ export function audio(
|
|
|
75
90
|
start?: number,
|
|
76
91
|
duration?: number,
|
|
77
92
|
gain?: number
|
|
93
|
+
label?: string
|
|
78
94
|
}
|
|
79
95
|
): Build<Item.Audio> {
|
|
80
96
|
return o => o.audio(media, options)
|
|
@@ -85,6 +101,7 @@ export function text(
|
|
|
85
101
|
options?: {
|
|
86
102
|
duration?: number,
|
|
87
103
|
styles?: TextStyleOptions
|
|
104
|
+
label?: string
|
|
88
105
|
}
|
|
89
106
|
): Build<Item.Text> {
|
|
90
107
|
return o => o.text(content, options)
|
|
@@ -98,8 +115,8 @@ export function captions(
|
|
|
98
115
|
return o => o.captions(item(o), transcript, options)
|
|
99
116
|
}
|
|
100
117
|
|
|
101
|
-
export function gap(duration: number): Build<Item.Gap> {
|
|
102
|
-
return o => o.gap(duration)
|
|
118
|
+
export function gap(duration: number, options?: ItemMeta): Build<Item.Gap> {
|
|
119
|
+
return o => o.gap(duration, options)
|
|
103
120
|
}
|
|
104
121
|
|
|
105
122
|
export function spatial(transform?: Transform, crop?: Crop): Build<Item.Spatial> {
|
|
@@ -232,7 +249,7 @@ export function textStyle(style: TextStyleOptions): Build<Item.TextStyle> {
|
|
|
232
249
|
|
|
233
250
|
function makeTransitionActions(): BuildTransitionActions {
|
|
234
251
|
const entries = Object.keys(transitions)
|
|
235
|
-
.map(key => [key, (duration: number) => (o: O) => o.transition[key as TransitionName](duration)])
|
|
252
|
+
.map(key => [key, (duration: number, options?: ItemMeta) => (o: O) => o.transition[key as TransitionName](duration, options)])
|
|
236
253
|
return Object.fromEntries(entries) as BuildTransitionActions
|
|
237
254
|
}
|
|
238
255
|
|
package/s/timeline/sugar/o.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {Id, TimelineFile} from "../parts/basics.js"
|
|
|
6
6
|
import {FilterAction, FilterActions} from "../parts/filters.js"
|
|
7
7
|
import {filters, FilterParams, FilterType} from "../parts/filters.js"
|
|
8
8
|
import {Transcription} from "../../features/speech/transcribe/types.js"
|
|
9
|
-
import {Crop, FilterableItem, Item, Kind, VisualAnimatableItem} from "../parts/item.js"
|
|
9
|
+
import {Crop, FilterableItem, Item, ItemMeta, Kind, VisualAnimatableItem} from "../parts/item.js"
|
|
10
10
|
import {animationPresets, makeAnimationPresets, visualAnimations} from "../parts/animations/registry.js"
|
|
11
11
|
import {TransitionAction, TransitionActions, transitions, TransitionName} from "../parts/transitions.js"
|
|
12
12
|
import {AnimationPreset, PresetAnimateAction, PresetAnimateActions, PresetAnimation, PresetOptions} from "../parts/animations/types.js"
|
|
@@ -17,6 +17,8 @@ type VisualAnimateActions = {
|
|
|
17
17
|
[TKey in keyof VisualAnimations]-?: AnimateAction<TKey>
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
type ContainerInput = [label: string, ...items: Item.Any[]] | Item.Any[]
|
|
21
|
+
|
|
20
22
|
export class O {
|
|
21
23
|
constructor(public state: {timeline: TimelineFile}) {}
|
|
22
24
|
|
|
@@ -229,20 +231,28 @@ export class O {
|
|
|
229
231
|
presets: this.#makePresetAnimateActions(),
|
|
230
232
|
}
|
|
231
233
|
|
|
232
|
-
sequence = (...
|
|
234
|
+
sequence = (...input: ContainerInput): Item.Sequence => {
|
|
235
|
+
const [first, ...rest] = input
|
|
236
|
+
const label = typeof first === "string" ? first : undefined
|
|
237
|
+
const items = (label ? rest : input) as Item.Any[]
|
|
233
238
|
const item = {
|
|
234
239
|
id: this.getId(),
|
|
235
240
|
kind: Kind.Sequence,
|
|
241
|
+
label,
|
|
236
242
|
childrenIds: items.map(item => item.id)
|
|
237
243
|
} as Item.Sequence
|
|
238
244
|
this.register(item)
|
|
239
245
|
return item
|
|
240
246
|
}
|
|
241
247
|
|
|
242
|
-
stack = (...
|
|
248
|
+
stack = (...input: ContainerInput): Item.Stack => {
|
|
249
|
+
const [first, ...rest] = input
|
|
250
|
+
const label = typeof first === "string" ? first : undefined
|
|
251
|
+
const items = (label ? rest : input) as Item.Any[]
|
|
243
252
|
const item = {
|
|
244
253
|
kind: Kind.Stack,
|
|
245
254
|
id: this.getId(),
|
|
255
|
+
label,
|
|
246
256
|
childrenIds: items.map(item => item.id)
|
|
247
257
|
} as Item.Stack
|
|
248
258
|
this.register(item)
|
|
@@ -254,6 +264,7 @@ export class O {
|
|
|
254
264
|
options?: {
|
|
255
265
|
start?: number,
|
|
256
266
|
duration?: number
|
|
267
|
+
label?: string
|
|
257
268
|
}): Item.Video => {
|
|
258
269
|
|
|
259
270
|
if(!media.hasVideo)
|
|
@@ -262,6 +273,7 @@ export class O {
|
|
|
262
273
|
const item: Item.Video = {
|
|
263
274
|
kind: Kind.Video,
|
|
264
275
|
id: this.getId(),
|
|
276
|
+
label: options?.label,
|
|
265
277
|
mediaHash: media.datafile.checksum.hash,
|
|
266
278
|
start: options?.start ?? 0,
|
|
267
279
|
duration: options?.duration ?? media.duration
|
|
@@ -274,6 +286,7 @@ export class O {
|
|
|
274
286
|
media: Media,
|
|
275
287
|
options?: {
|
|
276
288
|
duration?: number
|
|
289
|
+
label?: string
|
|
277
290
|
}): Item.Image => {
|
|
278
291
|
|
|
279
292
|
if(!media.isImage)
|
|
@@ -282,6 +295,7 @@ export class O {
|
|
|
282
295
|
const item: Item.Image = {
|
|
283
296
|
kind: Kind.Image,
|
|
284
297
|
id: this.getId(),
|
|
298
|
+
label: options?.label,
|
|
285
299
|
mediaHash: media.datafile.checksum.hash,
|
|
286
300
|
duration: options?.duration ?? 2000
|
|
287
301
|
}
|
|
@@ -295,6 +309,7 @@ export class O {
|
|
|
295
309
|
start?: number,
|
|
296
310
|
duration?: number,
|
|
297
311
|
gain?: number
|
|
312
|
+
label?: string
|
|
298
313
|
}): Item.Audio => {
|
|
299
314
|
|
|
300
315
|
if(!media.hasAudio)
|
|
@@ -303,6 +318,7 @@ export class O {
|
|
|
303
318
|
const item: Item.Audio = {
|
|
304
319
|
kind: Kind.Audio,
|
|
305
320
|
id: this.getId(),
|
|
321
|
+
label: options?.label,
|
|
306
322
|
mediaHash: media.datafile.checksum.hash,
|
|
307
323
|
start: options?.start ?? 0,
|
|
308
324
|
duration: options?.duration ?? media.duration,
|
|
@@ -315,10 +331,12 @@ export class O {
|
|
|
315
331
|
text = (content: string, options?: {
|
|
316
332
|
duration?: number,
|
|
317
333
|
styles?: TextStyleOptions
|
|
334
|
+
label?: string
|
|
318
335
|
}): Item.Text => {
|
|
319
336
|
|
|
320
337
|
const item = {
|
|
321
338
|
id: this.getId(),
|
|
339
|
+
label: options?.label,
|
|
322
340
|
content,
|
|
323
341
|
kind: Kind.Text,
|
|
324
342
|
duration: options?.duration ?? 2000
|
|
@@ -341,6 +359,7 @@ export class O {
|
|
|
341
359
|
const item: Item.Caption = {
|
|
342
360
|
id: this.getId(),
|
|
343
361
|
kind: Kind.Caption,
|
|
362
|
+
label: options?.label,
|
|
344
363
|
transcript,
|
|
345
364
|
itemId: options?.itemId,
|
|
346
365
|
start,
|
|
@@ -386,10 +405,11 @@ export class O {
|
|
|
386
405
|
{presets: this.#makeCaptionPresetActions()}
|
|
387
406
|
) as CaptionActions
|
|
388
407
|
|
|
389
|
-
gap = (duration: number): Item.Gap => {
|
|
408
|
+
gap = (duration: number, options?: ItemMeta): Item.Gap => {
|
|
390
409
|
const item = {
|
|
391
410
|
id: this.getId(),
|
|
392
411
|
kind: Kind.Gap,
|
|
412
|
+
label: options?.label,
|
|
393
413
|
duration
|
|
394
414
|
} as Item.Gap
|
|
395
415
|
this.register(item)
|
|
@@ -397,10 +417,11 @@ export class O {
|
|
|
397
417
|
}
|
|
398
418
|
|
|
399
419
|
#makeTransition = (key: TransitionName): TransitionAction => {
|
|
400
|
-
return (duration: number): Item.Transition => {
|
|
420
|
+
return (duration: number, options?: ItemMeta): Item.Transition => {
|
|
401
421
|
const item: Item.Transition = {
|
|
402
422
|
id: this.getId(),
|
|
403
423
|
kind: Kind.Transition,
|
|
424
|
+
label: options?.label,
|
|
404
425
|
name: transitions[key].name,
|
|
405
426
|
duration,
|
|
406
427
|
}
|