@shotstack/shotstack-studio 1.10.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7661 -4528
- package/dist/schema/assets/fonts/Montserrat.ttf +0 -0
- package/dist/schema/assets/fonts/OpenSans.ttf +0 -0
- package/dist/schema/assets/fonts/Roboto.ttf +0 -0
- package/dist/schema/assets/fonts/WorkSans.ttf +0 -0
- package/dist/schema/index.cjs +1 -1
- package/dist/schema/index.d.ts +7661 -4528
- package/dist/schema/index.mjs +288 -191
- package/dist/shotstack-studio.es.js +39229 -19778
- package/dist/shotstack-studio.umd.js +953 -35
- package/package.json +8 -4
- package/readme.md +95 -294
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cpuccino",
|
|
6
6
|
"dazzatron"
|
|
7
7
|
],
|
|
8
|
-
"version": "
|
|
8
|
+
"version": "2.0.0-beta.1",
|
|
9
9
|
"description": "A video editing library for creating and editing videos with Shotstack",
|
|
10
10
|
"type": "module",
|
|
11
11
|
"main": "dist/shotstack-studio.umd.js",
|
|
@@ -48,14 +48,15 @@
|
|
|
48
48
|
"build": "npm run build:main && npm run build:schema",
|
|
49
49
|
"build:main": "vite build",
|
|
50
50
|
"build:schema": "vite build --config vite.config.schema.ts",
|
|
51
|
-
"test": "
|
|
51
|
+
"test": "jest",
|
|
52
52
|
"test:watch": "jest --watch",
|
|
53
53
|
"test:package": "node test-package.js",
|
|
54
54
|
"typecheck": "tsc --noEmit && tsc --project tsconfig.test.json --noEmit",
|
|
55
55
|
"lint": "eslint --ignore-path .gitignore .",
|
|
56
56
|
"lint:fix": "eslint --ignore-path .gitignore --fix .",
|
|
57
57
|
"format": "prettier --ignore-path .gitignore --write .",
|
|
58
|
-
"prepublishOnly": "npm run build && npm run test && npm run test:package"
|
|
58
|
+
"prepublishOnly": "npm run build && npm run test && npm run test:package",
|
|
59
|
+
"generate:fonts": "npx tsx scripts/fetch-google-fonts.ts"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@jest/globals": "^30.2.0",
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
"eslint-config-prettier": "^9.1.0",
|
|
72
73
|
"eslint-plugin-import": "^2.31.0",
|
|
73
74
|
"jest": "^30.2.0",
|
|
75
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
74
76
|
"prettier": "^3.6.2",
|
|
75
77
|
"ts-jest": "^29.4.5",
|
|
76
78
|
"typescript": "^5.6.2",
|
|
@@ -78,10 +80,12 @@
|
|
|
78
80
|
"vite-plugin-dts": "^4.5.4"
|
|
79
81
|
},
|
|
80
82
|
"dependencies": {
|
|
81
|
-
"@
|
|
83
|
+
"@huggingface/transformers": "^3.0.0",
|
|
84
|
+
"@shotstack/shotstack-canvas": "^1.6.5",
|
|
82
85
|
"fast-deep-equal": "^3.1.3",
|
|
83
86
|
"howler": "^2.2.4",
|
|
84
87
|
"mediabunny": "^1.11.2",
|
|
88
|
+
"opentype": "^0.1.2",
|
|
85
89
|
"opentype.js": "^1.3.4",
|
|
86
90
|
"pixi-filters": "^6.0.5",
|
|
87
91
|
"pixi.js": "^8.5.2",
|
package/readme.md
CHANGED
|
@@ -20,7 +20,6 @@ Try Shotstack Studio in your preferred framework:
|
|
|
20
20
|
|
|
21
21
|
- Create video compositions with multiple tracks and clips
|
|
22
22
|
- Visual timeline interface
|
|
23
|
-
- WYSIWYG text editing
|
|
24
23
|
- Multi-track, drag-and-drop clip manipulation with snap-to-grid
|
|
25
24
|
- Use in conjunction with the [Shotstack Edit API](https://shotstack.io/docs/guide/getting-started/hello-world-using-curl/) to render video
|
|
26
25
|
- Export to video via the browser
|
|
@@ -44,22 +43,22 @@ import { Edit, Canvas, Controls, Timeline } from "@shotstack/shotstack-studio";
|
|
|
44
43
|
const response = await fetch("https://shotstack-assets.s3.amazonaws.com/templates/hello-world/hello.json");
|
|
45
44
|
const template = await response.json();
|
|
46
45
|
|
|
47
|
-
// 2.
|
|
48
|
-
const edit = new Edit(template
|
|
46
|
+
// 2. Create Edit from template and load it
|
|
47
|
+
const edit = new Edit(template);
|
|
49
48
|
await edit.load();
|
|
50
49
|
|
|
51
50
|
// 3. Create a canvas to display the edit
|
|
52
|
-
const canvas = new Canvas(
|
|
51
|
+
const canvas = new Canvas(edit);
|
|
53
52
|
await canvas.load(); // Renders to [data-shotstack-studio] element
|
|
54
53
|
|
|
55
|
-
// 4.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await timeline.load();
|
|
54
|
+
// 4. Initialize the Timeline
|
|
55
|
+
const container = document.querySelector("[data-shotstack-timeline]");
|
|
56
|
+
const timeline = new Timeline(edit, container, {
|
|
57
|
+
features: { toolbar: true, ruler: true, playhead: true, snap: true }
|
|
58
|
+
});
|
|
59
|
+
await timeline.load();
|
|
61
60
|
|
|
62
|
-
//
|
|
61
|
+
// 5. Add keyboard controls
|
|
63
62
|
const controls = new Controls(edit);
|
|
64
63
|
await controls.load();
|
|
65
64
|
```
|
|
@@ -80,14 +79,12 @@ The Edit class represents a video project with its timeline, clips, and properti
|
|
|
80
79
|
```typescript
|
|
81
80
|
import { Edit } from "@shotstack/shotstack-studio";
|
|
82
81
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
// Create an edit with dimensions and background
|
|
86
|
-
const edit = new Edit({ width: 1280, height: 720 }, "#000000");
|
|
82
|
+
// Create an edit from a template
|
|
83
|
+
const edit = new Edit(templateJson);
|
|
87
84
|
await edit.load();
|
|
88
85
|
|
|
89
|
-
//
|
|
90
|
-
await edit.loadEdit(
|
|
86
|
+
// Or reload a different template later
|
|
87
|
+
await edit.loadEdit(newTemplate);
|
|
91
88
|
|
|
92
89
|
// Playback controls
|
|
93
90
|
edit.play();
|
|
@@ -112,6 +109,8 @@ edit.deleteTrack(1);
|
|
|
112
109
|
// Undo/Redo
|
|
113
110
|
edit.undo();
|
|
114
111
|
edit.redo();
|
|
112
|
+
edit.canUndo(); // Check if undo is available (useful for UI)
|
|
113
|
+
edit.canRedo(); // Check if redo is available
|
|
115
114
|
|
|
116
115
|
// Get edit information
|
|
117
116
|
const clip = edit.getClip(0, 0);
|
|
@@ -122,27 +121,48 @@ const duration = edit.totalDuration; // in milliseconds
|
|
|
122
121
|
|
|
123
122
|
#### Events
|
|
124
123
|
|
|
125
|
-
The Edit class provides
|
|
124
|
+
The Edit class provides a typed event system to listen for specific actions:
|
|
126
125
|
|
|
127
126
|
```typescript
|
|
127
|
+
import { Edit, EditEvent } from "@shotstack/shotstack-studio";
|
|
128
|
+
|
|
128
129
|
// Listen for clip selection events
|
|
129
|
-
edit.events.on(
|
|
130
|
+
edit.events.on(EditEvent.ClipSelected, data => {
|
|
130
131
|
console.log("Clip selected:", data.clip);
|
|
131
132
|
console.log("Track index:", data.trackIndex);
|
|
132
133
|
console.log("Clip index:", data.clipIndex);
|
|
133
134
|
});
|
|
134
135
|
|
|
135
136
|
// Listen for clip update events
|
|
136
|
-
edit.events.on(
|
|
137
|
-
console.log("Previous state:", data.previous);
|
|
138
|
-
console.log("Current state:", data.current);
|
|
137
|
+
edit.events.on(EditEvent.ClipUpdated, data => {
|
|
138
|
+
console.log("Previous state:", data.previous);
|
|
139
|
+
console.log("Current state:", data.current);
|
|
139
140
|
});
|
|
141
|
+
|
|
142
|
+
// Listen for playback events
|
|
143
|
+
edit.events.on(EditEvent.PlaybackPlay, () => console.log("Playing"));
|
|
144
|
+
edit.events.on(EditEvent.PlaybackPause, () => console.log("Paused"));
|
|
140
145
|
```
|
|
141
146
|
|
|
142
147
|
Available events:
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
**Playback:** `PlaybackPlay`, `PlaybackPause`
|
|
150
|
+
|
|
151
|
+
**Clips:** `ClipAdded`, `ClipDeleted`, `ClipSelected`, `ClipUpdated`, `ClipCopied`, `ClipSplit`, `ClipRestored`
|
|
152
|
+
|
|
153
|
+
**Selection:** `SelectionCleared`
|
|
154
|
+
|
|
155
|
+
**Edit State:** `EditChanged`, `EditUndo`, `EditRedo`
|
|
156
|
+
|
|
157
|
+
**Tracks:** `TrackAdded`, `TrackRemoved`
|
|
158
|
+
|
|
159
|
+
**Duration:** `DurationChanged`
|
|
160
|
+
|
|
161
|
+
**Output:** `OutputResized`, `OutputFpsChanged`, `OutputFormatChanged`
|
|
162
|
+
|
|
163
|
+
**Merge Fields:** `MergeFieldRegistered`, `MergeFieldUpdated`, `MergeFieldRemoved`, `MergeFieldChanged`
|
|
164
|
+
|
|
165
|
+
**Transcription:** `TranscriptionProgress`, `TranscriptionCompleted`, `TranscriptionFailed`
|
|
146
166
|
|
|
147
167
|
### Canvas
|
|
148
168
|
|
|
@@ -150,7 +170,7 @@ The Canvas class provides the visual rendering of the edit.
|
|
|
150
170
|
|
|
151
171
|
```typescript
|
|
152
172
|
// Create and load the canvas
|
|
153
|
-
const canvas = new Canvas(edit
|
|
173
|
+
const canvas = new Canvas(edit);
|
|
154
174
|
await canvas.load();
|
|
155
175
|
|
|
156
176
|
// Zoom and positioning
|
|
@@ -190,16 +210,17 @@ The Timeline class provides a visual timeline interface for editing.
|
|
|
190
210
|
```typescript
|
|
191
211
|
import { Timeline } from "@shotstack/shotstack-studio";
|
|
192
212
|
|
|
193
|
-
const
|
|
213
|
+
const container = document.querySelector("[data-shotstack-timeline]");
|
|
214
|
+
const timeline = new Timeline(edit, container, {
|
|
215
|
+
features: {
|
|
216
|
+
toolbar: true, // Playback controls and editing buttons
|
|
217
|
+
ruler: true, // Time ruler with markers
|
|
218
|
+
playhead: true, // Draggable playhead
|
|
219
|
+
snap: true, // Snap clips to grid and other clips
|
|
220
|
+
badges: true // Asset type badges on clips
|
|
221
|
+
}
|
|
222
|
+
});
|
|
194
223
|
await timeline.load();
|
|
195
|
-
|
|
196
|
-
// Timeline features:
|
|
197
|
-
// - Visual track and clip representation
|
|
198
|
-
// - Drag-and-drop clip manipulation
|
|
199
|
-
// - Clip resizing with edge detection
|
|
200
|
-
// - Playhead control for navigation
|
|
201
|
-
// - Snap-to-grid functionality
|
|
202
|
-
// - Zoom and scroll controls
|
|
203
224
|
```
|
|
204
225
|
|
|
205
226
|
### VideoExporter
|
|
@@ -211,286 +232,66 @@ const exporter = new VideoExporter(edit, canvas);
|
|
|
211
232
|
await exporter.export("my-video.mp4", 25); // filename, fps
|
|
212
233
|
```
|
|
213
234
|
|
|
214
|
-
##
|
|
215
|
-
|
|
216
|
-
Shotstack Studio supports theming for visual components. Currently, theming is available for the Timeline component, with Canvas theming coming in a future releases.
|
|
235
|
+
## Merge Fields
|
|
217
236
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
The library includes pre-designed themes that you can use immediately:
|
|
237
|
+
Merge fields allow dynamic content substitution using `{{ FIELD_NAME }}` syntax in your templates.
|
|
221
238
|
|
|
222
239
|
```typescript
|
|
223
|
-
import {
|
|
224
|
-
import darkTheme from "@shotstack/shotstack-studio/themes/dark.json";
|
|
225
|
-
import minimalTheme from "@shotstack/shotstack-studio/themes/minimal.json";
|
|
240
|
+
import { Edit, EditEvent } from "@shotstack/shotstack-studio";
|
|
226
241
|
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
// Set a merge field value
|
|
243
|
+
edit.setMergeField("TITLE", "My Video Title");
|
|
244
|
+
edit.setMergeField("SUBTITLE", "A great subtitle");
|
|
230
245
|
|
|
231
|
-
|
|
246
|
+
// Get all registered merge fields
|
|
247
|
+
const fields = edit.getMergeFields();
|
|
232
248
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
timeline: {
|
|
238
|
-
// Main timeline colors
|
|
239
|
-
background: "#1e1e1e",
|
|
240
|
-
divider: "#1a1a1a",
|
|
241
|
-
playhead: "#ff4444",
|
|
242
|
-
snapGuide: "#888888",
|
|
243
|
-
dropZone: "#00ff00",
|
|
244
|
-
trackInsertion: "#00ff00",
|
|
245
|
-
|
|
246
|
-
// Toolbar styling
|
|
247
|
-
toolbar: {
|
|
248
|
-
background: "#1a1a1a",
|
|
249
|
-
surface: "#2a2a2a", // Button backgrounds
|
|
250
|
-
hover: "#3a3a3a", // Button hover state
|
|
251
|
-
active: "#007acc", // Button active state
|
|
252
|
-
divider: "#3a3a3a", // Separator lines
|
|
253
|
-
icon: "#888888", // Icon colors
|
|
254
|
-
text: "#ffffff", // Text color
|
|
255
|
-
height: 36 // Toolbar height in pixels
|
|
256
|
-
},
|
|
257
|
-
|
|
258
|
-
// Ruler styling
|
|
259
|
-
ruler: {
|
|
260
|
-
background: "#404040",
|
|
261
|
-
text: "#ffffff", // Time labels
|
|
262
|
-
markers: "#666666", // Time marker dots
|
|
263
|
-
height: 40 // Ruler height in pixels
|
|
264
|
-
},
|
|
265
|
-
|
|
266
|
-
// Track styling
|
|
267
|
-
tracks: {
|
|
268
|
-
surface: "#2d2d2d", // Primary track color
|
|
269
|
-
surfaceAlt: "#252525", // Alternating track color
|
|
270
|
-
border: "#3a3a3a", // Track borders
|
|
271
|
-
height: 60 // Track height in pixels
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
// Clip colors by asset type
|
|
275
|
-
clips: {
|
|
276
|
-
video: "#4a9eff",
|
|
277
|
-
audio: "#00d4aa",
|
|
278
|
-
image: "#f5a623",
|
|
279
|
-
text: "#d0021b",
|
|
280
|
-
shape: "#9013fe",
|
|
281
|
-
html: "#50e3c2",
|
|
282
|
-
luma: "#b8e986",
|
|
283
|
-
default: "#8e8e93", // Unknown asset types
|
|
284
|
-
selected: "#007acc", // Selection border
|
|
285
|
-
radius: 4 // Corner radius in pixels
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
// Canvas theming will be available in future releases
|
|
289
|
-
// canvas: { ... }
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const timeline = new Timeline(edit, { width: 1280, height: 300 }, { theme: customTheme });
|
|
249
|
+
// Listen for merge field changes
|
|
250
|
+
edit.events.on(EditEvent.MergeFieldUpdated, ({ field }) => {
|
|
251
|
+
console.log(`Field ${field.name} updated to:`, field.value);
|
|
252
|
+
});
|
|
293
253
|
```
|
|
294
254
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
Themes are organized by component, making it intuitive to customize specific parts of the interface:
|
|
255
|
+
In templates, use placeholders that will be replaced with merge field values:
|
|
298
256
|
|
|
299
|
-
|
|
300
|
-
- `toolbar`: Playback controls and buttons
|
|
301
|
-
- `ruler`: Time markers and labels
|
|
302
|
-
- `tracks`: Track backgrounds and borders
|
|
303
|
-
- `clips`: Asset-specific colors and selection states
|
|
304
|
-
- Global timeline properties (background, playhead, etc.)
|
|
305
|
-
|
|
306
|
-
- **Canvas** (coming soon): Will control the appearance of the video preview area
|
|
307
|
-
|
|
308
|
-
## Template Format
|
|
309
|
-
|
|
310
|
-
Templates use a JSON format with the following structure:
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
257
|
+
```json
|
|
313
258
|
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
{ src: "https://example.com/font.ttf" }
|
|
318
|
-
],
|
|
319
|
-
tracks: [
|
|
320
|
-
{
|
|
321
|
-
clips: [
|
|
322
|
-
{
|
|
323
|
-
asset: {
|
|
324
|
-
type: "image", // image, video, text, shape, audio
|
|
325
|
-
src: "https://example.com/image.jpg",
|
|
326
|
-
// Other asset properties depend on type
|
|
327
|
-
},
|
|
328
|
-
start: 0, // Start time in seconds
|
|
329
|
-
length: 5, // Duration in seconds
|
|
330
|
-
transition: { // Optional transitions
|
|
331
|
-
in: "fade",
|
|
332
|
-
out: "fade"
|
|
333
|
-
},
|
|
334
|
-
position: "center", // Positioning
|
|
335
|
-
scale: 1, // Scale factor
|
|
336
|
-
offset: {
|
|
337
|
-
x: 0.1, // X-axis offset relative to position
|
|
338
|
-
y: 0 // Y-axis offset relative to position
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
]
|
|
342
|
-
}
|
|
343
|
-
]
|
|
344
|
-
},
|
|
345
|
-
output: {
|
|
346
|
-
format: "mp4",
|
|
347
|
-
size: {
|
|
348
|
-
width: 1280,
|
|
349
|
-
height: 720
|
|
350
|
-
}
|
|
259
|
+
"asset": {
|
|
260
|
+
"type": "text",
|
|
261
|
+
"text": "{{ TITLE }}"
|
|
351
262
|
}
|
|
352
263
|
}
|
|
353
264
|
```
|
|
354
265
|
|
|
355
|
-
##
|
|
356
|
-
|
|
357
|
-
PolyForm Shield License 1.0.0
|
|
358
|
-
|
|
359
|
-
## API Reference
|
|
360
|
-
|
|
361
|
-
### Edit
|
|
266
|
+
## Custom Toolbar Buttons
|
|
362
267
|
|
|
363
|
-
|
|
268
|
+
Register custom toolbar buttons to extend the canvas toolbar with your own actions:
|
|
364
269
|
|
|
365
270
|
```typescript
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
Creates a new Edit instance with the specified dimensions and background color.
|
|
377
|
-
|
|
378
|
-
#### Properties
|
|
379
|
-
|
|
380
|
-
- `assetLoader` - Asset loader instance for managing media assets
|
|
381
|
-
- `events` - Event emitter for handling events
|
|
382
|
-
- `playbackTime` - Current playback position in milliseconds
|
|
383
|
-
- `totalDuration` - Total duration of the edit in milliseconds
|
|
384
|
-
|
|
385
|
-
#### Methods
|
|
386
|
-
|
|
387
|
-
- `async load()` - Initialize and prepare the edit for rendering
|
|
388
|
-
- `async loadEdit(edit: EditType)` - Load an edit from a JSON template
|
|
389
|
-
- `play()` - Start playback
|
|
390
|
-
- `pause()` - Pause playback
|
|
391
|
-
- `seek(target: number)` - Seek to a specific time in milliseconds
|
|
392
|
-
- `stop()` - Stop playback and return to beginning
|
|
393
|
-
- `addClip(trackIdx: number, clip: ClipType)` - Add a clip to a specific track
|
|
394
|
-
- `deleteClip(trackIdx: number, clipIdx: number)` - Delete a clip
|
|
395
|
-
- `getClip(trackIdx: number, clipIdx: number)` - Get a clip by track and index
|
|
396
|
-
- `addTrack(trackIdx: number, track: TrackType)` - Add a new track
|
|
397
|
-
- `getTrack(trackIdx: number)` - Get a track by index
|
|
398
|
-
- `deleteTrack(trackIdx: number)` - Delete a track
|
|
399
|
-
- `getEdit()` - Get the full edit configuration as a JSON object
|
|
400
|
-
- `undo()` - Undo the last editing operation
|
|
401
|
-
- `redo()` - Redo the last undone operation
|
|
402
|
-
|
|
403
|
-
#### Events
|
|
404
|
-
|
|
405
|
-
- `clip:selected` - Triggered when a clip is selected
|
|
406
|
-
- `clip:updated` - Triggered when a clip is modified
|
|
407
|
-
- `edit:undo` - Triggered when an undo operation is performed
|
|
408
|
-
- `edit:redo` - Triggered when a redo operation is performed
|
|
409
|
-
|
|
410
|
-
### Canvas
|
|
411
|
-
|
|
412
|
-
The `Canvas` class provides the visual rendering of the edit.
|
|
413
|
-
|
|
414
|
-
```typescript
|
|
415
|
-
import { Canvas } from "@shotstack/shotstack-studio";
|
|
416
|
-
import type { Size } from "@shotstack/shotstack-studio";
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
#### Constructor
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
constructor(size: Size, edit: Edit)
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
Creates a new canvas with specified dimensions for rendering the edit.
|
|
426
|
-
|
|
427
|
-
#### Methods
|
|
428
|
-
|
|
429
|
-
- `async load()` - Initialize the canvas and add it to the DOM
|
|
430
|
-
- `centerEdit()` - Center the edit in the canvas
|
|
431
|
-
- `zoomToFit()` - Zoom to fit the entire edit
|
|
432
|
-
- `setZoom(zoom: number)` - Set zoom level
|
|
433
|
-
- `dispose()` - Clean up resources and remove the canvas from the DOM
|
|
434
|
-
|
|
435
|
-
### Controls
|
|
436
|
-
|
|
437
|
-
The `Controls` class adds keyboard controls for playback.
|
|
438
|
-
|
|
439
|
-
```typescript
|
|
440
|
-
import { Controls } from "@shotstack/shotstack-studio";
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
#### Constructor
|
|
444
|
-
|
|
445
|
-
```typescript
|
|
446
|
-
constructor(edit: Edit)
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
Creates a new controls instance for the provided Edit.
|
|
450
|
-
|
|
451
|
-
#### Methods
|
|
452
|
-
|
|
453
|
-
- `async load()` - Set up event listeners for keyboard controls
|
|
454
|
-
|
|
455
|
-
### Timeline
|
|
456
|
-
|
|
457
|
-
The `Timeline` class provides a visual timeline interface for video editing.
|
|
458
|
-
|
|
459
|
-
```typescript
|
|
460
|
-
import { Timeline } from "@shotstack/shotstack-studio";
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
#### Constructor
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
constructor(edit: Edit, size: { width: number, height: number }, themeOptions?: TimelineThemeOptions)
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
Creates a new timeline interface for the provided Edit.
|
|
470
|
-
|
|
471
|
-
#### Methods
|
|
472
|
-
|
|
473
|
-
- `async load()` - Initialize the timeline and add it to the DOM
|
|
474
|
-
- `setTheme(themeOptions: TimelineThemeOptions)` - Change the timeline theme
|
|
475
|
-
- `setOptions(options: Partial<TimelineOptions>)` - Update timeline options
|
|
476
|
-
- `dispose()` - Clean up resources and remove from DOM
|
|
477
|
-
|
|
478
|
-
### VideoExporter
|
|
479
|
-
|
|
480
|
-
The `VideoExporter` class handles exporting the edit to MP4.
|
|
271
|
+
// Register a custom button
|
|
272
|
+
edit.registerToolbarButton({
|
|
273
|
+
id: "add-text",
|
|
274
|
+
icon: `<svg viewBox="0 0 16 16">...</svg>`,
|
|
275
|
+
tooltip: "Add Text",
|
|
276
|
+
event: "text:requested",
|
|
277
|
+
dividerBefore: true // Optional: add a divider before this button
|
|
278
|
+
});
|
|
481
279
|
|
|
482
|
-
|
|
483
|
-
|
|
280
|
+
// Handle the custom event
|
|
281
|
+
edit.events.on("text:requested", ({ position }) => {
|
|
282
|
+
// position is the current playhead position in milliseconds
|
|
283
|
+
edit.addClip(0, {
|
|
284
|
+
asset: { type: "text", text: "New Text" },
|
|
285
|
+
start: position / 1000,
|
|
286
|
+
length: 5
|
|
287
|
+
});
|
|
288
|
+
});
|
|
484
289
|
```
|
|
485
290
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
```typescript
|
|
489
|
-
constructor(edit: Edit, canvas: Canvas)
|
|
490
|
-
```
|
|
291
|
+
## API Reference
|
|
491
292
|
|
|
492
|
-
|
|
293
|
+
For complete schema and type definitions, see the [Shotstack API Reference](https://shotstack.io/docs/api/#tocs_edit).
|
|
493
294
|
|
|
494
|
-
|
|
295
|
+
## License
|
|
495
296
|
|
|
496
|
-
|
|
297
|
+
PolyForm Shield License 1.0.0
|