@revideo/create 0.4.9-alpha.1041 → 0.4.9-test.1044

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.
@@ -0,0 +1,157 @@
1
+ import { createClient } from "@deepgram/sdk";
2
+ import { renderVideo } from "@revideo/renderer";
3
+ import axios from "axios";
4
+ import * as fs from "fs";
5
+ import yargs from "yargs";
6
+ import { hideBin } from "yargs/helpers";
7
+
8
+ export interface Word {
9
+ punctuated_word: string;
10
+ start: number;
11
+ end: number;
12
+ }
13
+
14
+ export interface MetaData {
15
+ audioFile: string;
16
+ text: Word[];
17
+ textColor: string;
18
+ }
19
+
20
+ export const deepgramClient = createClient(
21
+ process.env.DEEPGRAM_API_KEY,
22
+ );
23
+
24
+ async function getPostText(postUrl: string) {
25
+ const response = await axios.get(postUrl + ".json");
26
+ const responseData = response.data;
27
+
28
+ return (
29
+ responseData[0].data.children[0].data.title +
30
+ ".\n" +
31
+ responseData[0].data.children[0].data.selftext
32
+ );
33
+ }
34
+
35
+ async function voiceNameToId(voiceName: string): Promise<string | null> {
36
+ const url = "https://api.elevenlabs.io/v1/voices";
37
+ const headers = {
38
+ "Content-Type": "application/json",
39
+ "xi-api-key": process.env.ELEVEN_API_KEY,
40
+ };
41
+
42
+ try {
43
+ const response = await axios.get(url, { headers });
44
+ const voices = response.data.voices;
45
+ const voice = voices.find((v: any) => v.name === voiceName);
46
+ return voice ? voice.voice_id : null;
47
+ } catch (error) {
48
+ console.error("Error fetching voices:", error);
49
+ throw error;
50
+ }
51
+ }
52
+
53
+ async function textToSpeech(post: string, voiceId: string, modelId: string) {
54
+ const url = `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`;
55
+ const headers = {
56
+ "Content-Type": "application/json",
57
+ "xi-api-key": process.env.ELEVEN_API_KEY,
58
+ };
59
+ const data = {
60
+ model_id: modelId,
61
+ text: post,
62
+ };
63
+
64
+ try {
65
+ const response = await axios.post(url, data, {
66
+ headers,
67
+ responseType: "arraybuffer",
68
+ });
69
+ return response.data;
70
+ } catch (error) {
71
+ console.error("Error making text-to-speech request:", error);
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ export async function speechToText(filePath: string) {
77
+ const { result } = await deepgramClient.listen.prerecorded.transcribeFile(
78
+ fs.readFileSync(filePath),
79
+ {
80
+ model: "nova-2",
81
+ smart_format: true,
82
+ },
83
+ );
84
+
85
+ return result;
86
+ }
87
+
88
+ async function main() {
89
+ const argv = await yargs(hideBin(process.argv)).options({
90
+ voice: {
91
+ alias: "v",
92
+ describe: "The name of the eleven labs voice to use",
93
+ type: "string",
94
+ default: "Sarah",
95
+ },
96
+ post: {
97
+ alias: "p",
98
+ describe: "The Reddit post URL",
99
+ type: "string",
100
+ default:
101
+ "https://www.reddit.com/r/TrueOffMyChest/comments/1bllfgk/i_hate_having_old_parents/",
102
+ },
103
+ textcolor: {
104
+ alias: "c",
105
+ describe: "color of the text",
106
+ type: "string",
107
+ default: "red",
108
+ },
109
+ onlyMetadata: {
110
+ alias: "m",
111
+ describe: "only save metadata and do not render the video",
112
+ type: "boolean",
113
+ default: false,
114
+ },
115
+ }).argv;
116
+
117
+ const url = argv.post;
118
+ const voiceName = argv.voice;
119
+ const textColor = argv.textcolor;
120
+
121
+ const post = await getPostText(url);
122
+ const voiceId = await voiceNameToId(voiceName);
123
+ const ttsRes = await textToSpeech(post, voiceId, "eleven_multilingual_v2");
124
+
125
+ await fs.writeFileSync("./output/audio.wav", ttsRes);
126
+
127
+ const transcriptionResponse = await speechToText("./output/audio.wav");
128
+ const words =
129
+ transcriptionResponse.results.channels[0].alternatives[0].words.map(
130
+ (word: any) => ({
131
+ punctuated_word: word.punctuated_word,
132
+ start: word.start,
133
+ end: word.end,
134
+ }),
135
+ );
136
+
137
+ const metaData: MetaData = {
138
+ audioFile: "./output/audio.wav",
139
+ text: words,
140
+ textColor: textColor,
141
+ };
142
+
143
+ fs.writeFileSync("./metadata.json", JSON.stringify(metaData, null, 2));
144
+ console.log("saved metadata to ./metadata.json");
145
+
146
+ if (!argv.onlyMetadata) {
147
+ const file = renderVideo({
148
+ projectFile: "./vite.config.ts",
149
+ variables: { data: metaData },
150
+ settings: { logProgress: true }
151
+ });
152
+
153
+ console.log(`rendered video to ${file}`)
154
+ }
155
+ }
156
+
157
+ main();
@@ -0,0 +1 @@
1
+ /// <reference types="@revideo/core/project" />
@@ -0,0 +1,5 @@
1
+ {
2
+ "version": 0,
3
+ "timeEvents": [],
4
+ "seed": 3377806303
5
+ }
@@ -0,0 +1,74 @@
1
+ import { Audio, Txt, Video, View2D, makeScene2D } from "@revideo/2d";
2
+ import { createRef, useScene, waitFor } from "@revideo/core";
3
+ import { MetaData, Word } from "../render";
4
+
5
+ export default makeScene2D(function* (view) {
6
+ const videoRef = createRef<Video>();
7
+ const data: MetaData = useScene().variables.get("data", {
8
+ audioFile: "hi",
9
+ text: [],
10
+ textColor: "red",
11
+ })();
12
+
13
+ yield view.add(
14
+ <>
15
+ <Video
16
+ ref={videoRef}
17
+ volume={0}
18
+ src={"https://revideo-example-assets.s3.amazonaws.com/minecraft.mp4"}
19
+ play={true}
20
+ size={"100%"}
21
+ />
22
+ <Audio src={data.audioFile} play={true} />
23
+ </>,
24
+ );
25
+
26
+ let waitBefore = data.text[0].start;
27
+
28
+ for (let i = 0; i < data.text.length; i++) {
29
+ const currentClip = data.text[i];
30
+ const nextClipStart =
31
+ i < data.text.length - 1 ? data.text[i + 1].start : null;
32
+ const isLastClip = i === data.text.length - 1;
33
+ const waitAfter = isLastClip ? 1 : 0;
34
+ yield* displayTextClip(
35
+ currentClip,
36
+ waitBefore,
37
+ waitAfter,
38
+ view,
39
+ data.textColor,
40
+ );
41
+ waitBefore = nextClipStart !== null ? nextClipStart - currentClip.end : 0;
42
+ }
43
+ });
44
+
45
+ function* displayTextClip(
46
+ textClip: Word,
47
+ waitBefore: number,
48
+ waitAfter: number,
49
+ view: View2D,
50
+ textColor: string,
51
+ ) {
52
+ const textRef = createRef<Txt>();
53
+ yield* waitFor(waitBefore);
54
+ view.add(
55
+ <Txt
56
+ fontSize={100}
57
+ fontWeight={800}
58
+ ref={textRef}
59
+ fontFamily={"Raleway"}
60
+ textWrap={true}
61
+ textAlign={"center"}
62
+ fill={textColor}
63
+ width={"70%"}
64
+ lineWidth={2}
65
+ shadowOffset={10}
66
+ shadowBlur={30}
67
+ shadowColor={"black"}
68
+ >
69
+ {textClip.punctuated_word}
70
+ </Txt>,
71
+ );
72
+ yield* waitFor(textClip.end - textClip.start + waitAfter);
73
+ textRef().remove();
74
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "@revideo/2d/tsconfig.project.json",
3
+ "include": ["src"],
4
+ "compilerOptions": {
5
+ "noEmit": false,
6
+ "outDir": "dist",
7
+ "module": "CommonJS"
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from "vite";
2
+ import motionCanvas from "@revideo/vite-plugin";
3
+
4
+ export default defineConfig({
5
+ plugins: [motionCanvas()],
6
+ });
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@radix-ui/react-navigation-menu": "^1.1.4",
13
- "@revideo/player-react": "0.4.8",
13
+ "@revideo/player-react": "0.5.0",
14
14
  "class-variance-authority": "^0.7.0",
15
15
  "lucide-react": "^0.378.0",
16
16
  "next": "14.2.3",
@@ -9,15 +9,15 @@
9
9
  "render": "tsc && node dist/render.js"
10
10
  },
11
11
  "dependencies": {
12
- "@revideo/core": "0.4.8",
13
- "@revideo/2d": "0.4.8",
14
- "@revideo/renderer": "0.4.8",
15
- "@revideo/vite-plugin": "0.4.8",
16
- "@revideo/ffmpeg": "0.4.8"
12
+ "@revideo/core": "0.5.0",
13
+ "@revideo/2d": "0.5.0",
14
+ "@revideo/renderer": "0.5.0",
15
+ "@revideo/vite-plugin": "0.5.0",
16
+ "@revideo/ffmpeg": "0.5.0"
17
17
  },
18
18
  "devDependencies": {
19
- "@revideo/ui": "0.4.8",
20
- "@revideo/cli": "0.4.8",
19
+ "@revideo/ui": "0.5.0",
20
+ "@revideo/cli": "0.5.0",
21
21
  "typescript": "^5.2.2",
22
22
  "vite": "^4.5"
23
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revideo/create",
3
- "version": "0.4.9-alpha.1041+79279b5a",
3
+ "version": "0.4.9-test.1044+1766a15f",
4
4
  "description": "Quickly scaffold revideo projects",
5
5
  "main": "index.js",
6
6
  "author": "revideo",
@@ -20,17 +20,17 @@
20
20
  "url": "https://github.com/havenhq/revideo.git"
21
21
  },
22
22
  "devDependencies": {
23
- "@revideo/2d": "^0.4.9-alpha.1041+79279b5a",
24
- "@revideo/core": "^0.4.9-alpha.1041+79279b5a",
25
- "@revideo/ffmpeg": "^0.4.9-alpha.1041+79279b5a",
26
- "@revideo/renderer": "^0.4.9-alpha.1041+79279b5a",
27
- "@revideo/ui": "^0.4.9-alpha.1041+79279b5a",
28
- "@revideo/vite-plugin": "^0.4.9-alpha.1041+79279b5a"
23
+ "@revideo/2d": "^0.4.9-test.1044+1766a15f",
24
+ "@revideo/core": "^0.4.9-test.1044+1766a15f",
25
+ "@revideo/ffmpeg": "^0.4.9-test.1044+1766a15f",
26
+ "@revideo/renderer": "^0.4.9-test.1044+1766a15f",
27
+ "@revideo/ui": "^0.4.9-test.1044+1766a15f",
28
+ "@revideo/vite-plugin": "^0.4.9-test.1044+1766a15f"
29
29
  },
30
30
  "dependencies": {
31
- "@revideo/telemetry": "^0.4.9-alpha.1041+79279b5a",
31
+ "@revideo/telemetry": "^0.4.9-test.1044+1766a15f",
32
32
  "minimist": "^1.2.8",
33
33
  "prompts": "^2.4.2"
34
34
  },
35
- "gitHead": "79279b5a45a6cadf3a833879198899bbe8279e4c"
35
+ "gitHead": "1766a15fae16a04405f9ec41273e2d7a4beb5b00"
36
36
  }