@revideo/create 0.5.11-alpha.1102 → 0.5.11-alpha.1104

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 (185) hide show
  1. package/examples/README.md +43 -0
  2. package/examples/avatar-with-background/package.json +27 -0
  3. package/examples/avatar-with-background/src/project.meta +31 -0
  4. package/examples/avatar-with-background/src/project.ts +6 -0
  5. package/examples/avatar-with-background/src/render.ts +14 -0
  6. package/examples/avatar-with-background/src/revideo.d.ts +1 -0
  7. package/examples/avatar-with-background/src/scenes/example.meta +5 -0
  8. package/examples/avatar-with-background/src/scenes/example.tsx +28 -0
  9. package/examples/avatar-with-background/tsconfig.json +9 -0
  10. package/examples/avatar-with-background/vite.config.ts +8 -0
  11. package/examples/default/README.md +19 -0
  12. package/examples/default/package.json +20 -0
  13. package/examples/default/src/project.tsx +56 -0
  14. package/examples/default/src/render.ts +15 -0
  15. package/examples/default/tsconfig.json +10 -0
  16. package/examples/github-stars-celebration/package-lock.json +3833 -0
  17. package/examples/github-stars-celebration/package.json +24 -0
  18. package/examples/github-stars-celebration/src/global.css +1 -0
  19. package/examples/github-stars-celebration/src/project.meta +28 -0
  20. package/examples/github-stars-celebration/src/project.ts +8 -0
  21. package/examples/github-stars-celebration/src/render.ts +15 -0
  22. package/examples/github-stars-celebration/src/revideo.d.ts +1 -0
  23. package/examples/github-stars-celebration/src/scenes/example.meta +5 -0
  24. package/examples/github-stars-celebration/src/scenes/example.tsx +51 -0
  25. package/examples/github-stars-celebration/tsconfig.json +9 -0
  26. package/examples/github-stars-celebration/vite.config.ts +8 -0
  27. package/examples/google-cloud-run-parallelized/README.md +127 -0
  28. package/examples/google-cloud-run-parallelized/render-orchestrator/Dockerfile +56 -0
  29. package/examples/google-cloud-run-parallelized/render-orchestrator/package.json +22 -0
  30. package/examples/google-cloud-run-parallelized/render-orchestrator/src/index.ts +72 -0
  31. package/examples/google-cloud-run-parallelized/render-orchestrator/src/revideo.d.ts +1 -0
  32. package/examples/google-cloud-run-parallelized/render-orchestrator/tsconfig.json +10 -0
  33. package/examples/google-cloud-run-parallelized/render-worker/.gcloudignore +17 -0
  34. package/examples/google-cloud-run-parallelized/render-worker/.puppeteerrc.cjs +9 -0
  35. package/examples/google-cloud-run-parallelized/render-worker/package.json +30 -0
  36. package/examples/google-cloud-run-parallelized/render-worker/src/index.ts +45 -0
  37. package/examples/google-cloud-run-parallelized/render-worker/src/project.meta +31 -0
  38. package/examples/google-cloud-run-parallelized/render-worker/src/project.ts +6 -0
  39. package/examples/google-cloud-run-parallelized/render-worker/src/render.ts +14 -0
  40. package/examples/google-cloud-run-parallelized/render-worker/src/revideo.d.ts +1 -0
  41. package/examples/google-cloud-run-parallelized/render-worker/src/scenes/example.tsx +30 -0
  42. package/examples/google-cloud-run-parallelized/render-worker/tsconfig.json +13 -0
  43. package/examples/google-cloud-run-parallelized/render-worker/vite.config.ts +9 -0
  44. package/examples/logo.svg +6 -0
  45. package/examples/logo_dark.svg +6 -0
  46. package/examples/marketing-templates/README.md +10 -0
  47. package/examples/marketing-templates/marketing-template/package.json +24 -0
  48. package/examples/marketing-templates/marketing-template/src/globals.css +0 -0
  49. package/examples/marketing-templates/marketing-template/src/project.meta +28 -0
  50. package/examples/marketing-templates/marketing-template/src/project.ts +9 -0
  51. package/examples/marketing-templates/marketing-template/src/render.ts +15 -0
  52. package/examples/marketing-templates/marketing-template/src/revideo.d.ts +1 -0
  53. package/examples/marketing-templates/marketing-template/src/scenes/example.meta +5 -0
  54. package/examples/marketing-templates/marketing-template/src/scenes/example.tsx +67 -0
  55. package/examples/marketing-templates/marketing-template/tsconfig.json +9 -0
  56. package/examples/marketing-templates/marketing-template/vite.config.ts +9 -0
  57. package/examples/marketing-templates/multiple-videos-in-one/package.json +24 -0
  58. package/examples/marketing-templates/multiple-videos-in-one/src/project.meta +28 -0
  59. package/examples/marketing-templates/multiple-videos-in-one/src/project.ts +9 -0
  60. package/examples/marketing-templates/multiple-videos-in-one/src/render.ts +15 -0
  61. package/examples/marketing-templates/multiple-videos-in-one/src/revideo.d.ts +1 -0
  62. package/examples/marketing-templates/multiple-videos-in-one/src/scenes/example.meta +5 -0
  63. package/examples/marketing-templates/multiple-videos-in-one/src/scenes/example.tsx +122 -0
  64. package/examples/marketing-templates/multiple-videos-in-one/tsconfig.json +9 -0
  65. package/examples/marketing-templates/multiple-videos-in-one/vite.config.ts +9 -0
  66. package/examples/minimal-drag-drop/README.md +29 -0
  67. package/examples/minimal-drag-drop/next/app/api/render/route.ts +22 -0
  68. package/examples/minimal-drag-drop/next/app/globals.css +3 -0
  69. package/examples/minimal-drag-drop/next/app/layout.tsx +25 -0
  70. package/examples/minimal-drag-drop/next/app/page.tsx +277 -0
  71. package/examples/minimal-drag-drop/next/next-env.d.ts +5 -0
  72. package/examples/minimal-drag-drop/next/next.config.mjs +4 -0
  73. package/examples/minimal-drag-drop/next/package-lock.json +5577 -0
  74. package/examples/minimal-drag-drop/next/package.json +35 -0
  75. package/examples/minimal-drag-drop/next/postcss.config.js +6 -0
  76. package/examples/minimal-drag-drop/next/public/favicon.ico +0 -0
  77. package/examples/minimal-drag-drop/next/public/next.svg +1 -0
  78. package/examples/minimal-drag-drop/next/public/vercel.svg +1 -0
  79. package/examples/minimal-drag-drop/next/tailwind.config.ts +30 -0
  80. package/examples/minimal-drag-drop/next/tsconfig.json +26 -0
  81. package/examples/minimal-drag-drop/next/utils/parse.ts +35 -0
  82. package/examples/minimal-drag-drop/revideo/package-lock.json +3771 -0
  83. package/examples/minimal-drag-drop/revideo/package.json +24 -0
  84. package/examples/minimal-drag-drop/revideo/src/global.css +1 -0
  85. package/examples/minimal-drag-drop/revideo/src/project.meta +28 -0
  86. package/examples/minimal-drag-drop/revideo/src/project.ts +9 -0
  87. package/examples/minimal-drag-drop/revideo/src/render.ts +15 -0
  88. package/examples/minimal-drag-drop/revideo/src/revideo.d.ts +1 -0
  89. package/examples/minimal-drag-drop/revideo/src/scenes/example.meta +5 -0
  90. package/examples/minimal-drag-drop/revideo/src/scenes/example.tsx +44 -0
  91. package/examples/minimal-drag-drop/revideo/tsconfig.json +9 -0
  92. package/examples/minimal-drag-drop/revideo/vite.config.ts +6 -0
  93. package/examples/parallelized-aws-lambda/.dockerignore +3 -0
  94. package/examples/parallelized-aws-lambda/Dockerfile +21 -0
  95. package/examples/parallelized-aws-lambda/Dockerfile.base +64 -0
  96. package/examples/parallelized-aws-lambda/README.md +197 -0
  97. package/examples/parallelized-aws-lambda/revideo-project/.puppeteerrc.cjs +9 -0
  98. package/examples/parallelized-aws-lambda/revideo-project/package-lock.json +4133 -0
  99. package/examples/parallelized-aws-lambda/revideo-project/package.json +28 -0
  100. package/examples/parallelized-aws-lambda/revideo-project/src/lambda.ts +157 -0
  101. package/examples/parallelized-aws-lambda/revideo-project/src/project.meta +28 -0
  102. package/examples/parallelized-aws-lambda/revideo-project/src/project.ts +7 -0
  103. package/examples/parallelized-aws-lambda/revideo-project/src/render.ts +17 -0
  104. package/examples/parallelized-aws-lambda/revideo-project/src/revideo.d.ts +1 -0
  105. package/examples/parallelized-aws-lambda/revideo-project/src/scenes/example.meta +5 -0
  106. package/examples/parallelized-aws-lambda/revideo-project/src/scenes/example.tsx +30 -0
  107. package/examples/parallelized-aws-lambda/revideo-project/tsconfig.json +10 -0
  108. package/examples/parallelized-aws-lambda/revideo-project/vite.config.ts +9 -0
  109. package/examples/reddit-post-video/README.md +84 -0
  110. package/examples/reddit-post-video/package-lock.json +2941 -0
  111. package/examples/reddit-post-video/package.json +27 -0
  112. package/examples/reddit-post-video/src/global.css +1 -0
  113. package/examples/reddit-post-video/src/metadata.json +576 -0
  114. package/examples/reddit-post-video/src/project.meta +31 -0
  115. package/examples/reddit-post-video/src/project.ts +9 -0
  116. package/examples/reddit-post-video/src/render.ts +157 -0
  117. package/examples/reddit-post-video/src/revideo.d.ts +1 -0
  118. package/examples/reddit-post-video/src/scenes/example.meta +5 -0
  119. package/examples/reddit-post-video/src/scenes/example.tsx +74 -0
  120. package/examples/reddit-post-video/tsconfig.json +9 -0
  121. package/examples/reddit-post-video/vite.config.ts +6 -0
  122. package/examples/rive-explanation-video/README.md +9 -0
  123. package/examples/rive-explanation-video/package.json +25 -0
  124. package/examples/rive-explanation-video/src/global.css +1 -0
  125. package/examples/rive-explanation-video/src/project.meta +31 -0
  126. package/examples/rive-explanation-video/src/project.ts +8 -0
  127. package/examples/rive-explanation-video/src/render.ts +15 -0
  128. package/examples/rive-explanation-video/src/revideo.d.ts +1 -0
  129. package/examples/rive-explanation-video/src/scenes/example.meta +5 -0
  130. package/examples/rive-explanation-video/src/scenes/example.tsx +218 -0
  131. package/examples/rive-explanation-video/tsconfig.json +9 -0
  132. package/examples/rive-explanation-video/vite.config.ts +8 -0
  133. package/examples/saas-template/.prettierrc +9 -0
  134. package/examples/saas-template/README.md +26 -0
  135. package/examples/saas-template/app/actions.tsx +114 -0
  136. package/examples/saas-template/app/api/render/route.ts +23 -0
  137. package/examples/saas-template/app/globals.css +3 -0
  138. package/examples/saas-template/app/layout.tsx +25 -0
  139. package/examples/saas-template/app/page.tsx +204 -0
  140. package/examples/saas-template/next.config.mjs +4 -0
  141. package/examples/saas-template/package.json +40 -0
  142. package/examples/saas-template/postcss.config.js +6 -0
  143. package/examples/saas-template/revideo/global.css +1 -0
  144. package/examples/saas-template/revideo/project.ts +9 -0
  145. package/examples/saas-template/revideo/scene.tsx +179 -0
  146. package/examples/saas-template/tailwind.config.ts +30 -0
  147. package/examples/saas-template/tsconfig.json +27 -0
  148. package/examples/saas-template/utils/parse.ts +35 -0
  149. package/examples/stitching-videos/README.md +7 -0
  150. package/examples/stitching-videos/package.json +23 -0
  151. package/examples/stitching-videos/src/project.meta +28 -0
  152. package/examples/stitching-videos/src/project.ts +20 -0
  153. package/examples/stitching-videos/src/render.ts +27 -0
  154. package/examples/stitching-videos/src/revideo.d.ts +1 -0
  155. package/examples/stitching-videos/src/scenes/example.tsx +30 -0
  156. package/examples/stitching-videos/tsconfig.json +9 -0
  157. package/examples/stitching-videos/vite.config.ts +8 -0
  158. package/examples/three-js-example/README.md +8 -0
  159. package/examples/three-js-example/package-lock.json +2753 -0
  160. package/examples/three-js-example/package.json +25 -0
  161. package/examples/three-js-example/src/components/Three.ts +166 -0
  162. package/examples/three-js-example/src/global.css +1 -0
  163. package/examples/three-js-example/src/project.meta +31 -0
  164. package/examples/three-js-example/src/project.ts +8 -0
  165. package/examples/three-js-example/src/render.ts +15 -0
  166. package/examples/three-js-example/src/revideo.d.ts +1 -0
  167. package/examples/three-js-example/src/scenes/basic3D.meta +5 -0
  168. package/examples/three-js-example/src/scenes/basic3D.tsx +89 -0
  169. package/examples/three-js-example/tsconfig.json +9 -0
  170. package/examples/three-js-example/vite.config.ts +6 -0
  171. package/examples/youtube-shorts/README.md +65 -0
  172. package/examples/youtube-shorts/package-lock.json +3881 -0
  173. package/examples/youtube-shorts/package.json +30 -0
  174. package/examples/youtube-shorts/src/get-assets.ts +34 -0
  175. package/examples/youtube-shorts/src/global.css +3 -0
  176. package/examples/youtube-shorts/src/metadata.json +635 -0
  177. package/examples/youtube-shorts/src/project.meta +28 -0
  178. package/examples/youtube-shorts/src/project.ts +9 -0
  179. package/examples/youtube-shorts/src/render.ts +12 -0
  180. package/examples/youtube-shorts/src/revideo.d.ts +1 -0
  181. package/examples/youtube-shorts/src/scenes/example.tsx +224 -0
  182. package/examples/youtube-shorts/src/utils.ts +123 -0
  183. package/examples/youtube-shorts/tsconfig.json +9 -0
  184. package/examples/youtube-shorts/vite.config.ts +8 -0
  185. package/package.json +9 -9
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "test-revideo-project",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "scripts": {
6
+ "start": "vite",
7
+ "serve": "vite",
8
+ "build": "tsc && vite build",
9
+ "render": "tsc && node dist/render.js"
10
+ },
11
+ "dependencies": {
12
+ "@revideo/2d": "0.5.10",
13
+ "@revideo/core": "0.5.10",
14
+ "@revideo/ffmpeg": "0.5.10",
15
+ "@revideo/renderer": "0.5.10",
16
+ "@revideo/vite-plugin": "0.5.10",
17
+ "@sparticuz/chromium": "^123.0.1",
18
+ "aws-lambda": "^1.0.7",
19
+ "aws-sdk": "^2.1642.0",
20
+ "ffmpeg-static": "^5.2.0"
21
+ },
22
+ "devDependencies": {
23
+ "@revideo/cli": "0.5.10",
24
+ "@revideo/ui": "0.5.10",
25
+ "typescript": "5.5.4",
26
+ "vite": "^4.5"
27
+ }
28
+ }
@@ -0,0 +1,157 @@
1
+ import { renderPartialVideo } from '@revideo/renderer';
2
+ import { mergeAudioWithVideo, concatenateMedia } from '@revideo/ffmpeg';
3
+ import chromium from '@sparticuz/chromium';
4
+ import * as AWS from "aws-sdk";
5
+ import * as fs from "fs";
6
+
7
+ AWS.config.update({ region: 'us-east-1' });
8
+ chromium.setHeadlessMode = true;
9
+
10
+ const s3 = new AWS.S3();
11
+ const lambda = new AWS.Lambda({
12
+ httpOptions: {
13
+ timeout: 900000, // 15 min timeout
14
+ },
15
+ });
16
+
17
+ export const handler = async (event: any, context: any) => {
18
+ const { jobType, jobId } = event;
19
+
20
+ if(jobType == "partialRender"){
21
+
22
+ try {
23
+ const { workerId, numWorkers, variables } = event;
24
+
25
+ const { audioFile, videoFile } = await renderPartialVideo({
26
+ projectFile: './src/project.ts',
27
+ workerId: workerId,
28
+ numWorkers: numWorkers,
29
+ variables: variables,
30
+ settings: { logProgress: true, viteBasePort: 5000, outDir: "/tmp/output", viteConfig: { cacheDir: "/tmp/.vite"}, puppeteer: {
31
+ headless: chromium.headless,
32
+ executablePath: await chromium.executablePath(),
33
+ args: chromium.args.filter(arg =>
34
+ !arg.startsWith('--single-process') &&
35
+ !arg.startsWith('--use-gl=angle') &&
36
+ !arg.startsWith('--use-angle=swiftshader') &&
37
+ !arg.startsWith('--disable-features=')
38
+ )
39
+ }}
40
+ });
41
+
42
+ await Promise.all([uploadFileToBucket(audioFile, `${jobId}-audio-${workerId}.wav`), uploadFileToBucket(videoFile, `${jobId}-video-${workerId}.mp4`)]);
43
+
44
+ return {
45
+ statusCode: 200,
46
+ body: JSON.stringify({
47
+ audioUrl: `https://${process.env.REVIDEO_BUCKET_NAME}.s3.amazonaws.com/${jobId}-audio-${workerId}.wav`,
48
+ videoUrl: `https://${process.env.REVIDEO_BUCKET_NAME}.s3.amazonaws.com/${jobId}-video-${workerId}.mp4`
49
+ }),
50
+ };
51
+ } catch(err) {
52
+ return {
53
+ statusCode: 500,
54
+ body: JSON.stringify({
55
+ error: `Error during partial render: ${err}`
56
+ })
57
+ }
58
+ }
59
+
60
+
61
+ } else {
62
+ const { numWorkers, variables, jobId } = event;
63
+
64
+ try {
65
+
66
+ const renderPromises = [];
67
+ for (let i = 0; i < numWorkers; i++) {
68
+ console.log("invoking worker", i);
69
+ renderPromises.push(invokePartialRender(variables, i, numWorkers, jobId));
70
+ }
71
+
72
+ console.log("now waiting");
73
+
74
+ const results = await Promise.all(renderPromises);
75
+ console.log("obtained results", results);
76
+ const audios = results.map(result => result.audioUrl);
77
+ const videos = results.map(result => result.videoUrl);
78
+
79
+ console.log("videos", videos);
80
+ await Promise.all([
81
+ concatenateMedia(audios, `/tmp/${jobId}-audio.wav`),
82
+ concatenateMedia(videos, `/tmp/${jobId}-visuals.mp4`)
83
+ ]);
84
+
85
+ await mergeAudioWithVideo(`/tmp/${jobId}-audio.wav`, `/tmp/${jobId}-visuals.mp4`, `/tmp/${jobId}.mp4`);
86
+ await uploadFileToBucket(`/tmp/${jobId}.mp4`, `${jobId}.mp4`);
87
+
88
+ return {
89
+ statusCode: 200,
90
+ body: JSON.stringify({
91
+ resultUrl: `https://${process.env.REVIDEO_BUCKET_NAME}.s3.amazonaws.com/${jobId}.mp4`,
92
+ }),
93
+ };
94
+ } catch(err){
95
+ return {
96
+ statusCode: 500,
97
+ body: JSON.stringify({
98
+ error: `An error occured during rendering: ${err}`
99
+ }),
100
+ };
101
+ }
102
+
103
+
104
+ }
105
+
106
+ };
107
+
108
+ async function uploadFileToBucket(localPath: string, destinationPath: string) {
109
+ const fileContent = await fs.promises.readFile(localPath);
110
+
111
+ const params = {
112
+ Bucket: process.env.REVIDEO_BUCKET_NAME,
113
+ Key: destinationPath,
114
+ Body: fileContent,
115
+ };
116
+
117
+ try {
118
+ const data = await s3.upload(params).promise();
119
+ console.log(`File uploaded successfully. ${data.Location}`);
120
+ } catch (err) {
121
+ console.error("Error uploading file: ", err);
122
+ }
123
+ }
124
+
125
+ async function invokePartialRender(variables: any, workerId: number, numWorkers: number, jobId: string){
126
+ const params = {
127
+ FunctionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
128
+ InvocationType: 'RequestResponse',
129
+ LogType: 'None',
130
+ Payload: JSON.stringify({
131
+ variables: variables,
132
+ workerId: workerId,
133
+ numWorkers: numWorkers,
134
+ jobId: jobId,
135
+ jobType: "partialRender"
136
+ }),
137
+ };
138
+
139
+ try {
140
+ const data = await lambda.invoke(params).promise();
141
+ const payload = JSON.parse(data.Payload as string);
142
+ console.log('Lambda invoke result:', payload);
143
+
144
+ // Parse the body string to JSON to access the audioUrl and videoUrl
145
+ const body = JSON.parse(payload.body);
146
+
147
+ if(payload.statusCode !== 200){
148
+ throw Error(body.message); // Use the parsed body for error messages
149
+ }
150
+
151
+ return { audioUrl: body.audioUrl, videoUrl: body.videoUrl };
152
+
153
+ } catch (error) {
154
+ console.error("Error during partial render:", error);
155
+ throw error;
156
+ }
157
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "version": 0,
3
+ "shared": {
4
+ "background": null,
5
+ "range": [
6
+ 0,
7
+ null
8
+ ],
9
+ "size": {
10
+ "x": 1920,
11
+ "y": 1080
12
+ },
13
+ "audioOffset": 0
14
+ },
15
+ "preview": {
16
+ "fps": 30,
17
+ "resolutionScale": 1
18
+ },
19
+ "rendering": {
20
+ "fps": 30,
21
+ "resolutionScale": 1,
22
+ "colorSpace": "srgb",
23
+ "exporter": {
24
+ "name": "@revideo/core/wasm",
25
+ "options": {}
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,7 @@
1
+ import {makeProject} from '@revideo/core';
2
+
3
+ import example from './scenes/example?scene';
4
+
5
+ export default makeProject({
6
+ scenes: [example],
7
+ });
@@ -0,0 +1,17 @@
1
+ import {renderVideo} from '@revideo/renderer';
2
+
3
+ async function render() {
4
+ console.log('Rendering video...');
5
+
6
+ // This is the main function that renders the video
7
+ console.time("render");
8
+ const file = await renderVideo({
9
+ projectFile: './src/project.ts',
10
+ settings: {logProgress: true},
11
+ });
12
+ console.timeEnd("render");
13
+
14
+ console.log(`Rendered video to ${file}`);
15
+ }
16
+
17
+ render();
@@ -0,0 +1 @@
1
+ /// <reference types="@revideo/core/project" />
@@ -0,0 +1,5 @@
1
+ {
2
+ "version": 0,
3
+ "timeEvents": [],
4
+ "seed": 307431050
5
+ }
@@ -0,0 +1,30 @@
1
+ import {Audio, Img, Txt, Video, makeScene2D} from '@revideo/2d';
2
+ import {createRef, createSignal, useScene, waitFor} from '@revideo/core';
3
+
4
+ export default makeScene2D(function* (view) {
5
+ const fontSize = createSignal(50);
6
+
7
+ yield view.add(
8
+ <>
9
+ <Video
10
+ src={'https://revideo-example-assets.s3.amazonaws.com/beach-4.mp4'}
11
+ size={['100%', '100%']}
12
+ play={true}
13
+ decoder={"ffmpeg"} // ffmpeg is more reliable than webcodecs decoder
14
+ />
15
+ <Audio
16
+ src={'https://revideo-example-assets.s3.amazonaws.com/chill-beat-2.mp3'}
17
+ play={true}
18
+ />
19
+ </>,
20
+ );
21
+
22
+ yield* waitFor(1);
23
+
24
+ yield view.add(<Txt fill={"white"} fontSize={fontSize}>{useScene().variables.get("message", "Hello World!")()}</Txt>);
25
+
26
+ yield* fontSize(100, 4); // increase font size to 100 in 4 seconds
27
+
28
+ yield* waitFor(25); // wait for 25 seconds more
29
+
30
+ });
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "@revideo/2d/tsconfig.project.json",
3
+ "include": ["src"],
4
+ "compilerOptions": {
5
+ "noEmit": false,
6
+ "outDir": "dist",
7
+ "module": "CommonJS",
8
+ "esModuleInterop": true,
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ import {defineConfig} from 'vite';
2
+ import motionCanvas from '@revideo/vite-plugin';
3
+
4
+
5
+ export default defineConfig({
6
+ plugins: [
7
+ motionCanvas(),
8
+ ]
9
+ });
@@ -0,0 +1,84 @@
1
+ # Create Short Videos from Reddit Posts 🪄
2
+
3
+ This project uses [Revideo](https://github.com/redotvideo/revideo) to automatically generate short videos from Reddit Post urls. Here is a (low resolution) example generated from this [Reddit Post](https://www.reddit.com/r/careeradvice/comments/1bn9do3/how_do_i_leave_a_job_i_hate_but_its_comfortable/):
4
+
5
+
6
+
7
+ https://github.com/user-attachments/assets/485df630-7862-4862-affe-7f510279f1fa
8
+
9
+
10
+ <br/>
11
+
12
+
13
+
14
+ <br/>
15
+
16
+
17
+ Two code files do most of the heavy lifting here:
18
+
19
+ - `src/render.ts` is a node process that fetches the contents of the provided Reddit post url, generates a voiceover using [ElevenLabs](https://elevenlabs.io/), gets timestamps for the voiceover and organizes all of this metadata in `./metadata.json`. Finally, it calls `renderVideo` to render & export the project using a headless browser.
20
+ - `src/scenes/example.tsx` defines the animation flow and audio of our video
21
+ <br/>
22
+ <br/>
23
+
24
+
25
+
26
+ ## Getting Started
27
+
28
+ First, you should clone the repository and install all dependencies:
29
+
30
+ ```bash
31
+ git clone https://github.com/redotvideo/examples.git
32
+ cd reddit-post-video
33
+ npm install
34
+ ```
35
+
36
+ You can now look at the example project using the editor:
37
+
38
+ ```bash
39
+ npm start
40
+ ```
41
+ <br/>
42
+ <br/>
43
+
44
+
45
+ ## Create your own video
46
+
47
+ To create your own video, you should first set up API keys for ElevenLabs (to generate voiceovers) and Deepgram (to get timestamps for subtitles):
48
+
49
+ ```
50
+ export ELEVEN_API_KEY=<your-elevenlabs-key>
51
+ export DEEPGRAM_API_KEY=<your-deepgram-key>
52
+ ```
53
+
54
+
55
+ You now have two options: You can either directly render and export a video, or first generate its metadata and voiceover and preview in the editor before exporting.
56
+
57
+ #### Option 1: Generate metadata, preview and render in editor
58
+
59
+ To generate metadata, run the following command:
60
+
61
+ ```bash
62
+ tsc && node dist/render.js --post <reddit-post-url> --onlyMetadata
63
+ ```
64
+
65
+ This saves the voiceover to `./output/audio.wav` and your metadata to `./metadata.json`. You can now preview your video by starting the editor, and export your video by clicking the "Render" button in the browser:
66
+
67
+ ```bash
68
+ npm start
69
+ ```
70
+
71
+ #### Option 2: Render video through function call
72
+
73
+ If you don't want to preview, but render directly, you can omit the `--onlyMetadata` flag. This will call the `renderVideo` function:
74
+
75
+ ```bash
76
+ tsc && node dist/src/renderScript.js --post <reddit-post-url>
77
+ ```
78
+
79
+ #### Additional parameters
80
+
81
+ You can modify the text color and voice of your video using the following flags:
82
+
83
+ - `--voice Daniel`: default is Sarah
84
+ - `--textcolor yellow`: default is red