@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.
Files changed (209) hide show
  1. package/dist/AbsoluteFill.d.ts +18 -0
  2. package/dist/AbsoluteFill.d.ts.map +1 -0
  3. package/dist/AbsoluteFill.js +25 -0
  4. package/dist/AbsoluteFill.js.map +1 -0
  5. package/dist/Audio.d.ts +80 -0
  6. package/dist/Audio.d.ts.map +1 -0
  7. package/dist/Audio.js +221 -0
  8. package/dist/Audio.js.map +1 -0
  9. package/dist/Composition.d.ts +208 -0
  10. package/dist/Composition.d.ts.map +1 -0
  11. package/dist/Composition.js +210 -0
  12. package/dist/Composition.js.map +1 -0
  13. package/dist/Easing.d.ts +88 -0
  14. package/dist/Easing.d.ts.map +1 -0
  15. package/dist/Easing.js +266 -0
  16. package/dist/Easing.js.map +1 -0
  17. package/dist/ErrorBoundary.d.ts +35 -0
  18. package/dist/ErrorBoundary.d.ts.map +1 -0
  19. package/dist/ErrorBoundary.js +74 -0
  20. package/dist/ErrorBoundary.js.map +1 -0
  21. package/dist/Folder.d.ts +46 -0
  22. package/dist/Folder.d.ts.map +1 -0
  23. package/dist/Folder.js +44 -0
  24. package/dist/Folder.js.map +1 -0
  25. package/dist/Freeze.d.ts +35 -0
  26. package/dist/Freeze.d.ts.map +1 -0
  27. package/dist/Freeze.js +40 -0
  28. package/dist/Freeze.js.map +1 -0
  29. package/dist/IFrame.d.ts +28 -0
  30. package/dist/IFrame.d.ts.map +1 -0
  31. package/dist/IFrame.js +57 -0
  32. package/dist/IFrame.js.map +1 -0
  33. package/dist/Img.d.ts +36 -0
  34. package/dist/Img.d.ts.map +1 -0
  35. package/dist/Img.js +91 -0
  36. package/dist/Img.js.map +1 -0
  37. package/dist/Loop.d.ts +66 -0
  38. package/dist/Loop.d.ts.map +1 -0
  39. package/dist/Loop.js +79 -0
  40. package/dist/Loop.js.map +1 -0
  41. package/dist/Player.d.ts +118 -0
  42. package/dist/Player.d.ts.map +1 -0
  43. package/dist/Player.js +311 -0
  44. package/dist/Player.js.map +1 -0
  45. package/dist/Sequence.d.ts +25 -0
  46. package/dist/Sequence.d.ts.map +1 -0
  47. package/dist/Sequence.js +37 -0
  48. package/dist/Sequence.js.map +1 -0
  49. package/dist/Series.d.ts +52 -0
  50. package/dist/Series.d.ts.map +1 -0
  51. package/dist/Series.js +86 -0
  52. package/dist/Series.js.map +1 -0
  53. package/dist/Text.d.ts +129 -0
  54. package/dist/Text.d.ts.map +1 -0
  55. package/dist/Text.js +211 -0
  56. package/dist/Text.js.map +1 -0
  57. package/dist/Video.d.ts +75 -0
  58. package/dist/Video.d.ts.map +1 -0
  59. package/dist/Video.js +136 -0
  60. package/dist/Video.js.map +1 -0
  61. package/dist/config.d.ts +128 -0
  62. package/dist/config.d.ts.map +1 -0
  63. package/dist/config.js +243 -0
  64. package/dist/config.js.map +1 -0
  65. package/dist/context.d.ts +84 -0
  66. package/dist/context.d.ts.map +1 -0
  67. package/dist/context.js +131 -0
  68. package/dist/context.js.map +1 -0
  69. package/dist/delayRender.d.ts +130 -0
  70. package/dist/delayRender.d.ts.map +1 -0
  71. package/dist/delayRender.js +197 -0
  72. package/dist/delayRender.js.map +1 -0
  73. package/dist/getInputProps.d.ts +118 -0
  74. package/dist/getInputProps.d.ts.map +1 -0
  75. package/dist/getInputProps.js +181 -0
  76. package/dist/getInputProps.js.map +1 -0
  77. package/dist/hooks/useDelayRender.d.ts +52 -0
  78. package/dist/hooks/useDelayRender.d.ts.map +1 -0
  79. package/dist/hooks/useDelayRender.js +92 -0
  80. package/dist/hooks/useDelayRender.js.map +1 -0
  81. package/dist/hooks.d.ts +19 -0
  82. package/dist/hooks.d.ts.map +1 -0
  83. package/dist/hooks.js +17 -0
  84. package/dist/hooks.js.map +1 -0
  85. package/dist/index.d.ts +71 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +65 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/interpolate.d.ts +80 -0
  90. package/dist/interpolate.d.ts.map +1 -0
  91. package/dist/interpolate.js +108 -0
  92. package/dist/interpolate.js.map +1 -0
  93. package/dist/interpolateColors.d.ts +50 -0
  94. package/dist/interpolateColors.d.ts.map +1 -0
  95. package/dist/interpolateColors.js +300 -0
  96. package/dist/interpolateColors.js.map +1 -0
  97. package/dist/makeTransform.d.ts +98 -0
  98. package/dist/makeTransform.d.ts.map +1 -0
  99. package/dist/makeTransform.js +287 -0
  100. package/dist/makeTransform.js.map +1 -0
  101. package/dist/measureSpring.d.ts +75 -0
  102. package/dist/measureSpring.d.ts.map +1 -0
  103. package/dist/measureSpring.js +108 -0
  104. package/dist/measureSpring.js.map +1 -0
  105. package/dist/noise.d.ts +110 -0
  106. package/dist/noise.d.ts.map +1 -0
  107. package/dist/noise.js +228 -0
  108. package/dist/noise.js.map +1 -0
  109. package/dist/preload.d.ts +145 -0
  110. package/dist/preload.d.ts.map +1 -0
  111. package/dist/preload.js +225 -0
  112. package/dist/preload.js.map +1 -0
  113. package/dist/registerRoot.d.ts +140 -0
  114. package/dist/registerRoot.d.ts.map +1 -0
  115. package/dist/registerRoot.js +238 -0
  116. package/dist/registerRoot.js.map +1 -0
  117. package/dist/shapes/Circle.d.ts +15 -0
  118. package/dist/shapes/Circle.d.ts.map +1 -0
  119. package/dist/shapes/Circle.js +11 -0
  120. package/dist/shapes/Circle.js.map +1 -0
  121. package/dist/shapes/Ellipse.d.ts +16 -0
  122. package/dist/shapes/Ellipse.d.ts.map +1 -0
  123. package/dist/shapes/Ellipse.js +11 -0
  124. package/dist/shapes/Ellipse.js.map +1 -0
  125. package/dist/shapes/Line.d.ts +15 -0
  126. package/dist/shapes/Line.d.ts.map +1 -0
  127. package/dist/shapes/Line.js +11 -0
  128. package/dist/shapes/Line.js.map +1 -0
  129. package/dist/shapes/Path.d.ts +20 -0
  130. package/dist/shapes/Path.d.ts.map +1 -0
  131. package/dist/shapes/Path.js +14 -0
  132. package/dist/shapes/Path.js.map +1 -0
  133. package/dist/shapes/Polygon.d.ts +15 -0
  134. package/dist/shapes/Polygon.d.ts.map +1 -0
  135. package/dist/shapes/Polygon.js +16 -0
  136. package/dist/shapes/Polygon.js.map +1 -0
  137. package/dist/shapes/Rect.d.ts +18 -0
  138. package/dist/shapes/Rect.d.ts.map +1 -0
  139. package/dist/shapes/Rect.js +11 -0
  140. package/dist/shapes/Rect.js.map +1 -0
  141. package/dist/shapes/Svg.d.ts +16 -0
  142. package/dist/shapes/Svg.d.ts.map +1 -0
  143. package/dist/shapes/Svg.js +15 -0
  144. package/dist/shapes/Svg.js.map +1 -0
  145. package/dist/shapes/index.d.ts +16 -0
  146. package/dist/shapes/index.d.ts.map +1 -0
  147. package/dist/shapes/index.js +9 -0
  148. package/dist/shapes/index.js.map +1 -0
  149. package/dist/shapes/usePathLength.d.ts +24 -0
  150. package/dist/shapes/usePathLength.d.ts.map +1 -0
  151. package/dist/shapes/usePathLength.js +32 -0
  152. package/dist/shapes/usePathLength.js.map +1 -0
  153. package/dist/staticFile.d.ts +47 -0
  154. package/dist/staticFile.d.ts.map +1 -0
  155. package/dist/staticFile.js +105 -0
  156. package/dist/staticFile.js.map +1 -0
  157. package/dist/templates/api.d.ts +26 -0
  158. package/dist/templates/api.d.ts.map +1 -0
  159. package/dist/templates/api.js +142 -0
  160. package/dist/templates/api.js.map +1 -0
  161. package/dist/templates/index.d.ts +7 -0
  162. package/dist/templates/index.d.ts.map +1 -0
  163. package/dist/templates/index.js +7 -0
  164. package/dist/templates/index.js.map +1 -0
  165. package/dist/templates/mockData.d.ts +7 -0
  166. package/dist/templates/mockData.d.ts.map +1 -0
  167. package/dist/templates/mockData.js +262 -0
  168. package/dist/templates/mockData.js.map +1 -0
  169. package/dist/templates/types.d.ts +104 -0
  170. package/dist/templates/types.d.ts.map +1 -0
  171. package/dist/templates/types.js +16 -0
  172. package/dist/templates/types.js.map +1 -0
  173. package/dist/transitions/TransitionSeries.d.ts +127 -0
  174. package/dist/transitions/TransitionSeries.d.ts.map +1 -0
  175. package/dist/transitions/TransitionSeries.js +190 -0
  176. package/dist/transitions/TransitionSeries.js.map +1 -0
  177. package/dist/transitions/index.d.ts +52 -0
  178. package/dist/transitions/index.d.ts.map +1 -0
  179. package/dist/transitions/index.js +31 -0
  180. package/dist/transitions/index.js.map +1 -0
  181. package/dist/transitions/presets/fade.d.ts +45 -0
  182. package/dist/transitions/presets/fade.d.ts.map +1 -0
  183. package/dist/transitions/presets/fade.js +56 -0
  184. package/dist/transitions/presets/fade.js.map +1 -0
  185. package/dist/transitions/presets/flip.d.ts +99 -0
  186. package/dist/transitions/presets/flip.d.ts.map +1 -0
  187. package/dist/transitions/presets/flip.js +153 -0
  188. package/dist/transitions/presets/flip.js.map +1 -0
  189. package/dist/transitions/presets/slide.d.ts +61 -0
  190. package/dist/transitions/presets/slide.d.ts.map +1 -0
  191. package/dist/transitions/presets/slide.js +116 -0
  192. package/dist/transitions/presets/slide.js.map +1 -0
  193. package/dist/transitions/presets/wipe.d.ts +69 -0
  194. package/dist/transitions/presets/wipe.d.ts.map +1 -0
  195. package/dist/transitions/presets/wipe.js +136 -0
  196. package/dist/transitions/presets/wipe.js.map +1 -0
  197. package/dist/transitions/presets/zoom.d.ts +76 -0
  198. package/dist/transitions/presets/zoom.d.ts.map +1 -0
  199. package/dist/transitions/presets/zoom.js +110 -0
  200. package/dist/transitions/presets/zoom.js.map +1 -0
  201. package/dist/useAudioData.d.ts +112 -0
  202. package/dist/useAudioData.d.ts.map +1 -0
  203. package/dist/useAudioData.js +183 -0
  204. package/dist/useAudioData.js.map +1 -0
  205. package/dist/useSpring.d.ts +79 -0
  206. package/dist/useSpring.d.ts.map +1 -0
  207. package/dist/useSpring.js +140 -0
  208. package/dist/useSpring.js.map +1 -0
  209. 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"}
@@ -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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"}