@editframe/create 0.43.0 → 0.45.0
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/dist/index.js +16 -28
- package/dist/index.js.map +1 -1
- package/dist/skills/editframe-brand-video-generator/README.md +155 -0
- package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
- package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
- package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
- package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
- package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
- package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
- package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
- package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
- package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
- package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
- package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
- package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
- package/dist/skills/editframe-composition/SKILL.md +169 -0
- package/dist/skills/editframe-composition/references/audio.md +483 -0
- package/dist/skills/editframe-composition/references/captions.md +844 -0
- package/dist/skills/editframe-composition/references/composition-model.md +73 -0
- package/dist/skills/editframe-composition/references/configuration.md +403 -0
- package/dist/skills/editframe-composition/references/css-parts.md +105 -0
- package/dist/skills/editframe-composition/references/css-variables.md +640 -0
- package/dist/skills/editframe-composition/references/entry-points.md +810 -0
- package/dist/skills/editframe-composition/references/events.md +499 -0
- package/dist/skills/editframe-composition/references/getting-started.md +259 -0
- package/dist/skills/editframe-composition/references/hooks.md +234 -0
- package/dist/skills/editframe-composition/references/image.md +241 -0
- package/dist/skills/editframe-composition/references/r3f.md +580 -0
- package/dist/skills/editframe-composition/references/render-api.md +484 -0
- package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
- package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
- package/dist/skills/editframe-composition/references/scripting.md +606 -0
- package/dist/skills/editframe-composition/references/sequencing.md +116 -0
- package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
- package/dist/skills/editframe-composition/references/surface.md +329 -0
- package/dist/skills/editframe-composition/references/text.md +627 -0
- package/dist/skills/editframe-composition/references/time-model.md +99 -0
- package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
- package/dist/skills/editframe-composition/references/timegroup.md +457 -0
- package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
- package/dist/skills/editframe-composition/references/transcription.md +47 -0
- package/dist/skills/editframe-composition/references/transitions.md +608 -0
- package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
- package/dist/skills/editframe-composition/references/video.md +506 -0
- package/dist/skills/editframe-composition/references/waveform.md +327 -0
- package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
- package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
- package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
- package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
- package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
- package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
- package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
- package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
- package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
- package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
- package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
- package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
- package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
- package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
- package/dist/skills/editframe-editor-gui/references/play.md +370 -0
- package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
- package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
- package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
- package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
- package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
- package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
- package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
- package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
- package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
- package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
- package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
- package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
- package/dist/skills/editframe-motion-design/SKILL.md +101 -0
- package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
- package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
- package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
- package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
- package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
- package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
- package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
- package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
- package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
- package/dist/skills/editframe-webhooks/SKILL.md +126 -0
- package/dist/skills/editframe-webhooks/references/events.md +382 -0
- package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
- package/dist/skills/editframe-webhooks/references/security.md +418 -0
- package/dist/skills/editframe-webhooks/references/testing.md +409 -0
- package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
- package/dist/templates/html/AGENTS.md +13 -0
- package/dist/templates/react/AGENTS.md +13 -0
- package/dist/utils.js +15 -16
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/tsdown.config.ts +4 -0
- package/dist/detectAgent.js +0 -89
- package/dist/detectAgent.js.map +0 -1
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Timeline Root
|
|
3
|
+
description: Required wrapper component for React-based Editframe timelines that sets up rendering context and playback coordination.
|
|
4
|
+
type: reference
|
|
5
|
+
nav:
|
|
6
|
+
parent: "React"
|
|
7
|
+
priority: 10
|
|
8
|
+
related: ["timegroup", "configuration"]
|
|
9
|
+
api:
|
|
10
|
+
properties:
|
|
11
|
+
- name: id
|
|
12
|
+
type: string
|
|
13
|
+
required: true
|
|
14
|
+
description: Unique identifier for the root timegroup
|
|
15
|
+
- name: component
|
|
16
|
+
type: React.ComponentType
|
|
17
|
+
required: true
|
|
18
|
+
description: React component that renders your timeline content
|
|
19
|
+
- name: className
|
|
20
|
+
type: string
|
|
21
|
+
description: CSS class name for the container
|
|
22
|
+
- name: style
|
|
23
|
+
type: React.CSSProperties
|
|
24
|
+
description: Inline styles for the container
|
|
25
|
+
- name: children
|
|
26
|
+
type: React.ReactNode
|
|
27
|
+
description: Optional children (typically used for Configuration wrapper)
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# TimelineRoot
|
|
31
|
+
|
|
32
|
+
Wrapper component required for React-based timelines to ensure proper rendering.
|
|
33
|
+
|
|
34
|
+
## Why TimelineRoot is Required
|
|
35
|
+
|
|
36
|
+
`TimelineRoot` ensures that React components work correctly during video rendering. Without it:
|
|
37
|
+
|
|
38
|
+
- React hooks won't work during rendering (`useTimingInfo`, `useEffect`, etc.)
|
|
39
|
+
- JavaScript state and effects won't be present
|
|
40
|
+
- Dynamic content won't update correctly
|
|
41
|
+
- Render output may not match preview
|
|
42
|
+
|
|
43
|
+
Always wrap your composition component with `TimelineRoot` for consistent behavior.
|
|
44
|
+
|
|
45
|
+
## Import
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { TimelineRoot } from "@editframe/react";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Basic Usage
|
|
52
|
+
|
|
53
|
+
### Minimal Setup
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// Video.tsx
|
|
57
|
+
import { Timegroup, Text } from "@editframe/react";
|
|
58
|
+
|
|
59
|
+
export const Video = () => {
|
|
60
|
+
return (
|
|
61
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
|
|
62
|
+
<Timegroup mode="fixed" duration="5s" className="absolute w-full h-full">
|
|
63
|
+
<Text duration="5s" className="text-white text-4xl">
|
|
64
|
+
Your video starts here
|
|
65
|
+
</Text>
|
|
66
|
+
</Timegroup>
|
|
67
|
+
</Timegroup>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// main.tsx
|
|
72
|
+
import React from "react";
|
|
73
|
+
import ReactDOM from "react-dom/client";
|
|
74
|
+
import { TimelineRoot } from "@editframe/react";
|
|
75
|
+
import { Video } from "./Video";
|
|
76
|
+
import "@editframe/elements/styles.css";
|
|
77
|
+
|
|
78
|
+
const root = document.getElementById("root");
|
|
79
|
+
if (!root) throw new Error("Root element not found");
|
|
80
|
+
|
|
81
|
+
ReactDOM.createRoot(root).render(
|
|
82
|
+
<TimelineRoot id="root" component={Video} />
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### With Configuration
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// main.tsx
|
|
90
|
+
import React from "react";
|
|
91
|
+
import ReactDOM from "react-dom/client";
|
|
92
|
+
import { Configuration, TimelineRoot } from "@editframe/react";
|
|
93
|
+
import { Video } from "./Video";
|
|
94
|
+
import "@editframe/elements/styles.css";
|
|
95
|
+
|
|
96
|
+
const root = document.getElementById("root");
|
|
97
|
+
if (!root) throw new Error("Root element not found");
|
|
98
|
+
|
|
99
|
+
ReactDOM.createRoot(root).render(
|
|
100
|
+
<Configuration apiHost="https://api.example.com" mediaEngine="local">
|
|
101
|
+
<TimelineRoot id="root" component={Video} />
|
|
102
|
+
</Configuration>
|
|
103
|
+
);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### With Workbench
|
|
107
|
+
|
|
108
|
+
The root `Timegroup` in your component should have the `workbench` prop:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
// Video.tsx
|
|
112
|
+
export const Video = () => {
|
|
113
|
+
return (
|
|
114
|
+
<Timegroup
|
|
115
|
+
workbench // Enables workbench UI
|
|
116
|
+
mode="sequence"
|
|
117
|
+
className="w-[1920px] h-[1080px] bg-black"
|
|
118
|
+
>
|
|
119
|
+
{/* Your composition */}
|
|
120
|
+
</Timegroup>
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// main.tsx
|
|
125
|
+
ReactDOM.createRoot(root).render(
|
|
126
|
+
<TimelineRoot id="root" component={Video} />
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## How It Works
|
|
131
|
+
|
|
132
|
+
`TimelineRoot` ensures your React component tree is properly initialized for both preview and rendering. It handles the setup required to make React hooks, state, and effects work consistently throughout the video rendering process.
|
|
133
|
+
|
|
134
|
+
## Examples
|
|
135
|
+
|
|
136
|
+
### With useTimingInfo Hook
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
// AnimatedScene.tsx
|
|
140
|
+
import { Timegroup, Text, useTimingInfo } from "@editframe/react";
|
|
141
|
+
|
|
142
|
+
const AnimatedScene = () => {
|
|
143
|
+
const { ref, percentComplete } = useTimingInfo();
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<Timegroup ref={ref} mode="fixed" duration="5s" className="absolute w-full h-full">
|
|
147
|
+
<div style={{ opacity: percentComplete }}>
|
|
148
|
+
<Text duration="5s" className="text-white text-4xl">
|
|
149
|
+
Fading in...
|
|
150
|
+
</Text>
|
|
151
|
+
</div>
|
|
152
|
+
</Timegroup>
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const Video = () => {
|
|
157
|
+
return (
|
|
158
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
|
|
159
|
+
<AnimatedScene />
|
|
160
|
+
</Timegroup>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// main.tsx
|
|
165
|
+
ReactDOM.createRoot(root).render(
|
|
166
|
+
<TimelineRoot id="root" component={Video} />
|
|
167
|
+
);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### With Dynamic Content
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
// DynamicVideo.tsx
|
|
174
|
+
import { Timegroup, Text } from "@editframe/react";
|
|
175
|
+
|
|
176
|
+
interface VideoProps {
|
|
177
|
+
title: string;
|
|
178
|
+
duration: string;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const DynamicVideo = ({ title, duration }: VideoProps) => {
|
|
182
|
+
return (
|
|
183
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
|
|
184
|
+
<Timegroup mode="fixed" duration={duration} className="absolute w-full h-full">
|
|
185
|
+
<Text duration={duration} className="text-white text-4xl">
|
|
186
|
+
{title}
|
|
187
|
+
</Text>
|
|
188
|
+
</Timegroup>
|
|
189
|
+
</Timegroup>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Wrapper component for TimelineRoot
|
|
194
|
+
export const Video = () => {
|
|
195
|
+
return <DynamicVideo title="Hello World" duration="5s" />;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// main.tsx
|
|
199
|
+
ReactDOM.createRoot(root).render(
|
|
200
|
+
<TimelineRoot id="root" component={Video} />
|
|
201
|
+
);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### With Frame Tasks
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// CounterScene.tsx
|
|
208
|
+
import { useRef, useEffect } from "react";
|
|
209
|
+
import { Timegroup } from "@editframe/react";
|
|
210
|
+
|
|
211
|
+
const CounterScene = () => {
|
|
212
|
+
const timegroupRef = useRef<HTMLElement>(null);
|
|
213
|
+
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
const tg = timegroupRef.current;
|
|
216
|
+
if (!tg) return;
|
|
217
|
+
|
|
218
|
+
tg.initializer = (instance) => {
|
|
219
|
+
return instance.addFrameTask((info) => {
|
|
220
|
+
const text = instance.querySelector('.counter-text');
|
|
221
|
+
if (text) {
|
|
222
|
+
const seconds = (info.ownCurrentTimeMs / 1000).toFixed(2);
|
|
223
|
+
text.textContent = `Time: ${seconds}s`;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return () => {
|
|
229
|
+
if (tg) tg.initializer = undefined;
|
|
230
|
+
};
|
|
231
|
+
}, []);
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<Timegroup ref={timegroupRef} mode="fixed" duration="10s" className="absolute w-full h-full">
|
|
235
|
+
<div className="text-4xl text-white counter-text" />
|
|
236
|
+
</Timegroup>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export const Video = () => {
|
|
241
|
+
return (
|
|
242
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
|
|
243
|
+
<CounterScene />
|
|
244
|
+
</Timegroup>
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// main.tsx - TimelineRoot ensures frame tasks work during rendering
|
|
249
|
+
ReactDOM.createRoot(root).render(
|
|
250
|
+
<TimelineRoot id="root" component={Video} />
|
|
251
|
+
);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Common Patterns
|
|
255
|
+
|
|
256
|
+
### Separating Composition from Wrapper
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
// VideoComposition.tsx - Pure composition logic
|
|
260
|
+
export const VideoComposition = () => {
|
|
261
|
+
return (
|
|
262
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
|
|
263
|
+
{/* Your scenes */}
|
|
264
|
+
</Timegroup>
|
|
265
|
+
);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// App.tsx - Wrapper with Configuration
|
|
269
|
+
import { Configuration, TimelineRoot } from "@editframe/react";
|
|
270
|
+
import { VideoComposition } from "./VideoComposition";
|
|
271
|
+
|
|
272
|
+
export const App = () => {
|
|
273
|
+
return (
|
|
274
|
+
<Configuration
|
|
275
|
+
apiHost={import.meta.env.VITE_EDITFRAME_API}
|
|
276
|
+
mediaEngine="local"
|
|
277
|
+
>
|
|
278
|
+
<TimelineRoot id="root" component={VideoComposition} />
|
|
279
|
+
</Configuration>
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Multiple Timelines
|
|
285
|
+
|
|
286
|
+
If you need multiple independent timelines, use different IDs:
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
<div>
|
|
290
|
+
<TimelineRoot id="timeline-1" component={Video1} />
|
|
291
|
+
<TimelineRoot id="timeline-2" component={Video2} />
|
|
292
|
+
</div>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Custom Container Styling
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
<TimelineRoot
|
|
299
|
+
id="root"
|
|
300
|
+
component={Video}
|
|
301
|
+
className="custom-container"
|
|
302
|
+
style={{ maxWidth: '1920px', margin: '0 auto' }}
|
|
303
|
+
/>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Requirements
|
|
307
|
+
|
|
308
|
+
### Component Must Return Timegroup
|
|
309
|
+
|
|
310
|
+
Your component **must** render a `Timegroup` at the root level:
|
|
311
|
+
|
|
312
|
+
```tsx
|
|
313
|
+
// ✅ Correct
|
|
314
|
+
export const Video = () => {
|
|
315
|
+
return (
|
|
316
|
+
<Timegroup mode="sequence">
|
|
317
|
+
{/* content */}
|
|
318
|
+
</Timegroup>
|
|
319
|
+
);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// ❌ Wrong - no Timegroup at root
|
|
323
|
+
export const Video = () => {
|
|
324
|
+
return (
|
|
325
|
+
<div>
|
|
326
|
+
<Timegroup mode="sequence">
|
|
327
|
+
{/* content */}
|
|
328
|
+
</Timegroup>
|
|
329
|
+
</div>
|
|
330
|
+
);
|
|
331
|
+
};
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Synchronous Rendering Only
|
|
335
|
+
|
|
336
|
+
The component must render synchronously. Avoid:
|
|
337
|
+
- Suspense boundaries
|
|
338
|
+
- Lazy loading at the root
|
|
339
|
+
- Async data fetching that blocks render
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
// ✅ Correct - synchronous render
|
|
343
|
+
export const Video = () => {
|
|
344
|
+
return <Timegroup mode="sequence">{/* content */}</Timegroup>;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// ❌ Wrong - Suspense blocks synchronous render
|
|
348
|
+
export const Video = () => {
|
|
349
|
+
return (
|
|
350
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
351
|
+
<Timegroup mode="sequence">{/* content */}</Timegroup>
|
|
352
|
+
</Suspense>
|
|
353
|
+
);
|
|
354
|
+
};
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Troubleshooting
|
|
358
|
+
|
|
359
|
+
### "No ef-timegroup found in component"
|
|
360
|
+
|
|
361
|
+
Your component must render a `Timegroup` at the root level. Check that:
|
|
362
|
+
- Component returns a `Timegroup` directly
|
|
363
|
+
- No wrapper divs around the `Timegroup`
|
|
364
|
+
- Component is not returning `null` or `undefined`
|
|
365
|
+
|
|
366
|
+
### Hooks Not Working During Rendering
|
|
367
|
+
|
|
368
|
+
Make sure you're using `TimelineRoot` in your `main.tsx`:
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
// ❌ Wrong - hooks won't work during rendering
|
|
372
|
+
ReactDOM.createRoot(root).render(<Video />);
|
|
373
|
+
|
|
374
|
+
// ✅ Correct - hooks work everywhere
|
|
375
|
+
ReactDOM.createRoot(root).render(
|
|
376
|
+
<TimelineRoot id="root" component={Video} />
|
|
377
|
+
);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Render Output Doesn't Match Preview
|
|
381
|
+
|
|
382
|
+
This usually means `TimelineRoot` is missing. Always use `TimelineRoot` to ensure consistent behavior between preview and rendering.
|
|
383
|
+
|
|
384
|
+
## Performance Considerations
|
|
385
|
+
|
|
386
|
+
`TimelineRoot` ensures your React components work correctly during rendering. For best performance:
|
|
387
|
+
|
|
388
|
+
- Keep your component tree reasonably sized
|
|
389
|
+
- Avoid expensive computations in render
|
|
390
|
+
- Use memoization for complex calculations
|
|
391
|
+
- Frame tasks are still the best way to update content per-frame
|
|
392
|
+
|
|
393
|
+
## See Also
|
|
394
|
+
|
|
395
|
+
- [scripting.md](references/scripting.md) - Frame tasks and initializers
|
|
396
|
+
- [hooks.md](references/hooks.md) - useTimingInfo and other hooks
|
|
397
|
+
- [configuration.md](references/configuration.md) - Configuration component
|
|
398
|
+
- [getting-started.md](references/getting-started.md) - Project setup
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Transcription
|
|
3
|
+
description: Generate word-level transcription data from audio and video files for use with ef-captions synchronized caption playback.
|
|
4
|
+
type: how-to
|
|
5
|
+
nav:
|
|
6
|
+
parent: "Rendering"
|
|
7
|
+
priority: 30
|
|
8
|
+
related: ["captions", "audio"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Generating Captions
|
|
12
|
+
|
|
13
|
+
Generate word-level captions for `ef-captions` using the Editframe CLI.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx editframe transcribe video.mp4 -o captions.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
See the `editframe-cli` skill for full transcription options, language support, and requirements.
|
|
22
|
+
|
|
23
|
+
## Automatic Transcription
|
|
24
|
+
|
|
25
|
+
During development, captions are generated automatically when you reference a video/audio file:
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<ef-captions for="my-video">
|
|
29
|
+
<ef-captions-active-word class="text-yellow-300"></ef-captions-active-word>
|
|
30
|
+
</ef-captions>
|
|
31
|
+
|
|
32
|
+
<ef-video id="my-video" src="video.mp4"></ef-video>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The dev server detects the video and generates captions on first use.
|
|
36
|
+
|
|
37
|
+
## Use in Composition
|
|
38
|
+
|
|
39
|
+
Load from file:
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<ef-captions captions-src="/assets/captions.json">
|
|
43
|
+
<ef-captions-before-active-word class="text-white/60"></ef-captions-before-active-word>
|
|
44
|
+
<ef-captions-active-word class="text-yellow-300 font-bold"></ef-captions-active-word>
|
|
45
|
+
<ef-captions-after-active-word class="text-white/40"></ef-captions-after-active-word>
|
|
46
|
+
</ef-captions>
|
|
47
|
+
```
|