@editframe/create 0.44.0 → 0.45.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.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 +1 -1
- package/tsdown.config.ts +4 -0
- package/dist/detectAgent.js +0 -89
- package/dist/detectAgent.js.map +0 -1
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useMediaInfo Hook
|
|
3
|
+
description: React hook for reading media metadata — duration, loading state, and dimensions — from Video and Audio composition elements.
|
|
4
|
+
type: reference
|
|
5
|
+
nav:
|
|
6
|
+
parent: "React"
|
|
7
|
+
priority: 12
|
|
8
|
+
related: ["hooks", "video", "audio"]
|
|
9
|
+
api:
|
|
10
|
+
functions:
|
|
11
|
+
- name: useMediaInfo
|
|
12
|
+
signature: "useMediaInfo(mediaRef: RefObject<MediaElement>): MediaInfo"
|
|
13
|
+
description: Access media metadata from Video or Audio ref
|
|
14
|
+
returns: MediaInfo object with intrinsicDurationMs and loading state
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# useMediaInfo
|
|
18
|
+
|
|
19
|
+
Access media metadata like duration and loading state from Video and Audio components.
|
|
20
|
+
|
|
21
|
+
## Import
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { useMediaInfo } from "@editframe/react";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Return Type
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
interface MediaInfo {
|
|
31
|
+
intrinsicDurationMs: number | undefined; // Media duration in milliseconds
|
|
32
|
+
loading: boolean; // True while metadata is loading
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Basic Usage
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { useRef } from "react";
|
|
40
|
+
import { Video, useMediaInfo } from "@editframe/react";
|
|
41
|
+
|
|
42
|
+
const VideoWithDuration = () => {
|
|
43
|
+
const videoRef = useRef(null);
|
|
44
|
+
const { intrinsicDurationMs, loading } = useMediaInfo(videoRef);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<>
|
|
48
|
+
<Video
|
|
49
|
+
ref={videoRef}
|
|
50
|
+
src="/assets/video.mp4"
|
|
51
|
+
className="size-full object-cover"
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
{loading ? (
|
|
55
|
+
<div className="absolute top-4 right-4 text-white">
|
|
56
|
+
Loading...
|
|
57
|
+
</div>
|
|
58
|
+
) : (
|
|
59
|
+
<div className="absolute top-4 right-4 text-white">
|
|
60
|
+
Duration: {((intrinsicDurationMs || 0) / 1000).toFixed(1)}s
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## With Audio
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useRef } from "react";
|
|
72
|
+
import { Audio, Waveform, useMediaInfo } from "@editframe/react";
|
|
73
|
+
|
|
74
|
+
const AudioWithInfo = () => {
|
|
75
|
+
const audioRef = useRef(null);
|
|
76
|
+
const { intrinsicDurationMs, loading } = useMediaInfo(audioRef);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
<Audio
|
|
81
|
+
ref={audioRef}
|
|
82
|
+
src="/assets/music.mp3"
|
|
83
|
+
/>
|
|
84
|
+
|
|
85
|
+
{!loading && intrinsicDurationMs && (
|
|
86
|
+
<>
|
|
87
|
+
<Waveform target={audioRef} className="w-full h-24" />
|
|
88
|
+
<div className="text-white text-center mt-2">
|
|
89
|
+
{(intrinsicDurationMs / 1000).toFixed(1)} seconds
|
|
90
|
+
</div>
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
93
|
+
</>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Format Duration Display
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { useRef } from "react";
|
|
102
|
+
import { Video, useMediaInfo } from "@editframe/react";
|
|
103
|
+
|
|
104
|
+
const formatDuration = (ms: number | undefined): string => {
|
|
105
|
+
if (ms === undefined) return "--:--";
|
|
106
|
+
|
|
107
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
108
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
109
|
+
const seconds = totalSeconds % 60;
|
|
110
|
+
|
|
111
|
+
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const VideoWithFormattedTime = () => {
|
|
115
|
+
const videoRef = useRef(null);
|
|
116
|
+
const { intrinsicDurationMs } = useMediaInfo(videoRef);
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<>
|
|
120
|
+
<Video
|
|
121
|
+
ref={videoRef}
|
|
122
|
+
src="/assets/video.mp4"
|
|
123
|
+
className="size-full object-cover"
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
<div className="absolute bottom-4 right-4 bg-black/70 text-white px-3 py-1 rounded">
|
|
127
|
+
{formatDuration(intrinsicDurationMs)}
|
|
128
|
+
</div>
|
|
129
|
+
</>
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Dynamic Timegroup Duration
|
|
135
|
+
|
|
136
|
+
Set timegroup duration based on media duration:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { useRef, useEffect, useState } from "react";
|
|
140
|
+
import { Timegroup, Video, useMediaInfo } from "@editframe/react";
|
|
141
|
+
|
|
142
|
+
const DynamicDurationScene = () => {
|
|
143
|
+
const videoRef = useRef(null);
|
|
144
|
+
const { intrinsicDurationMs, loading } = useMediaInfo(videoRef);
|
|
145
|
+
const [duration, setDuration] = useState("10s");
|
|
146
|
+
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (intrinsicDurationMs) {
|
|
149
|
+
setDuration(`${intrinsicDurationMs}ms`);
|
|
150
|
+
}
|
|
151
|
+
}, [intrinsicDurationMs]);
|
|
152
|
+
|
|
153
|
+
if (loading) {
|
|
154
|
+
return <div className="text-white">Loading video...</div>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Timegroup mode="fixed" duration={duration} className="absolute w-full h-full">
|
|
159
|
+
<Video
|
|
160
|
+
ref={videoRef}
|
|
161
|
+
src="/assets/video.mp4"
|
|
162
|
+
className="size-full object-cover"
|
|
163
|
+
/>
|
|
164
|
+
</Timegroup>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Loading States
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { useRef } from "react";
|
|
173
|
+
import { Video, useMediaInfo } from "@editframe/react";
|
|
174
|
+
|
|
175
|
+
const VideoWithLoadingState = () => {
|
|
176
|
+
const videoRef = useRef(null);
|
|
177
|
+
const { intrinsicDurationMs, loading } = useMediaInfo(videoRef);
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div className="relative w-full h-full">
|
|
181
|
+
<Video
|
|
182
|
+
ref={videoRef}
|
|
183
|
+
src="/assets/large-video.mp4"
|
|
184
|
+
className="size-full object-cover"
|
|
185
|
+
/>
|
|
186
|
+
|
|
187
|
+
{loading && (
|
|
188
|
+
<div className="absolute inset-0 flex items-center justify-center bg-black/50">
|
|
189
|
+
<div className="text-white text-xl">
|
|
190
|
+
Loading video metadata...
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
)}
|
|
194
|
+
|
|
195
|
+
{!loading && !intrinsicDurationMs && (
|
|
196
|
+
<div className="absolute inset-0 flex items-center justify-center bg-red-500/50">
|
|
197
|
+
<div className="text-white text-xl">
|
|
198
|
+
Failed to load video
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Progress Indicator
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
import { useRef } from "react";
|
|
211
|
+
import { Video, useMediaInfo, useTimingInfo } from "@editframe/react";
|
|
212
|
+
|
|
213
|
+
const VideoWithProgress = () => {
|
|
214
|
+
const videoRef = useRef(null);
|
|
215
|
+
const { ref: timegroupRef, ownCurrentTimeMs } = useTimingInfo();
|
|
216
|
+
const { intrinsicDurationMs } = useMediaInfo(videoRef);
|
|
217
|
+
|
|
218
|
+
const progress = intrinsicDurationMs
|
|
219
|
+
? (ownCurrentTimeMs / intrinsicDurationMs) * 100
|
|
220
|
+
: 0;
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<div ref={timegroupRef} className="relative w-full h-full">
|
|
224
|
+
<Video
|
|
225
|
+
ref={videoRef}
|
|
226
|
+
src="/assets/video.mp4"
|
|
227
|
+
className="size-full object-cover"
|
|
228
|
+
/>
|
|
229
|
+
|
|
230
|
+
<div className="absolute bottom-0 left-0 right-0 h-1 bg-gray-700">
|
|
231
|
+
<div
|
|
232
|
+
className="h-full bg-blue-500 transition-all"
|
|
233
|
+
style={{ width: `${progress}%` }}
|
|
234
|
+
/>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Multiple Videos
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { useRef } from "react";
|
|
245
|
+
import { Video, useMediaInfo } from "@editframe/react";
|
|
246
|
+
|
|
247
|
+
const MultiVideoInfo = () => {
|
|
248
|
+
const video1Ref = useRef(null);
|
|
249
|
+
const video2Ref = useRef(null);
|
|
250
|
+
|
|
251
|
+
const video1Info = useMediaInfo(video1Ref);
|
|
252
|
+
const video2Info = useMediaInfo(video2Ref);
|
|
253
|
+
|
|
254
|
+
const totalDuration =
|
|
255
|
+
(video1Info.intrinsicDurationMs || 0) +
|
|
256
|
+
(video2Info.intrinsicDurationMs || 0);
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<>
|
|
260
|
+
<Video ref={video1Ref} src="/assets/clip1.mp4" className="size-full" />
|
|
261
|
+
<Video ref={video2Ref} src="/assets/clip2.mp4" className="size-full" />
|
|
262
|
+
|
|
263
|
+
<div className="absolute top-4 left-4 bg-black/70 text-white px-3 py-2 rounded">
|
|
264
|
+
<div>Clip 1: {((video1Info.intrinsicDurationMs || 0) / 1000).toFixed(1)}s</div>
|
|
265
|
+
<div>Clip 2: {((video2Info.intrinsicDurationMs || 0) / 1000).toFixed(1)}s</div>
|
|
266
|
+
<div className="border-t border-white/30 mt-1 pt-1">
|
|
267
|
+
Total: {(totalDuration / 1000).toFixed(1)}s
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</>
|
|
271
|
+
);
|
|
272
|
+
};
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Conditional Rendering
|
|
276
|
+
|
|
277
|
+
Only show content when media is loaded:
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { useRef } from "react";
|
|
281
|
+
import { Timegroup, Video, Text, useMediaInfo } from "@editframe/react";
|
|
282
|
+
|
|
283
|
+
const ConditionalScene = () => {
|
|
284
|
+
const videoRef = useRef(null);
|
|
285
|
+
const { loading } = useMediaInfo(videoRef);
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
<Timegroup mode="contain" className="absolute w-full h-full">
|
|
289
|
+
<Video
|
|
290
|
+
ref={videoRef}
|
|
291
|
+
src="/assets/video.mp4"
|
|
292
|
+
className="size-full object-cover"
|
|
293
|
+
/>
|
|
294
|
+
|
|
295
|
+
{!loading && (
|
|
296
|
+
<Text
|
|
297
|
+
duration="5s"
|
|
298
|
+
className="absolute top-8 left-8 text-white text-3xl"
|
|
299
|
+
>
|
|
300
|
+
Video Title
|
|
301
|
+
</Text>
|
|
302
|
+
)}
|
|
303
|
+
</Timegroup>
|
|
304
|
+
);
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Error Handling
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
import { useRef, useEffect, useState } from "react";
|
|
312
|
+
import { Video, useMediaInfo } from "@editframe/react";
|
|
313
|
+
|
|
314
|
+
const VideoWithErrorHandling = () => {
|
|
315
|
+
const videoRef = useRef(null);
|
|
316
|
+
const { intrinsicDurationMs, loading } = useMediaInfo(videoRef);
|
|
317
|
+
const [error, setError] = useState(false);
|
|
318
|
+
|
|
319
|
+
useEffect(() => {
|
|
320
|
+
// If still loading after 10 seconds, consider it an error
|
|
321
|
+
if (loading) {
|
|
322
|
+
const timeout = setTimeout(() => {
|
|
323
|
+
if (loading && !intrinsicDurationMs) {
|
|
324
|
+
setError(true);
|
|
325
|
+
}
|
|
326
|
+
}, 10000);
|
|
327
|
+
|
|
328
|
+
return () => clearTimeout(timeout);
|
|
329
|
+
}
|
|
330
|
+
}, [loading, intrinsicDurationMs]);
|
|
331
|
+
|
|
332
|
+
if (error) {
|
|
333
|
+
return (
|
|
334
|
+
<div className="flex items-center justify-center w-full h-full bg-red-500 text-white">
|
|
335
|
+
Failed to load video
|
|
336
|
+
</div>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return (
|
|
341
|
+
<Video
|
|
342
|
+
ref={videoRef}
|
|
343
|
+
src="/assets/video.mp4"
|
|
344
|
+
className="size-full object-cover"
|
|
345
|
+
/>
|
|
346
|
+
);
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Notes
|
|
351
|
+
|
|
352
|
+
- The ref must point to a Video or Audio component from `@editframe/react`
|
|
353
|
+
- `intrinsicDurationMs` is `undefined` until metadata loads
|
|
354
|
+
- `loading` is `true` while media metadata is being fetched
|
|
355
|
+
- Updates automatically when the media source changes
|
|
356
|
+
- Duration is in milliseconds for consistency with other timing APIs
|
|
357
|
+
- Works with both local and remote media files
|