@codellyson/framely 0.1.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/dist/AbsoluteFill.d.ts +18 -0
- package/dist/AbsoluteFill.d.ts.map +1 -0
- package/dist/AbsoluteFill.js +25 -0
- package/dist/AbsoluteFill.js.map +1 -0
- package/dist/Audio.d.ts +80 -0
- package/dist/Audio.d.ts.map +1 -0
- package/dist/Audio.js +221 -0
- package/dist/Audio.js.map +1 -0
- package/dist/Composition.d.ts +208 -0
- package/dist/Composition.d.ts.map +1 -0
- package/dist/Composition.js +210 -0
- package/dist/Composition.js.map +1 -0
- package/dist/Easing.d.ts +88 -0
- package/dist/Easing.d.ts.map +1 -0
- package/dist/Easing.js +266 -0
- package/dist/Easing.js.map +1 -0
- package/dist/ErrorBoundary.d.ts +35 -0
- package/dist/ErrorBoundary.d.ts.map +1 -0
- package/dist/ErrorBoundary.js +74 -0
- package/dist/ErrorBoundary.js.map +1 -0
- package/dist/Folder.d.ts +46 -0
- package/dist/Folder.d.ts.map +1 -0
- package/dist/Folder.js +44 -0
- package/dist/Folder.js.map +1 -0
- package/dist/Freeze.d.ts +35 -0
- package/dist/Freeze.d.ts.map +1 -0
- package/dist/Freeze.js +40 -0
- package/dist/Freeze.js.map +1 -0
- package/dist/IFrame.d.ts +28 -0
- package/dist/IFrame.d.ts.map +1 -0
- package/dist/IFrame.js +57 -0
- package/dist/IFrame.js.map +1 -0
- package/dist/Img.d.ts +36 -0
- package/dist/Img.d.ts.map +1 -0
- package/dist/Img.js +91 -0
- package/dist/Img.js.map +1 -0
- package/dist/Loop.d.ts +66 -0
- package/dist/Loop.d.ts.map +1 -0
- package/dist/Loop.js +79 -0
- package/dist/Loop.js.map +1 -0
- package/dist/Player.d.ts +118 -0
- package/dist/Player.d.ts.map +1 -0
- package/dist/Player.js +311 -0
- package/dist/Player.js.map +1 -0
- package/dist/Sequence.d.ts +25 -0
- package/dist/Sequence.d.ts.map +1 -0
- package/dist/Sequence.js +37 -0
- package/dist/Sequence.js.map +1 -0
- package/dist/Series.d.ts +52 -0
- package/dist/Series.d.ts.map +1 -0
- package/dist/Series.js +86 -0
- package/dist/Series.js.map +1 -0
- package/dist/Text.d.ts +129 -0
- package/dist/Text.d.ts.map +1 -0
- package/dist/Text.js +211 -0
- package/dist/Text.js.map +1 -0
- package/dist/Video.d.ts +75 -0
- package/dist/Video.d.ts.map +1 -0
- package/dist/Video.js +136 -0
- package/dist/Video.js.map +1 -0
- package/dist/config.d.ts +128 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +243 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +84 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +131 -0
- package/dist/context.js.map +1 -0
- package/dist/delayRender.d.ts +130 -0
- package/dist/delayRender.d.ts.map +1 -0
- package/dist/delayRender.js +197 -0
- package/dist/delayRender.js.map +1 -0
- package/dist/getInputProps.d.ts +118 -0
- package/dist/getInputProps.d.ts.map +1 -0
- package/dist/getInputProps.js +181 -0
- package/dist/getInputProps.js.map +1 -0
- package/dist/hooks/useDelayRender.d.ts +52 -0
- package/dist/hooks/useDelayRender.d.ts.map +1 -0
- package/dist/hooks/useDelayRender.js +92 -0
- package/dist/hooks/useDelayRender.js.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +17 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolate.d.ts +80 -0
- package/dist/interpolate.d.ts.map +1 -0
- package/dist/interpolate.js +108 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/interpolateColors.d.ts +50 -0
- package/dist/interpolateColors.d.ts.map +1 -0
- package/dist/interpolateColors.js +300 -0
- package/dist/interpolateColors.js.map +1 -0
- package/dist/makeTransform.d.ts +98 -0
- package/dist/makeTransform.d.ts.map +1 -0
- package/dist/makeTransform.js +287 -0
- package/dist/makeTransform.js.map +1 -0
- package/dist/measureSpring.d.ts +75 -0
- package/dist/measureSpring.d.ts.map +1 -0
- package/dist/measureSpring.js +108 -0
- package/dist/measureSpring.js.map +1 -0
- package/dist/noise.d.ts +110 -0
- package/dist/noise.d.ts.map +1 -0
- package/dist/noise.js +228 -0
- package/dist/noise.js.map +1 -0
- package/dist/preload.d.ts +145 -0
- package/dist/preload.d.ts.map +1 -0
- package/dist/preload.js +225 -0
- package/dist/preload.js.map +1 -0
- package/dist/registerRoot.d.ts +140 -0
- package/dist/registerRoot.d.ts.map +1 -0
- package/dist/registerRoot.js +238 -0
- package/dist/registerRoot.js.map +1 -0
- package/dist/shapes/Circle.d.ts +15 -0
- package/dist/shapes/Circle.d.ts.map +1 -0
- package/dist/shapes/Circle.js +11 -0
- package/dist/shapes/Circle.js.map +1 -0
- package/dist/shapes/Ellipse.d.ts +16 -0
- package/dist/shapes/Ellipse.d.ts.map +1 -0
- package/dist/shapes/Ellipse.js +11 -0
- package/dist/shapes/Ellipse.js.map +1 -0
- package/dist/shapes/Line.d.ts +15 -0
- package/dist/shapes/Line.d.ts.map +1 -0
- package/dist/shapes/Line.js +11 -0
- package/dist/shapes/Line.js.map +1 -0
- package/dist/shapes/Path.d.ts +20 -0
- package/dist/shapes/Path.d.ts.map +1 -0
- package/dist/shapes/Path.js +14 -0
- package/dist/shapes/Path.js.map +1 -0
- package/dist/shapes/Polygon.d.ts +15 -0
- package/dist/shapes/Polygon.d.ts.map +1 -0
- package/dist/shapes/Polygon.js +16 -0
- package/dist/shapes/Polygon.js.map +1 -0
- package/dist/shapes/Rect.d.ts +18 -0
- package/dist/shapes/Rect.d.ts.map +1 -0
- package/dist/shapes/Rect.js +11 -0
- package/dist/shapes/Rect.js.map +1 -0
- package/dist/shapes/Svg.d.ts +16 -0
- package/dist/shapes/Svg.d.ts.map +1 -0
- package/dist/shapes/Svg.js +15 -0
- package/dist/shapes/Svg.js.map +1 -0
- package/dist/shapes/index.d.ts +16 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +9 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/usePathLength.d.ts +24 -0
- package/dist/shapes/usePathLength.d.ts.map +1 -0
- package/dist/shapes/usePathLength.js +32 -0
- package/dist/shapes/usePathLength.js.map +1 -0
- package/dist/staticFile.d.ts +47 -0
- package/dist/staticFile.d.ts.map +1 -0
- package/dist/staticFile.js +105 -0
- package/dist/staticFile.js.map +1 -0
- package/dist/templates/api.d.ts +26 -0
- package/dist/templates/api.d.ts.map +1 -0
- package/dist/templates/api.js +142 -0
- package/dist/templates/api.js.map +1 -0
- package/dist/templates/index.d.ts +7 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +7 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/mockData.d.ts +7 -0
- package/dist/templates/mockData.d.ts.map +1 -0
- package/dist/templates/mockData.js +262 -0
- package/dist/templates/mockData.js.map +1 -0
- package/dist/templates/types.d.ts +104 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/templates/types.js +16 -0
- package/dist/templates/types.js.map +1 -0
- package/dist/transitions/TransitionSeries.d.ts +127 -0
- package/dist/transitions/TransitionSeries.d.ts.map +1 -0
- package/dist/transitions/TransitionSeries.js +190 -0
- package/dist/transitions/TransitionSeries.js.map +1 -0
- package/dist/transitions/index.d.ts +52 -0
- package/dist/transitions/index.d.ts.map +1 -0
- package/dist/transitions/index.js +31 -0
- package/dist/transitions/index.js.map +1 -0
- package/dist/transitions/presets/fade.d.ts +45 -0
- package/dist/transitions/presets/fade.d.ts.map +1 -0
- package/dist/transitions/presets/fade.js +56 -0
- package/dist/transitions/presets/fade.js.map +1 -0
- package/dist/transitions/presets/flip.d.ts +99 -0
- package/dist/transitions/presets/flip.d.ts.map +1 -0
- package/dist/transitions/presets/flip.js +153 -0
- package/dist/transitions/presets/flip.js.map +1 -0
- package/dist/transitions/presets/slide.d.ts +61 -0
- package/dist/transitions/presets/slide.d.ts.map +1 -0
- package/dist/transitions/presets/slide.js +116 -0
- package/dist/transitions/presets/slide.js.map +1 -0
- package/dist/transitions/presets/wipe.d.ts +69 -0
- package/dist/transitions/presets/wipe.d.ts.map +1 -0
- package/dist/transitions/presets/wipe.js +136 -0
- package/dist/transitions/presets/wipe.js.map +1 -0
- package/dist/transitions/presets/zoom.d.ts +76 -0
- package/dist/transitions/presets/zoom.d.ts.map +1 -0
- package/dist/transitions/presets/zoom.js +110 -0
- package/dist/transitions/presets/zoom.js.map +1 -0
- package/dist/useAudioData.d.ts +112 -0
- package/dist/useAudioData.d.ts.map +1 -0
- package/dist/useAudioData.js +183 -0
- package/dist/useAudioData.js.map +1 -0
- package/dist/useSpring.d.ts +79 -0
- package/dist/useSpring.d.ts.map +1 -0
- package/dist/useSpring.js +140 -0
- package/dist/useSpring.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the AbsoluteFill component.
|
|
4
|
+
* Extends standard HTML div attributes so callers can pass
|
|
5
|
+
* any valid div prop (className, onClick, aria-*, etc.).
|
|
6
|
+
*/
|
|
7
|
+
export interface AbsoluteFillProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
/** Optional inline styles merged on top of the base layout styles. */
|
|
9
|
+
style?: React.CSSProperties;
|
|
10
|
+
/** Content rendered inside the absolutely-positioned container. */
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A full-size, absolutely positioned container.
|
|
15
|
+
* The building block for layering elements in a composition.
|
|
16
|
+
*/
|
|
17
|
+
export declare const AbsoluteFill: React.ForwardRefExoticComponent<AbsoluteFillProps & React.RefAttributes<HTMLDivElement>>;
|
|
18
|
+
//# sourceMappingURL=AbsoluteFill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbsoluteFill.d.ts","sourceRoot":"","sources":["../src/AbsoluteFill.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,iBACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5C,sEAAsE;IACtE,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAcD;;;GAGG;AACH,eAAO,MAAM,YAAY,0FAgBvB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
const absoluteFillStyle = {
|
|
4
|
+
position: 'absolute',
|
|
5
|
+
top: 0,
|
|
6
|
+
left: 0,
|
|
7
|
+
right: 0,
|
|
8
|
+
bottom: 0,
|
|
9
|
+
display: 'flex',
|
|
10
|
+
flexDirection: 'column',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A full-size, absolutely positioned container.
|
|
16
|
+
* The building block for layering elements in a composition.
|
|
17
|
+
*/
|
|
18
|
+
export const AbsoluteFill = React.forwardRef(({ style, children, ...props }, ref) => {
|
|
19
|
+
return (_jsx("div", { ref: ref, style: {
|
|
20
|
+
...absoluteFillStyle,
|
|
21
|
+
...style,
|
|
22
|
+
}, ...props, children: children }));
|
|
23
|
+
});
|
|
24
|
+
AbsoluteFill.displayName = 'AbsoluteFill';
|
|
25
|
+
//# sourceMappingURL=AbsoluteFill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbsoluteFill.js","sourceRoot":"","sources":["../src/AbsoluteFill.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B,MAAM,iBAAiB,GAAwB;IAC7C,QAAQ,EAAE,UAAU;IACpB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,MAAM;IACf,aAAa,EAAE,QAAQ;IACvB,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,QAAQ;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAG1C,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IACvC,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,KAAK,EAAE;YACL,GAAG,iBAAiB;YACpB,GAAG,KAAK;SACT,KACG,KAAK,YAER,QAAQ,GACL,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,YAAY,CAAC,WAAW,GAAG,cAAc,CAAC"}
|
package/dist/Audio.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Volume can be a static number (0–1) or a function that receives
|
|
3
|
+
* the current frame and returns a number (0–1).
|
|
4
|
+
*/
|
|
5
|
+
export type VolumeCallback = (frame: number) => number;
|
|
6
|
+
/**
|
|
7
|
+
* Props accepted by the Audio component.
|
|
8
|
+
*
|
|
9
|
+
* Extends standard HTML audio attributes so callers can pass any
|
|
10
|
+
* native audio prop (e.g. `crossOrigin`, `id`, `className`), but
|
|
11
|
+
* the component itself only uses the subset listed here.
|
|
12
|
+
*/
|
|
13
|
+
export interface AudioProps extends Omit<React.AudioHTMLAttributes<HTMLAudioElement>, 'volume' | 'onError'> {
|
|
14
|
+
/** Audio source URL (use staticFile() for local assets). */
|
|
15
|
+
src: string;
|
|
16
|
+
/** Volume level 0–1, or a callback `(frame) => number`. */
|
|
17
|
+
volume?: number | VolumeCallback;
|
|
18
|
+
/** Playback speed multiplier. @default 1 */
|
|
19
|
+
playbackRate?: number;
|
|
20
|
+
/** Whether to mute audio. @default false */
|
|
21
|
+
muted?: boolean;
|
|
22
|
+
/** Loop the audio. @default false */
|
|
23
|
+
loop?: boolean;
|
|
24
|
+
/** Frame to start playing from. @default 0 */
|
|
25
|
+
startFrom?: number;
|
|
26
|
+
/** Frame to stop playing at (exclusive). */
|
|
27
|
+
endAt?: number;
|
|
28
|
+
/** Callback when audio fails to load. */
|
|
29
|
+
onError?: (error: Error) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Metadata returned by {@link getAudioMetadata}.
|
|
33
|
+
*/
|
|
34
|
+
export interface AudioMetadata {
|
|
35
|
+
/** Duration of the audio in seconds. */
|
|
36
|
+
duration: number;
|
|
37
|
+
/**
|
|
38
|
+
* Sample rate of the audio.
|
|
39
|
+
* `null` when using the HTMLAudioElement API (Web Audio API
|
|
40
|
+
* would be needed for an accurate value).
|
|
41
|
+
*/
|
|
42
|
+
sampleRate: number | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Audio component that syncs with the Framely timeline.
|
|
46
|
+
*
|
|
47
|
+
* The audio's playback position is controlled by the current frame,
|
|
48
|
+
* ensuring perfect sync between audio and your composition.
|
|
49
|
+
*
|
|
50
|
+
* Note: During rendering, audio is handled separately by the backend
|
|
51
|
+
* (FFmpeg muxing). This component is primarily for preview playback.
|
|
52
|
+
*
|
|
53
|
+
* Usage:
|
|
54
|
+
* import { Audio, staticFile } from './lib';
|
|
55
|
+
*
|
|
56
|
+
* <Audio src={staticFile('audio/background.mp3')} />
|
|
57
|
+
* <Audio src={staticFile('audio/sfx.wav')} volume={0.8} />
|
|
58
|
+
* <Audio
|
|
59
|
+
* src={staticFile('audio/voiceover.mp3')}
|
|
60
|
+
* volume={(frame) => interpolate(frame, [0, 30], [0, 1])}
|
|
61
|
+
* />
|
|
62
|
+
*/
|
|
63
|
+
export declare function Audio({ src, volume, playbackRate, muted, loop, startFrom, endAt, onError, }: AudioProps): null;
|
|
64
|
+
/**
|
|
65
|
+
* Get audio metadata from a source.
|
|
66
|
+
*
|
|
67
|
+
* @param src - Audio URL
|
|
68
|
+
* @returns A promise that resolves with duration and sampleRate info
|
|
69
|
+
*/
|
|
70
|
+
export declare function getAudioMetadata(src: string): Promise<AudioMetadata>;
|
|
71
|
+
/**
|
|
72
|
+
* Calculate the duration in frames for an audio file.
|
|
73
|
+
*
|
|
74
|
+
* @param src - Audio URL
|
|
75
|
+
* @param fps - Frames per second
|
|
76
|
+
* @returns Duration in frames (rounded up)
|
|
77
|
+
*/
|
|
78
|
+
export declare function getAudioDurationInFrames(src: string, fps: number): Promise<number>;
|
|
79
|
+
export default Audio;
|
|
80
|
+
//# sourceMappingURL=Audio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Audio.d.ts","sourceRoot":"","sources":["../src/Audio.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,WAAW,UACf,SAAQ,IAAI,CACV,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,QAAQ,GAAG,SAAS,CACrB;IACD,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;IACjC,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,EACpB,GAAG,EACH,MAAU,EACV,YAAgB,EAChB,KAAa,EACb,IAAY,EACZ,SAAa,EACb,KAAK,EACL,OAAO,GACR,EAAE,UAAU,GAAG,IAAI,CAwKnB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAkB1E;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED,eAAe,KAAK,CAAC"}
|
package/dist/Audio.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { useEffect, useRef, useState, useMemo } from 'react';
|
|
2
|
+
import { useTimeline } from './context';
|
|
3
|
+
import { delayRender, continueRender, cancelRender } from './delayRender';
|
|
4
|
+
/**
|
|
5
|
+
* Audio component that syncs with the Framely timeline.
|
|
6
|
+
*
|
|
7
|
+
* The audio's playback position is controlled by the current frame,
|
|
8
|
+
* ensuring perfect sync between audio and your composition.
|
|
9
|
+
*
|
|
10
|
+
* Note: During rendering, audio is handled separately by the backend
|
|
11
|
+
* (FFmpeg muxing). This component is primarily for preview playback.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* import { Audio, staticFile } from './lib';
|
|
15
|
+
*
|
|
16
|
+
* <Audio src={staticFile('audio/background.mp3')} />
|
|
17
|
+
* <Audio src={staticFile('audio/sfx.wav')} volume={0.8} />
|
|
18
|
+
* <Audio
|
|
19
|
+
* src={staticFile('audio/voiceover.mp3')}
|
|
20
|
+
* volume={(frame) => interpolate(frame, [0, 30], [0, 1])}
|
|
21
|
+
* />
|
|
22
|
+
*/
|
|
23
|
+
export function Audio({ src, volume = 1, playbackRate = 1, muted = false, loop = false, startFrom = 0, endAt, onError, }) {
|
|
24
|
+
const { frame, fps, playing, renderMode } = useTimeline();
|
|
25
|
+
const audioRef = useRef(null);
|
|
26
|
+
const handleRef = useRef(null);
|
|
27
|
+
const [ready, setReady] = useState(false);
|
|
28
|
+
// Calculate the actual volume (support callback)
|
|
29
|
+
const actualVolume = useMemo(() => {
|
|
30
|
+
if (typeof volume === 'function') {
|
|
31
|
+
return Math.max(0, Math.min(1, volume(frame)));
|
|
32
|
+
}
|
|
33
|
+
return Math.max(0, Math.min(1, volume));
|
|
34
|
+
}, [volume, frame]);
|
|
35
|
+
// In render mode, register audio track metadata for FFmpeg mixing
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!renderMode)
|
|
38
|
+
return;
|
|
39
|
+
const trackInfo = {
|
|
40
|
+
src,
|
|
41
|
+
startFrame: startFrom,
|
|
42
|
+
volume: typeof volume === 'number' ? volume : 1,
|
|
43
|
+
};
|
|
44
|
+
if (!window.__FRAMELY_AUDIO_TRACKS) {
|
|
45
|
+
window.__FRAMELY_AUDIO_TRACKS = [];
|
|
46
|
+
}
|
|
47
|
+
window.__FRAMELY_AUDIO_TRACKS.push(trackInfo);
|
|
48
|
+
return () => {
|
|
49
|
+
if (window.__FRAMELY_AUDIO_TRACKS) {
|
|
50
|
+
const idx = window.__FRAMELY_AUDIO_TRACKS.indexOf(trackInfo);
|
|
51
|
+
if (idx !== -1) {
|
|
52
|
+
window.__FRAMELY_AUDIO_TRACKS.splice(idx, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}, [renderMode, src, startFrom, volume]);
|
|
57
|
+
// Calculate target time based on frame
|
|
58
|
+
const targetTime = useMemo(() => {
|
|
59
|
+
const relativeFrame = frame - startFrom;
|
|
60
|
+
if (relativeFrame < 0)
|
|
61
|
+
return 0;
|
|
62
|
+
return relativeFrame / fps;
|
|
63
|
+
}, [frame, startFrom, fps]);
|
|
64
|
+
// Check if we're within the audio's active range
|
|
65
|
+
const isActive = useMemo(() => {
|
|
66
|
+
if (frame < startFrom)
|
|
67
|
+
return false;
|
|
68
|
+
if (endAt !== undefined && frame >= endAt)
|
|
69
|
+
return false;
|
|
70
|
+
return true;
|
|
71
|
+
}, [frame, startFrom, endAt]);
|
|
72
|
+
// Delay render until audio is ready (skip in render mode)
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (renderMode)
|
|
75
|
+
return;
|
|
76
|
+
handleRef.current = delayRender(`Loading audio: ${src}`, {
|
|
77
|
+
timeoutInMilliseconds: 30000,
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
if (handleRef.current !== null) {
|
|
81
|
+
continueRender(handleRef.current);
|
|
82
|
+
handleRef.current = null;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}, [src, renderMode]);
|
|
86
|
+
// Create audio element (skip in render mode — audio is handled by FFmpeg)
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (renderMode)
|
|
89
|
+
return;
|
|
90
|
+
const audio = new window.Audio();
|
|
91
|
+
audio.preload = 'auto';
|
|
92
|
+
audio.src = src;
|
|
93
|
+
audioRef.current = audio;
|
|
94
|
+
const handleCanPlay = () => {
|
|
95
|
+
setReady(true);
|
|
96
|
+
if (handleRef.current !== null) {
|
|
97
|
+
continueRender(handleRef.current);
|
|
98
|
+
handleRef.current = null;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const handleError = () => {
|
|
102
|
+
const err = new Error(`Failed to load audio: ${src}`);
|
|
103
|
+
onError?.(err);
|
|
104
|
+
if (handleRef.current !== null) {
|
|
105
|
+
cancelRender(err);
|
|
106
|
+
handleRef.current = null;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
audio.addEventListener('canplaythrough', handleCanPlay);
|
|
110
|
+
audio.addEventListener('error', handleError);
|
|
111
|
+
return () => {
|
|
112
|
+
audio.removeEventListener('canplaythrough', handleCanPlay);
|
|
113
|
+
audio.removeEventListener('error', handleError);
|
|
114
|
+
audio.pause();
|
|
115
|
+
audio.src = '';
|
|
116
|
+
audioRef.current = null;
|
|
117
|
+
};
|
|
118
|
+
}, [src, onError, renderMode]);
|
|
119
|
+
// Sync audio time with frame
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (renderMode)
|
|
122
|
+
return;
|
|
123
|
+
const audio = audioRef.current;
|
|
124
|
+
if (!audio || !ready)
|
|
125
|
+
return;
|
|
126
|
+
// Only seek if we're more than half a frame off
|
|
127
|
+
const tolerance = 0.5 / fps;
|
|
128
|
+
if (Math.abs(audio.currentTime - targetTime) > tolerance) {
|
|
129
|
+
audio.currentTime = targetTime;
|
|
130
|
+
}
|
|
131
|
+
}, [targetTime, ready, fps, renderMode]);
|
|
132
|
+
// Sync volume
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (renderMode)
|
|
135
|
+
return;
|
|
136
|
+
const audio = audioRef.current;
|
|
137
|
+
if (!audio)
|
|
138
|
+
return;
|
|
139
|
+
audio.volume = actualVolume;
|
|
140
|
+
}, [actualVolume, renderMode]);
|
|
141
|
+
// Sync playback rate
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (renderMode)
|
|
144
|
+
return;
|
|
145
|
+
const audio = audioRef.current;
|
|
146
|
+
if (!audio)
|
|
147
|
+
return;
|
|
148
|
+
audio.playbackRate = playbackRate;
|
|
149
|
+
}, [playbackRate, renderMode]);
|
|
150
|
+
// Sync muted state
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (renderMode)
|
|
153
|
+
return;
|
|
154
|
+
const audio = audioRef.current;
|
|
155
|
+
if (!audio)
|
|
156
|
+
return;
|
|
157
|
+
audio.muted = muted;
|
|
158
|
+
}, [muted, renderMode]);
|
|
159
|
+
// Sync loop state
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (renderMode)
|
|
162
|
+
return;
|
|
163
|
+
const audio = audioRef.current;
|
|
164
|
+
if (!audio)
|
|
165
|
+
return;
|
|
166
|
+
audio.loop = loop;
|
|
167
|
+
}, [loop, renderMode]);
|
|
168
|
+
// Handle play/pause (for preview mode)
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
if (renderMode)
|
|
171
|
+
return;
|
|
172
|
+
const audio = audioRef.current;
|
|
173
|
+
if (!audio || !ready)
|
|
174
|
+
return;
|
|
175
|
+
if (playing && isActive) {
|
|
176
|
+
audio.play().catch(() => {
|
|
177
|
+
// Autoplay might be blocked, that's okay
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
audio.pause();
|
|
182
|
+
}
|
|
183
|
+
}, [playing, ready, isActive, renderMode]);
|
|
184
|
+
// Audio doesn't render anything visible
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get audio metadata from a source.
|
|
189
|
+
*
|
|
190
|
+
* @param src - Audio URL
|
|
191
|
+
* @returns A promise that resolves with duration and sampleRate info
|
|
192
|
+
*/
|
|
193
|
+
export async function getAudioMetadata(src) {
|
|
194
|
+
return new Promise((resolve, reject) => {
|
|
195
|
+
const audio = new window.Audio();
|
|
196
|
+
audio.addEventListener('loadedmetadata', () => {
|
|
197
|
+
resolve({
|
|
198
|
+
duration: audio.duration,
|
|
199
|
+
// Note: Web Audio API would be needed for sampleRate
|
|
200
|
+
sampleRate: null,
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
audio.addEventListener('error', () => {
|
|
204
|
+
reject(new Error(`Failed to load audio metadata: ${src}`));
|
|
205
|
+
});
|
|
206
|
+
audio.src = src;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Calculate the duration in frames for an audio file.
|
|
211
|
+
*
|
|
212
|
+
* @param src - Audio URL
|
|
213
|
+
* @param fps - Frames per second
|
|
214
|
+
* @returns Duration in frames (rounded up)
|
|
215
|
+
*/
|
|
216
|
+
export async function getAudioDurationInFrames(src, fps) {
|
|
217
|
+
const metadata = await getAudioMetadata(src);
|
|
218
|
+
return Math.ceil(metadata.duration * fps);
|
|
219
|
+
}
|
|
220
|
+
export default Audio;
|
|
221
|
+
//# sourceMappingURL=Audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Audio.js","sourceRoot":"","sources":["../src/Audio.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { type ComponentType, type LazyExoticComponent, type ReactElement } from 'react';
|
|
2
|
+
import type { ZodType } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Supported codecs for rendering output.
|
|
5
|
+
*/
|
|
6
|
+
export type Codec = 'h264' | 'h265' | 'vp8' | 'vp9' | 'mp3' | 'aac' | 'wav' | 'prores' | 'gif';
|
|
7
|
+
/**
|
|
8
|
+
* Schema interface supporting Zod-style and generic validate-style schemas.
|
|
9
|
+
*/
|
|
10
|
+
export interface CompositionSchema<T = Record<string, unknown>> {
|
|
11
|
+
safeParse?: (data: unknown) => {
|
|
12
|
+
success: boolean;
|
|
13
|
+
data?: T;
|
|
14
|
+
error?: unknown;
|
|
15
|
+
};
|
|
16
|
+
parse?: (data: unknown) => T;
|
|
17
|
+
validate?: (data: unknown) => T;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Input provided to a calculateMetadata function.
|
|
21
|
+
*/
|
|
22
|
+
export interface CalculateMetadataInput<T extends Record<string, unknown>> {
|
|
23
|
+
defaultProps: T;
|
|
24
|
+
props: T;
|
|
25
|
+
abortSignal: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Output returned from a calculateMetadata function.
|
|
29
|
+
*/
|
|
30
|
+
export interface CalculateMetadataOutput<T extends Record<string, unknown>> {
|
|
31
|
+
props?: Partial<T>;
|
|
32
|
+
durationInFrames?: number;
|
|
33
|
+
width?: number;
|
|
34
|
+
height?: number;
|
|
35
|
+
fps?: number;
|
|
36
|
+
defaultCodec?: Codec;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Callback type for dynamically computing composition metadata.
|
|
40
|
+
*/
|
|
41
|
+
export type CalculateMetadataFunction<T extends Record<string, unknown>> = (input: CalculateMetadataInput<T>) => Promise<CalculateMetadataOutput<T>>;
|
|
42
|
+
/**
|
|
43
|
+
* Props accepted by the Composition component.
|
|
44
|
+
*
|
|
45
|
+
* @template T - The shape of props passed to the rendered component.
|
|
46
|
+
*/
|
|
47
|
+
export interface CompositionProps<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
48
|
+
/** Unique identifier for the composition. */
|
|
49
|
+
id: string;
|
|
50
|
+
/** React component to render. Mutually exclusive with lazyComponent. */
|
|
51
|
+
component?: ComponentType<T>;
|
|
52
|
+
/** Async function returning a module with a component (for code-splitting). */
|
|
53
|
+
lazyComponent?: () => Promise<{
|
|
54
|
+
default: ComponentType<T>;
|
|
55
|
+
} | ComponentType<T>>;
|
|
56
|
+
/** Video width in pixels. @default 1920 */
|
|
57
|
+
width?: number;
|
|
58
|
+
/** Video height in pixels. @default 1080 */
|
|
59
|
+
height?: number;
|
|
60
|
+
/** Frames per second. @default 30 */
|
|
61
|
+
fps?: number;
|
|
62
|
+
/** Total number of frames. @default 300 */
|
|
63
|
+
durationInFrames?: number;
|
|
64
|
+
/** Default props passed to the component. @default {} */
|
|
65
|
+
defaultProps?: T;
|
|
66
|
+
/** Async function to dynamically compute metadata before rendering. */
|
|
67
|
+
calculateMetadata?: CalculateMetadataFunction<T>;
|
|
68
|
+
/** Zod schema (or compatible) for prop validation and visual editing. */
|
|
69
|
+
schema?: ZodType<T> | CompositionSchema<T>;
|
|
70
|
+
/** Default codec used when rendering this composition. */
|
|
71
|
+
defaultCodec?: Codec;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolved composition configuration stored in the registry.
|
|
75
|
+
*/
|
|
76
|
+
export interface CompositionConfig<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
77
|
+
id: string;
|
|
78
|
+
component?: ComponentType<T>;
|
|
79
|
+
lazyComponent?: () => Promise<{
|
|
80
|
+
default: ComponentType<T>;
|
|
81
|
+
} | ComponentType<T>>;
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
fps: number;
|
|
85
|
+
durationInFrames: number;
|
|
86
|
+
defaultProps: T;
|
|
87
|
+
calculateMetadata?: CalculateMetadataFunction<T>;
|
|
88
|
+
schema?: ZodType<T> | CompositionSchema<T>;
|
|
89
|
+
defaultCodec?: Codec;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolved metadata after applying calculateMetadata.
|
|
93
|
+
*/
|
|
94
|
+
export interface ResolvedMetadata<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
95
|
+
width: number;
|
|
96
|
+
height: number;
|
|
97
|
+
fps: number;
|
|
98
|
+
durationInFrames: number;
|
|
99
|
+
props: T;
|
|
100
|
+
defaultCodec?: Codec;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Result of validating props against a composition's schema.
|
|
104
|
+
*/
|
|
105
|
+
export type ValidationResult<T = Record<string, unknown>> = {
|
|
106
|
+
success: true;
|
|
107
|
+
data: T;
|
|
108
|
+
error?: undefined;
|
|
109
|
+
} | {
|
|
110
|
+
success: false;
|
|
111
|
+
data?: undefined;
|
|
112
|
+
error: unknown;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Composition defines a video's dimensions, frame rate, and duration.
|
|
116
|
+
* It doesn't render anything itself — it's a declarative config
|
|
117
|
+
* that the Player and Renderer use to know how to handle the video.
|
|
118
|
+
*
|
|
119
|
+
* Usage:
|
|
120
|
+
* <Composition
|
|
121
|
+
* id="my-video"
|
|
122
|
+
* component={MyVideoComponent}
|
|
123
|
+
* width={1920}
|
|
124
|
+
* height={1080}
|
|
125
|
+
* fps={30}
|
|
126
|
+
* durationInFrames={300}
|
|
127
|
+
* defaultProps={{ title: "Hello" }}
|
|
128
|
+
* />
|
|
129
|
+
*
|
|
130
|
+
* // With lazy loading
|
|
131
|
+
* <Composition
|
|
132
|
+
* id="heavy-video"
|
|
133
|
+
* lazyComponent={() => import('./HeavyVideo')}
|
|
134
|
+
* ...
|
|
135
|
+
* />
|
|
136
|
+
*
|
|
137
|
+
* // With dynamic metadata
|
|
138
|
+
* <Composition
|
|
139
|
+
* id="data-video"
|
|
140
|
+
* component={DataVideo}
|
|
141
|
+
* calculateMetadata={async ({ props }) => {
|
|
142
|
+
* const data = await fetchData();
|
|
143
|
+
* return {
|
|
144
|
+
* props: { ...props, data },
|
|
145
|
+
* durationInFrames: data.length * 30,
|
|
146
|
+
* };
|
|
147
|
+
* }}
|
|
148
|
+
* ...
|
|
149
|
+
* />
|
|
150
|
+
*/
|
|
151
|
+
export declare function Composition<T extends Record<string, unknown> = Record<string, unknown>>(_props: CompositionProps<T>): ReactElement | null;
|
|
152
|
+
export declare namespace Composition {
|
|
153
|
+
var displayName: string;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Helper to define compositions as plain objects (for registry/routing).
|
|
157
|
+
*
|
|
158
|
+
* @template T - The shape of props passed to the rendered component.
|
|
159
|
+
* @param config - Composition configuration
|
|
160
|
+
* @returns Normalized composition config
|
|
161
|
+
*/
|
|
162
|
+
export declare function defineComposition<T extends Record<string, unknown> = Record<string, unknown>>(config: CompositionProps<T> & {
|
|
163
|
+
id: string;
|
|
164
|
+
}): CompositionConfig<T>;
|
|
165
|
+
/**
|
|
166
|
+
* Resolve a composition's component (handles lazy loading).
|
|
167
|
+
*
|
|
168
|
+
* @template T - The shape of props for the component.
|
|
169
|
+
* @param composition - Composition config from registry
|
|
170
|
+
* @returns The resolved component (possibly lazy-wrapped)
|
|
171
|
+
*/
|
|
172
|
+
export declare function resolveComponent<T extends Record<string, unknown>>(composition: CompositionConfig<T>): ComponentType<T> | LazyExoticComponent<ComponentType<T>>;
|
|
173
|
+
/**
|
|
174
|
+
* Resolve a composition's metadata (handles calculateMetadata).
|
|
175
|
+
*
|
|
176
|
+
* @template T - The shape of props for the component.
|
|
177
|
+
* @param composition - Composition config from registry
|
|
178
|
+
* @param inputProps - Props passed via CLI or API
|
|
179
|
+
* @returns Resolved metadata
|
|
180
|
+
*/
|
|
181
|
+
export declare function resolveMetadata<T extends Record<string, unknown>>(composition: CompositionConfig<T>, inputProps?: Partial<T>): Promise<ResolvedMetadata<T>>;
|
|
182
|
+
/**
|
|
183
|
+
* Validate props against a composition's schema.
|
|
184
|
+
*
|
|
185
|
+
* @template T - The shape of props for the component.
|
|
186
|
+
* @param composition - Composition config from registry
|
|
187
|
+
* @param props - Props to validate
|
|
188
|
+
* @returns Validation result with success status and parsed data or error
|
|
189
|
+
*/
|
|
190
|
+
export declare function validateProps<T extends Record<string, unknown>>(composition: CompositionConfig<T>, props: unknown): ValidationResult<T>;
|
|
191
|
+
/**
|
|
192
|
+
* Get the default props for a composition, considering schema defaults.
|
|
193
|
+
*
|
|
194
|
+
* @template T - The shape of props for the component.
|
|
195
|
+
* @param composition - Composition config from registry
|
|
196
|
+
* @returns Default props merged with schema defaults
|
|
197
|
+
*/
|
|
198
|
+
export declare function getDefaultProps<T extends Record<string, unknown>>(composition: CompositionConfig<T>): T;
|
|
199
|
+
/**
|
|
200
|
+
* Create a composition wrapper component that handles lazy loading.
|
|
201
|
+
*
|
|
202
|
+
* @template T - The shape of props for the component.
|
|
203
|
+
* @param composition - Composition config
|
|
204
|
+
* @returns Wrapped component with Suspense boundary
|
|
205
|
+
*/
|
|
206
|
+
export declare function createCompositionWrapper<T extends Record<string, unknown>>(composition: CompositionConfig<T>): ComponentType<T>;
|
|
207
|
+
export default Composition;
|
|
208
|
+
//# sourceMappingURL=Composition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composition.d.ts","sourceRoot":"","sources":["../src/Composition.tsx"],"names":[],"mappings":"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"}
|