remotion-claude-agent-demo 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 (128) hide show
  1. package/README.md +160 -0
  2. package/apps/web/README.md +36 -0
  3. package/apps/web/env.example +20 -0
  4. package/apps/web/eslint.config.mjs +18 -0
  5. package/apps/web/next.config.ts +7 -0
  6. package/apps/web/package-lock.json +10348 -0
  7. package/apps/web/package.json +35 -0
  8. package/apps/web/postcss.config.mjs +7 -0
  9. package/apps/web/public/file.svg +1 -0
  10. package/apps/web/public/globe.svg +1 -0
  11. package/apps/web/public/next.svg +1 -0
  12. package/apps/web/public/vercel.svg +1 -0
  13. package/apps/web/public/window.svg +1 -0
  14. package/apps/web/src/app/.well-known/agent-card.json/route.ts +50 -0
  15. package/apps/web/src/app/background-tasks/[jobId]/cancel/route.ts +29 -0
  16. package/apps/web/src/app/events/stream/route.ts +58 -0
  17. package/apps/web/src/app/favicon.ico +0 -0
  18. package/apps/web/src/app/globals.css +174 -0
  19. package/apps/web/src/app/layout.tsx +34 -0
  20. package/apps/web/src/app/messages/answer/route.ts +57 -0
  21. package/apps/web/src/app/messages/stream/route.ts +381 -0
  22. package/apps/web/src/app/page.tsx +358 -0
  23. package/apps/web/src/app/tasks/[taskId]/cancel/route.ts +24 -0
  24. package/apps/web/src/app/tasks/[taskId]/route.ts +24 -0
  25. package/apps/web/src/app/tasks/route.ts +13 -0
  26. package/apps/web/src/components/chat/agent-blocks.tsx +111 -0
  27. package/apps/web/src/components/chat/ask-user-question-panel.tsx +172 -0
  28. package/apps/web/src/components/chat/session-sidebar.tsx +222 -0
  29. package/apps/web/src/components/chat/subagent-activity-sidebar.tsx +248 -0
  30. package/apps/web/src/components/chat/tool-blocks.tsx +550 -0
  31. package/apps/web/src/lib/a2a/activity-store.ts +150 -0
  32. package/apps/web/src/lib/a2a/client.ts +357 -0
  33. package/apps/web/src/lib/a2a/sse.ts +19 -0
  34. package/apps/web/src/lib/a2a/task-store.ts +111 -0
  35. package/apps/web/src/lib/a2a/types.ts +216 -0
  36. package/apps/web/src/lib/agent/answer-store.ts +109 -0
  37. package/apps/web/src/lib/agent/background-delivery.ts +343 -0
  38. package/apps/web/src/lib/agent/background-tool.ts +78 -0
  39. package/apps/web/src/lib/agent/background.ts +452 -0
  40. package/apps/web/src/lib/agent/chat.ts +543 -0
  41. package/apps/web/src/lib/agent/session-store.ts +26 -0
  42. package/apps/web/src/lib/chat/types.ts +44 -0
  43. package/apps/web/src/lib/env.ts +31 -0
  44. package/apps/web/src/lib/hooks/useA2AChat.ts +863 -0
  45. package/apps/web/src/lib/state/chat-atoms.ts +52 -0
  46. package/apps/web/src/lib/workspace.ts +9 -0
  47. package/apps/web/tsconfig.json +35 -0
  48. package/bin/remotion-agent.js +451 -0
  49. package/package.json +34 -0
  50. package/templates/.claude/CLAUDE.md +95 -0
  51. package/templates/.claude/README.md +129 -0
  52. package/templates/.claude/agents/composer-agent.md +188 -0
  53. package/templates/.claude/agents/crafter.md +181 -0
  54. package/templates/.claude/agents/creator.md +134 -0
  55. package/templates/.claude/agents/perceiver.md +92 -0
  56. package/templates/.claude/settings.json +36 -0
  57. package/templates/.claude/settings.local.json +39 -0
  58. package/templates/.claude/skills/agent-browser/SKILL.md +349 -0
  59. package/templates/.claude/skills/agent-browser/references/authentication.md +188 -0
  60. package/templates/.claude/skills/agent-browser/references/proxy-support.md +175 -0
  61. package/templates/.claude/skills/agent-browser/references/session-management.md +181 -0
  62. package/templates/.claude/skills/agent-browser/references/snapshot-refs.md +186 -0
  63. package/templates/.claude/skills/agent-browser/references/video-recording.md +162 -0
  64. package/templates/.claude/skills/agent-browser/templates/authenticated-session.sh +91 -0
  65. package/templates/.claude/skills/agent-browser/templates/capture-workflow.sh +68 -0
  66. package/templates/.claude/skills/agent-browser/templates/form-automation.sh +64 -0
  67. package/templates/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
  68. package/templates/.claude/skills/algorithmic-art/SKILL.md +405 -0
  69. package/templates/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
  70. package/templates/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
  71. package/templates/.claude/skills/asset-validator/SKILL.md +376 -0
  72. package/templates/.claude/skills/audio-video-sync/SKILL.md +219 -0
  73. package/templates/.claude/skills/bgm-manager/SKILL.md +334 -0
  74. package/templates/.claude/skills/remotion-best-practices/SKILL.md +45 -0
  75. package/templates/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
  76. package/templates/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
  77. package/templates/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  78. package/templates/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  79. package/templates/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  80. package/templates/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
  81. package/templates/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
  82. package/templates/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  83. package/templates/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
  84. package/templates/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
  85. package/templates/.claude/skills/remotion-best-practices/rules/compositions.md +141 -0
  86. package/templates/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
  87. package/templates/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  88. package/templates/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
  89. package/templates/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  90. package/templates/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  91. package/templates/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  92. package/templates/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
  93. package/templates/.claude/skills/remotion-best-practices/rules/images.md +130 -0
  94. package/templates/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  95. package/templates/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
  96. package/templates/.claude/skills/remotion-best-practices/rules/maps.md +403 -0
  97. package/templates/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  98. package/templates/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  99. package/templates/.claude/skills/remotion-best-practices/rules/parameters.md +98 -0
  100. package/templates/.claude/skills/remotion-best-practices/rules/sequencing.md +118 -0
  101. package/templates/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
  102. package/templates/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
  103. package/templates/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
  104. package/templates/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  105. package/templates/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
  106. package/templates/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
  107. package/templates/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
  108. package/templates/.claude/skills/remotion-components/SKILL.md +453 -0
  109. package/templates/.claude/skills/render-config/SKILL.md +290 -0
  110. package/templates/.claude/skills/script-writer/SKILL.md +59 -0
  111. package/templates/.claude/skills/style-director/script-writer/SKILL.md +82 -0
  112. package/templates/.claude/skills/style-director/style-director/SKILL.md +287 -0
  113. package/templates/.claude/skills/style-director/style-director/references/audience-and-scenarios.md +43 -0
  114. package/templates/.claude/skills/style-director/style-director/references/interaction-innovation.md +26 -0
  115. package/templates/.claude/skills/style-director/style-director/references/motion-grammar.md +66 -0
  116. package/templates/.claude/skills/style-director/style-director/references/quality-checklist.md +29 -0
  117. package/templates/.claude/skills/style-director/style-director/references/scene-recipes.md +38 -0
  118. package/templates/.claude/skills/style-director/style-director/references/visual-style-system.md +148 -0
  119. package/templates/.claude/skills/subtitle-composer/SKILL.md +304 -0
  120. package/templates/.claude/skills/subtitle-processor/SKILL.md +308 -0
  121. package/templates/.claude/skills/timeline-generator/SKILL.md +253 -0
  122. package/templates/.claude/skills/video-preflight-check/SKILL.md +353 -0
  123. package/templates/.claude/skills/voice-synthesizer/SKILL.md +296 -0
  124. package/templates/.claude/skills/voice-synthesizer/scripts/synthesize_voice.py +315 -0
  125. package/templates/.claude/skills/voice-synthesizer/scripts/tts_cli.py +142 -0
  126. package/templates/.claude/skills/web-design-guidelines/SKILL.md +36 -0
  127. package/templates/.claude/skills/youtube-downloader/SKILL.md +99 -0
  128. package/templates/.claude/skills/youtube-downloader/scripts/download_video.py +145 -0
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: get-video-dimensions
3
+ description: Getting the width and height of a video file with Mediabunny
4
+ metadata:
5
+ tags: dimensions, width, height, resolution, size, video
6
+ ---
7
+
8
+ # Getting video dimensions with Mediabunny
9
+
10
+ Mediabunny can extract the width and height of a video file. It works in browser, Node.js, and Bun environments.
11
+
12
+ ## Getting video dimensions
13
+
14
+ ```tsx
15
+ import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
16
+
17
+ export const getVideoDimensions = async (src: string) => {
18
+ const input = new Input({
19
+ formats: ALL_FORMATS,
20
+ source: new UrlSource(src, {
21
+ getRetryDelay: () => null,
22
+ }),
23
+ });
24
+
25
+ const videoTrack = await input.getPrimaryVideoTrack();
26
+ if (!videoTrack) {
27
+ throw new Error("No video track found");
28
+ }
29
+
30
+ return {
31
+ width: videoTrack.displayWidth,
32
+ height: videoTrack.displayHeight,
33
+ };
34
+ };
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ```tsx
40
+ const dimensions = await getVideoDimensions("https://remotion.media/video.mp4");
41
+ console.log(dimensions.width); // e.g. 1920
42
+ console.log(dimensions.height); // e.g. 1080
43
+ ```
44
+
45
+ ## Using with local files
46
+
47
+ For local files, use `FileSource` instead of `UrlSource`:
48
+
49
+ ```tsx
50
+ import { Input, ALL_FORMATS, FileSource } from "mediabunny";
51
+
52
+ const input = new Input({
53
+ formats: ALL_FORMATS,
54
+ source: new FileSource(file), // File object from input or drag-drop
55
+ });
56
+
57
+ const videoTrack = await input.getPrimaryVideoTrack();
58
+ const width = videoTrack.displayWidth;
59
+ const height = videoTrack.displayHeight;
60
+ ```
61
+
62
+ ## Using with staticFile in Remotion
63
+
64
+ ```tsx
65
+ import { staticFile } from "remotion";
66
+
67
+ const dimensions = await getVideoDimensions(staticFile("video.mp4"));
68
+ ```
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: get-video-duration
3
+ description: Getting the duration of a video file in seconds with Mediabunny
4
+ metadata:
5
+ tags: duration, video, length, time, seconds
6
+ ---
7
+
8
+ # Getting video duration with Mediabunny
9
+
10
+ Mediabunny can extract the duration of a video file. It works in browser, Node.js, and Bun environments.
11
+
12
+ ## Getting video duration
13
+
14
+ ```tsx
15
+ import { Input, ALL_FORMATS, UrlSource } from "mediabunny";
16
+
17
+ export const getVideoDuration = async (src: string) => {
18
+ const input = new Input({
19
+ formats: ALL_FORMATS,
20
+ source: new UrlSource(src, {
21
+ getRetryDelay: () => null,
22
+ }),
23
+ });
24
+
25
+ const durationInSeconds = await input.computeDuration();
26
+ return durationInSeconds;
27
+ };
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```tsx
33
+ const duration = await getVideoDuration("https://remotion.media/video.mp4");
34
+ console.log(duration); // e.g. 10.5 (seconds)
35
+ ```
36
+
37
+ ## Using with local files
38
+
39
+ For local files, use `FileSource` instead of `UrlSource`:
40
+
41
+ ```tsx
42
+ import { Input, ALL_FORMATS, FileSource } from "mediabunny";
43
+
44
+ const input = new Input({
45
+ formats: ALL_FORMATS,
46
+ source: new FileSource(file), // File object from input or drag-drop
47
+ });
48
+
49
+ const durationInSeconds = await input.computeDuration();
50
+ ```
51
+
52
+ ## Using with staticFile in Remotion
53
+
54
+ ```tsx
55
+ import { staticFile } from "remotion";
56
+
57
+ const duration = await getVideoDuration(staticFile("video.mp4"));
58
+ ```
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: gif
3
+ description: Displaying GIFs, APNG, AVIF and WebP in Remotion
4
+ metadata:
5
+ tags: gif, animation, images, animated, apng, avif, webp
6
+ ---
7
+
8
+ # Using Animated images in Remotion
9
+
10
+ ## Basic usage
11
+
12
+ Use `<AnimatedImage>` to display a GIF, APNG, AVIF or WebP image synchronized with Remotion's timeline:
13
+
14
+ ```tsx
15
+ import {AnimatedImage, staticFile} from 'remotion';
16
+
17
+ export const MyComposition = () => {
18
+ return <AnimatedImage src={staticFile('animation.gif')} width={500} height={500} />;
19
+ };
20
+ ```
21
+
22
+ Remote URLs are also supported (must have CORS enabled):
23
+
24
+ ```tsx
25
+ <AnimatedImage src="https://example.com/animation.gif" width={500} height={500} />
26
+ ```
27
+
28
+ ## Sizing and fit
29
+
30
+ Control how the image fills its container with the `fit` prop:
31
+
32
+ ```tsx
33
+ // Stretch to fill (default)
34
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="fill" />
35
+
36
+ // Maintain aspect ratio, fit inside container
37
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="contain" />
38
+
39
+ // Fill container, crop if needed
40
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="cover" />
41
+ ```
42
+
43
+ ## Playback speed
44
+
45
+ Use `playbackRate` to control the animation speed:
46
+
47
+ ```tsx
48
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={2} /> {/* 2x speed */}
49
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={0.5} /> {/* Half speed */}
50
+ ```
51
+
52
+ ## Looping behavior
53
+
54
+ Control what happens when the animation finishes:
55
+
56
+ ```tsx
57
+ // Loop indefinitely (default)
58
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="loop" />
59
+
60
+ // Play once, show final frame
61
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="pause-after-finish" />
62
+
63
+ // Play once, then clear canvas
64
+ <AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="clear-after-finish" />
65
+ ```
66
+
67
+ ## Styling
68
+
69
+ Use the `style` prop for additional CSS (use `width` and `height` props for sizing):
70
+
71
+ ```tsx
72
+ <AnimatedImage
73
+ src={staticFile('animation.gif')}
74
+ width={500}
75
+ height={500}
76
+ style={{
77
+ borderRadius: 20,
78
+ position: 'absolute',
79
+ top: 100,
80
+ left: 50,
81
+ }}
82
+ />
83
+ ```
84
+
85
+ ## Getting GIF duration
86
+
87
+ Use `getGifDurationInSeconds()` from `@remotion/gif` to get the duration of a GIF.
88
+
89
+ ```bash
90
+ npx remotion add @remotion/gif # If project uses npm
91
+ bunx remotion add @remotion/gif # If project uses bun
92
+ yarn remotion add @remotion/gif # If project uses yarn
93
+ pnpm exec remotion add @remotion/gif # If project uses pnpm
94
+ ```
95
+
96
+ ```tsx
97
+ import {getGifDurationInSeconds} from '@remotion/gif';
98
+ import {staticFile} from 'remotion';
99
+
100
+ const duration = await getGifDurationInSeconds(staticFile('animation.gif'));
101
+ console.log(duration); // e.g. 2.5
102
+ ```
103
+
104
+ This is useful for setting the composition duration to match the GIF:
105
+
106
+ ```tsx
107
+ import {getGifDurationInSeconds} from '@remotion/gif';
108
+ import {staticFile, CalculateMetadataFunction} from 'remotion';
109
+
110
+ const calculateMetadata: CalculateMetadataFunction = async () => {
111
+ const duration = await getGifDurationInSeconds(staticFile('animation.gif'));
112
+ return {
113
+ durationInFrames: Math.ceil(duration * 30),
114
+ };
115
+ };
116
+ ```
117
+
118
+ ## Alternative
119
+
120
+ If `<AnimatedImage>` does not work (only supported in Chrome and Firefox), you can use `<Gif>` from `@remotion/gif` instead.
121
+
122
+ ```bash
123
+ npx remotion add @remotion/gif # If project uses npm
124
+ bunx remotion add @remotion/gif # If project uses bun
125
+ yarn remotion add @remotion/gif # If project uses yarn
126
+ pnpm exec remotion add @remotion/gif # If project uses pnpm
127
+ ```
128
+
129
+ ```tsx
130
+ import {Gif} from '@remotion/gif';
131
+ import {staticFile} from 'remotion';
132
+
133
+ export const MyComposition = () => {
134
+ return <Gif src={staticFile('animation.gif')} width={500} height={500} />;
135
+ };
136
+ ```
137
+
138
+ The `<Gif>` component has the same props as `<AnimatedImage>` but only supports GIF files.
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: images
3
+ description: Embedding images in Remotion using the <Img> component
4
+ metadata:
5
+ tags: images, img, staticFile, png, jpg, svg, webp
6
+ ---
7
+
8
+ # Using images in Remotion
9
+
10
+ ## The `<Img>` component
11
+
12
+ Always use the `<Img>` component from `remotion` to display images:
13
+
14
+ ```tsx
15
+ import { Img, staticFile } from "remotion";
16
+
17
+ export const MyComposition = () => {
18
+ return <Img src={staticFile("photo.png")} />;
19
+ };
20
+ ```
21
+
22
+ ## Important restrictions
23
+
24
+ **You MUST use the `<Img>` component from `remotion`.** Do not use:
25
+
26
+ - Native HTML `<img>` elements
27
+ - Next.js `<Image>` component
28
+ - CSS `background-image`
29
+
30
+ The `<Img>` component ensures images are fully loaded before rendering, preventing flickering and blank frames during video export.
31
+
32
+ ## Local images with staticFile()
33
+
34
+ Place images in the `public/` folder and use `staticFile()` to reference them:
35
+
36
+ ```
37
+ my-video/
38
+ ├─ public/
39
+ │ ├─ logo.png
40
+ │ ├─ avatar.jpg
41
+ │ └─ icon.svg
42
+ ├─ src/
43
+ ├─ package.json
44
+ ```
45
+
46
+ ```tsx
47
+ import { Img, staticFile } from "remotion";
48
+
49
+ <Img src={staticFile("logo.png")} />
50
+ ```
51
+
52
+ ## Remote images
53
+
54
+ Remote URLs can be used directly without `staticFile()`:
55
+
56
+ ```tsx
57
+ <Img src="https://example.com/image.png" />
58
+ ```
59
+
60
+ Ensure remote images have CORS enabled.
61
+
62
+ For animated GIFs, use the `<Gif>` component from `@remotion/gif` instead.
63
+
64
+ ## Sizing and positioning
65
+
66
+ Use the `style` prop to control size and position:
67
+
68
+ ```tsx
69
+ <Img
70
+ src={staticFile("photo.png")}
71
+ style={{
72
+ width: 500,
73
+ height: 300,
74
+ position: "absolute",
75
+ top: 100,
76
+ left: 50,
77
+ objectFit: "cover",
78
+ }}
79
+ />
80
+ ```
81
+
82
+ ## Dynamic image paths
83
+
84
+ Use template literals for dynamic file references:
85
+
86
+ ```tsx
87
+ import { Img, staticFile, useCurrentFrame } from "remotion";
88
+
89
+ const frame = useCurrentFrame();
90
+
91
+ // Image sequence
92
+ <Img src={staticFile(`frames/frame${frame}.png`)} />
93
+
94
+ // Selecting based on props
95
+ <Img src={staticFile(`avatars/${props.userId}.png`)} />
96
+
97
+ // Conditional images
98
+ <Img src={staticFile(`icons/${isActive ? "active" : "inactive"}.svg`)} />
99
+ ```
100
+
101
+ This pattern is useful for:
102
+
103
+ - Image sequences (frame-by-frame animations)
104
+ - User-specific avatars or profile images
105
+ - Theme-based icons
106
+ - State-dependent graphics
107
+
108
+ ## Getting image dimensions
109
+
110
+ Use `getImageDimensions()` to get the dimensions of an image:
111
+
112
+ ```tsx
113
+ import { getImageDimensions, staticFile } from "remotion";
114
+
115
+ const { width, height } = await getImageDimensions(staticFile("photo.png"));
116
+ ```
117
+
118
+ This is useful for calculating aspect ratios or sizing compositions:
119
+
120
+ ```tsx
121
+ import { getImageDimensions, staticFile, CalculateMetadataFunction } from "remotion";
122
+
123
+ const calculateMetadata: CalculateMetadataFunction = async () => {
124
+ const { width, height } = await getImageDimensions(staticFile("photo.png"));
125
+ return {
126
+ width,
127
+ height,
128
+ };
129
+ };
130
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: import-srt-captions
3
+ description: Importing .srt subtitle files into Remotion using @remotion/captions
4
+ metadata:
5
+ tags: captions, subtitles, srt, import, parse
6
+ ---
7
+
8
+ # Importing .srt subtitles into Remotion
9
+
10
+ If you have an existing `.srt` subtitle file, you can import it into Remotion using `parseSrt()` from `@remotion/captions`.
11
+
12
+ ## Prerequisites
13
+
14
+ First, the @remotion/captions package needs to be installed.
15
+ If it is not installed, use the following command:
16
+
17
+ ```bash
18
+ npx remotion add @remotion/captions # If project uses npm
19
+ bunx remotion add @remotion/captions # If project uses bun
20
+ yarn remotion add @remotion/captions # If project uses yarn
21
+ pnpm exec remotion add @remotion/captions # If project uses pnpm
22
+ ```
23
+
24
+ ## Reading an .srt file
25
+
26
+ Use `staticFile()` to reference an `.srt` file in your `public` folder, then fetch and parse it:
27
+
28
+ ```tsx
29
+ import {useState, useEffect, useCallback} from 'react';
30
+ import {AbsoluteFill, staticFile, useDelayRender} from 'remotion';
31
+ import {parseSrt} from '@remotion/captions';
32
+ import type {Caption} from '@remotion/captions';
33
+
34
+ export const MyComponent: React.FC = () => {
35
+ const [captions, setCaptions] = useState<Caption[] | null>(null);
36
+ const {delayRender, continueRender, cancelRender} = useDelayRender();
37
+ const [handle] = useState(() => delayRender());
38
+
39
+ const fetchCaptions = useCallback(async () => {
40
+ try {
41
+ const response = await fetch(staticFile('subtitles.srt'));
42
+ const text = await response.text();
43
+ const {captions: parsed} = parseSrt({input: text});
44
+ setCaptions(parsed);
45
+ continueRender(handle);
46
+ } catch (e) {
47
+ cancelRender(e);
48
+ }
49
+ }, [continueRender, cancelRender, handle]);
50
+
51
+ useEffect(() => {
52
+ fetchCaptions();
53
+ }, [fetchCaptions]);
54
+
55
+ if (!captions) {
56
+ return null;
57
+ }
58
+
59
+ return <AbsoluteFill>{/* Use captions here */}</AbsoluteFill>;
60
+ };
61
+ ```
62
+
63
+ Remote URLs are also supported - you can `fetch()` a remote file via URL instead of using `staticFile()`.
64
+
65
+ ## Using imported captions
66
+
67
+ Once parsed, the captions are in the `Caption` format and can be used with all `@remotion/captions` utilities.
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: lottie
3
+ description: Embedding Lottie animations in Remotion.
4
+ metadata:
5
+ category: Animation
6
+ ---
7
+
8
+ # Using Lottie Animations in Remotion
9
+
10
+ ## Prerequisites
11
+
12
+ First, the @remotion/lottie package needs to be installed.
13
+ If it is not, use the following command:
14
+
15
+ ```bash
16
+ npx remotion add @remotion/lottie # If project uses npm
17
+ bunx remotion add @remotion/lottie # If project uses bun
18
+ yarn remotion add @remotion/lottie # If project uses yarn
19
+ pnpm exec remotion add @remotion/lottie # If project uses pnpm
20
+ ```
21
+
22
+ ## Displaying a Lottie file
23
+
24
+ To import a Lottie animation:
25
+
26
+ - Fetch the Lottie asset
27
+ - Wrap the loading process in `delayRender()` and `continueRender()`
28
+ - Save the animation data in a state
29
+ - Render the Lottie animation using the `Lottie` component from the `@remotion/lottie` package
30
+
31
+ ```tsx
32
+ import {Lottie, LottieAnimationData} from '@remotion/lottie';
33
+ import {useEffect, useState} from 'react';
34
+ import {cancelRender, continueRender, delayRender} from 'remotion';
35
+
36
+ export const MyAnimation = () => {
37
+ const [handle] = useState(() => delayRender('Loading Lottie animation'));
38
+
39
+ const [animationData, setAnimationData] = useState<LottieAnimationData | null>(null);
40
+
41
+ useEffect(() => {
42
+ fetch('https://assets4.lottiefiles.com/packages/lf20_zyquagfl.json')
43
+ .then((data) => data.json())
44
+ .then((json) => {
45
+ setAnimationData(json);
46
+ continueRender(handle);
47
+ })
48
+ .catch((err) => {
49
+ cancelRender(err);
50
+ });
51
+ }, [handle]);
52
+
53
+ if (!animationData) {
54
+ return null;
55
+ }
56
+
57
+ return <Lottie animationData={animationData} />;
58
+ };
59
+ ```
60
+
61
+ ## Styling and animating
62
+
63
+ Lottie supports the `style` prop to allow styles and animations:
64
+
65
+ ```tsx
66
+ return <Lottie animationData={animationData} style={{width: 400, height: 400}} />;
67
+ ```
68
+