@revideo/renderer 0.3.7-alpha.975 → 0.3.7-beta.987

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 (46) hide show
  1. package/lib/client/FFmpegExporterClient.d.ts +46 -0
  2. package/lib/client/FFmpegExporterClient.d.ts.map +1 -0
  3. package/lib/client/FFmpegExporterClient.js +118 -0
  4. package/lib/client/ffpmeg.d.ts +3 -0
  5. package/lib/client/ffpmeg.d.ts.map +1 -0
  6. package/lib/client/ffpmeg.js +9 -0
  7. package/lib/client/index.d.ts +3 -0
  8. package/lib/client/index.d.ts.map +1 -0
  9. package/lib/client/index.js +9 -0
  10. package/lib/index.js +5 -0
  11. package/lib/index.js.map +1 -0
  12. package/lib/server/RendererPlugin.d.ts +3 -0
  13. package/lib/server/RendererPlugin.d.ts.map +1 -0
  14. package/lib/server/RendererPlugin.js +50 -0
  15. package/lib/server/ffmpeg/FFmpegBridge.d.ts +22 -0
  16. package/lib/server/ffmpeg/FFmpegBridge.d.ts.map +1 -0
  17. package/lib/server/ffmpeg/FFmpegBridge.js +92 -0
  18. package/lib/server/ffmpeg/FFmpegExporterServer.d.ts +39 -0
  19. package/lib/server/ffmpeg/FFmpegExporterServer.d.ts.map +1 -0
  20. package/lib/server/ffmpeg/FFmpegExporterServer.js +264 -0
  21. package/lib/server/ffmpeg/FFmpegPlugin.d.ts +3 -0
  22. package/lib/server/ffmpeg/FFmpegPlugin.d.ts.map +1 -0
  23. package/lib/server/ffmpeg/FFmpegPlugin.js +23 -0
  24. package/lib/server/ffmpeg/ImageStream.d.ts +10 -0
  25. package/lib/server/ffmpeg/ImageStream.d.ts.map +1 -0
  26. package/lib/server/ffmpeg/ImageStream.js +25 -0
  27. package/lib/server/ffmpeg/VideoFrameExtractor.d.ts +41 -0
  28. package/lib/server/ffmpeg/VideoFrameExtractor.d.ts.map +1 -0
  29. package/lib/server/ffmpeg/VideoFrameExtractor.js +148 -0
  30. package/lib/server/ffmpeg/utils.d.ts +8 -0
  31. package/lib/server/ffmpeg/utils.d.ts.map +1 -0
  32. package/lib/server/ffmpeg/utils.js +141 -0
  33. package/lib/server/render-video.d.ts +32 -9
  34. package/lib/server/render-video.d.ts.map +1 -1
  35. package/lib/server/render-video.js +66 -57
  36. package/lib/server/renderVideo.d.ts +10 -0
  37. package/lib/server/renderVideo.d.ts.map +1 -0
  38. package/lib/server/renderVideo.js +124 -0
  39. package/lib/server/renderer-plugin.d.ts +1 -1
  40. package/lib/server/renderer-plugin.d.ts.map +1 -1
  41. package/lib/server/renderer-plugin.js +4 -4
  42. package/lib/server/tsconfig.tsbuildinfo +1 -1
  43. package/lib/server/utils.d.ts +3 -0
  44. package/lib/server/utils.d.ts.map +1 -0
  45. package/lib/server/utils.js +20 -0
  46. package/package.json +4 -4
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSampleRate = exports.checkForAudioStream = exports.mergeAudioWithVideo = exports.doesFileExist = exports.getVideoDuration = exports.createSilentAudioFile = exports.concatenateMedia = void 0;
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+ const os = require("os");
7
+ const ffmpeg = require("fluent-ffmpeg");
8
+ const uuid_1 = require("uuid");
9
+ async function concatenateMedia(files, outputFile) {
10
+ const tempFile = path.join(os.tmpdir(), `${(0, uuid_1.v4)()}.txt`);
11
+ const fileContent = files.map(file => `file '${file.replace(/'/g, "\\'")}'`).join('\n');
12
+ await fs.promises.writeFile(tempFile, fileContent);
13
+ return new Promise((resolve, reject) => {
14
+ const ffmpegCommand = ffmpeg();
15
+ ffmpegCommand.input(tempFile)
16
+ .inputOptions([
17
+ '-f concat',
18
+ '-safe 0'
19
+ ])
20
+ .outputOptions([
21
+ '-c copy'
22
+ ])
23
+ .on('error', (err) => {
24
+ console.error('Error:', err);
25
+ fs.promises.unlink(tempFile).catch(console.error);
26
+ reject(err); // Reject the promise on error
27
+ })
28
+ .on('end', () => {
29
+ console.log('Concatenation finished.');
30
+ fs.promises.unlink(tempFile).catch(console.error);
31
+ resolve(); // Resolve the promise on successful completion
32
+ })
33
+ .save(outputFile);
34
+ });
35
+ }
36
+ exports.concatenateMedia = concatenateMedia;
37
+ async function createSilentAudioFile(filePath, duration) {
38
+ return new Promise((resolve, reject) => {
39
+ ffmpeg()
40
+ .addInput('anullsrc')
41
+ .audioChannels(2)
42
+ .audioFrequency(48000)
43
+ .outputOptions(['-t', duration.toString(), '-acodec', 'aac'])
44
+ .on('end', () => {
45
+ console.log(`Silent audio file created at ${filePath}`);
46
+ resolve(filePath);
47
+ })
48
+ .on('error', (err) => {
49
+ console.error('Error creating silent audio file:', err);
50
+ reject(err);
51
+ })
52
+ .save(filePath);
53
+ });
54
+ }
55
+ exports.createSilentAudioFile = createSilentAudioFile;
56
+ async function getVideoDuration(filePath) {
57
+ return new Promise((resolve, reject) => {
58
+ ffmpeg.ffprobe(filePath, (err, metadata) => {
59
+ if (err) {
60
+ reject(err);
61
+ return;
62
+ }
63
+ const duration = metadata.format.duration;
64
+ if (duration) {
65
+ resolve(duration);
66
+ }
67
+ else {
68
+ reject(new Error('Could not determine video duration.'));
69
+ }
70
+ });
71
+ });
72
+ }
73
+ exports.getVideoDuration = getVideoDuration;
74
+ async function doesFileExist(filePath) {
75
+ try {
76
+ await fs.promises.access(filePath, fs.constants.F_OK);
77
+ return true;
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ exports.doesFileExist = doesFileExist;
84
+ async function mergeAudioWithVideo(audioPath, videoPath, outputPath) {
85
+ return new Promise((resolve, reject) => {
86
+ ffmpeg()
87
+ .input(videoPath)
88
+ .input(audioPath)
89
+ .outputOptions([
90
+ '-c:v',
91
+ 'copy',
92
+ '-c:a',
93
+ 'aac',
94
+ '-strict',
95
+ 'experimental',
96
+ ])
97
+ .on('end', () => {
98
+ resolve();
99
+ console.log(`\nRendered successfully! Video saved to: ${outputPath}`);
100
+ })
101
+ .on('error', err => {
102
+ console.error(`Error merging video and audio: ${err.message}`);
103
+ reject(err);
104
+ })
105
+ .save(outputPath);
106
+ });
107
+ }
108
+ exports.mergeAudioWithVideo = mergeAudioWithVideo;
109
+ async function checkForAudioStream(file) {
110
+ return new Promise((resolve, reject) => {
111
+ ffmpeg.ffprobe(file, (err, metadata) => {
112
+ if (err) {
113
+ console.error(`error checking for audioStream for file ${file}`, err);
114
+ reject(err);
115
+ return;
116
+ }
117
+ const audioStreams = metadata.streams.filter(s => s.codec_type === 'audio');
118
+ resolve(audioStreams.length > 0);
119
+ });
120
+ });
121
+ }
122
+ exports.checkForAudioStream = checkForAudioStream;
123
+ async function getSampleRate(filePath) {
124
+ return new Promise((resolve, reject) => {
125
+ ffmpeg.ffprobe(filePath, (err, metadata) => {
126
+ if (err) {
127
+ reject(err);
128
+ return;
129
+ }
130
+ const audioStream = metadata.streams.find(s => s.codec_type === 'audio');
131
+ if (audioStream && audioStream.sample_rate) {
132
+ resolve(audioStream.sample_rate);
133
+ }
134
+ else {
135
+ reject(new Error('No audio stream found'));
136
+ }
137
+ });
138
+ });
139
+ }
140
+ exports.getSampleRate = getSampleRate;
141
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zZXJ2ZXIvZmZtcGVnL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekIseUJBQXlCO0FBQ3pCLHdDQUF3QztBQUN4QywrQkFBb0M7QUFHN0IsS0FBSyxVQUFVLGdCQUFnQixDQUFDLEtBQWUsRUFBRSxVQUFrQjtJQUN0RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLElBQUEsU0FBTSxHQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEYsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFbkQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLGFBQWEsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUUvQixhQUFhLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQzthQUMxQixZQUFZLENBQUM7WUFDWixXQUFXO1lBQ1gsU0FBUztTQUNWLENBQUM7YUFDRCxhQUFhLENBQUM7WUFDYixTQUFTO1NBQ1YsQ0FBQzthQUNELEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM3QixFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFL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
@@ -1,26 +1,49 @@
1
1
  import { FfmpegSettings } from '@revideo/ffmpeg';
2
2
  import { BrowserLaunchArgumentOptions } from 'puppeteer';
3
- export interface RenderVideoSettings {
4
- name?: string;
3
+ import { ServerOptions } from 'vite';
4
+ export interface RenderSettings {
5
+ outFile?: `${string}.mp4`;
6
+ outDir?: string;
5
7
  range?: [number, number];
6
8
  ffmpeg?: FfmpegSettings;
7
9
  puppeteer?: BrowserLaunchArgumentOptions;
8
10
  workers?: number;
9
11
  dimensions?: [number, number];
10
12
  logProgress?: boolean;
13
+ /**
14
+ * When using multiple workers, this is the port of the first worker.
15
+ * Each worker will increment the port by 1.
16
+ * If the port is already in use, the next port will be used.
17
+ *
18
+ * Default is 9000
19
+ */
11
20
  viteBasePort?: number;
21
+ viteServerOptions?: Omit<ServerOptions, 'port'>;
22
+ progressCallback?: (worker: number, progress: number) => void;
23
+ }
24
+ interface RenderVideoProps {
25
+ projectFile: string;
26
+ variables?: Record<string, unknown>;
27
+ settings?: RenderSettings;
12
28
  }
13
- export declare const renderPartialVideo: (configFile: string, workerId: number, numWorkers: number, params?: Record<string, unknown>, progressCallback?: ((worker: number, progress: number) => void) | undefined, settings?: RenderVideoSettings) => Promise<{
14
- audioFile: string;
15
- videoFile: string;
16
- }>;
17
29
  /**
18
30
  * Renders a video to a file.
19
- * @param configFile - Path to the vite config file (vite.config.ts).
20
- * @param params - Parameters to pass to your project (see https://docs.re.video/parameterized-video)
31
+ * @param projectFile - Path to the project.ts file.
32
+ * @param variables - Variables to pass to your project (see https://docs.re.video/parameterized-video)
21
33
  * @param progressCallback - Callback function to track rendering progress. Progress is a number between 0 and 1.
22
34
  * @param settings - Settings for the rendering process.
23
35
  * @returns - Path to the rendered video file.
24
36
  */
25
- export declare const renderVideo: (configFile: string, params?: Record<string, unknown>, progressCallback?: ((worker: number, progress: number) => void) | undefined, settings?: RenderVideoSettings) => Promise<string>;
37
+ export declare const renderVideo: ({ projectFile, variables, settings, }: RenderVideoProps) => Promise<string>;
38
+ interface RenderPartialVideoProps extends RenderVideoProps {
39
+ workerId: number;
40
+ settings: {
41
+ workers: number;
42
+ } & RenderSettings;
43
+ }
44
+ export declare const renderPartialVideo: ({ projectFile, variables, settings, workerId, }: RenderPartialVideoProps) => Promise<{
45
+ audioFile: string;
46
+ videoFile: string;
47
+ }>;
48
+ export {};
26
49
  //# sourceMappingURL=render-video.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-video.d.ts","sourceRoot":"","sources":["../../server/render-video.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAMf,MAAM,iBAAiB,CAAC;AAIzB,OAAkB,EAAU,4BAA4B,EAAC,MAAM,WAAW,CAAC;AA8B3E,MAAM,WAAW,mBAAmB;IAElC,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzB,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAwPD,eAAO,MAAM,kBAAkB,eACjB,MAAM,YACR,MAAM,cACJ,MAAM,WACT,OAAO,MAAM,EAAE,OAAO,CAAC,+BACJ,MAAM,YAAY,MAAM,KAAK,IAAI,0BACnD,mBAAmB;;;EA4B9B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,eACV,MAAM,WACT,OAAO,MAAM,EAAE,OAAO,CAAC,+BACJ,MAAM,YAAY,MAAM,KAAK,IAAI,0BACnD,mBAAmB,oBAsC9B,CAAC"}
1
+ {"version":3,"file":"render-video.d.ts","sourceRoot":"","sources":["../../server/render-video.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAMf,MAAM,iBAAiB,CAAC;AAKzB,OAAkB,EAAU,4BAA4B,EAAC,MAAM,WAAW,CAAC;AAE3E,OAAO,EAAC,aAAa,EAA8B,MAAM,MAAM,CAAC;AA4BhE,MAAM,WAAW,cAAc;IAE7B,OAAO,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC;IAG1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzB,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,SAAS,CAAC,EAAE,4BAA4B,CAAC;IAEzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAChD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/D;AAyRD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,0CAIrB,gBAAgB,oBAwClB,CAAC;AAEF,UAAU,uBAAwB,SAAQ,gBAAgB;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,GAAG,cAAc,CAAC;CAC9C;AAED,eAAO,MAAM,kBAAkB,oDAK5B,uBAAuB;;;EAyBzB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderVideo = exports.renderPartialVideo = void 0;
3
+ exports.renderPartialVideo = exports.renderVideo = void 0;
4
4
  const ffmpeg_1 = require("@revideo/ffmpeg");
5
+ const vite_plugin_1 = require("@revideo/vite-plugin");
5
6
  const fs = require("fs");
6
7
  const os = require("os");
7
8
  const path = require("path");
@@ -25,28 +26,35 @@ function buildUrl(port, fileName, workerId, totalNumOfWorkers, range = [0, Infin
25
26
  /**
26
27
  * Starts the vite server and creates a puppeteer browser instance
27
28
  */
28
- async function initBrowserAndServer(fixedPort, resolvedConfigPath, settings, params) {
29
- const args = settings.puppeteer?.args ?? [];
30
- args.includes('--single-process') || args.push('--single-process');
29
+ async function initBrowserAndServer(fixedPort, projectFile, outputFolderName, settings, variables) {
30
+ const resolvedProjectPath = path.join(process.cwd(), projectFile);
31
31
  const [browser, server] = await Promise.all([
32
- puppeteer_1.default.launch({ headless: true, ...settings.puppeteer, args }),
32
+ puppeteer_1.default.launch({ headless: true, ...settings.puppeteer }),
33
33
  (0, vite_1.createServer)({
34
- configFile: resolvedConfigPath,
34
+ configFile: false,
35
35
  server: {
36
+ ...settings.viteServerOptions,
36
37
  port: fixedPort,
38
+ hmr: false,
37
39
  },
38
- plugins: [(0, renderer_plugin_1.rendererPlugin)(params, settings.ffmpeg)],
40
+ plugins: [
41
+ (0, vite_plugin_1.default)({ project: resolvedProjectPath, output: outputFolderName }),
42
+ (0, renderer_plugin_1.rendererPlugin)(variables, settings.ffmpeg, projectFile),
43
+ ],
39
44
  }).then(server => server.listen()),
40
45
  ]);
41
46
  if (!server.httpServer) {
42
47
  throw new Error('HTTP server is not initialized');
43
48
  }
44
49
  const address = server.httpServer.address();
45
- const port = address && typeof address === 'object' ? address.port : null;
46
- if (port === null) {
50
+ const resolvedPort = address && typeof address === 'object' ? address.port : null;
51
+ if (resolvedPort === null) {
47
52
  throw new Error('Server address is null');
48
53
  }
49
- return { browser, server, port };
54
+ return { browser, server, resolvedPort };
55
+ }
56
+ function trackProgress(tracker, id, progress) {
57
+ tracker.set(id, progress);
50
58
  }
51
59
  /**
52
60
  * Navigates to the URL and renders the video on the page
@@ -111,23 +119,23 @@ async function renderVideoOnPage(id, browser, server, url, progressTracker, prog
111
119
  /**
112
120
  * Initializes the browser and starts rendering the video
113
121
  */
114
- async function initializeBrowserAndStartRendering(resolvedConfigPath, projectName, i, numOfWorkers, settings, hiddenFolderId, params, progressCallback) {
122
+ async function initializeBrowserAndStartRendering(projectFile, outputFileName, outputFolderName, i, numOfWorkers, settings, hiddenFolderId, variables, progressCallback) {
115
123
  const port = (settings.viteBasePort !== undefined ? settings.viteBasePort : 9000) + i;
116
124
  const progressTracker = new Map();
117
- const { browser, server } = await initBrowserAndServer(port, resolvedConfigPath, settings, params);
118
- const url = buildUrl(port, `${projectName}-${i}`, i, numOfWorkers, settings.range, hiddenFolderId, settings.dimensions);
125
+ const { browser, server, resolvedPort } = await initBrowserAndServer(port, projectFile, outputFolderName, settings, variables);
126
+ const url = buildUrl(resolvedPort, `${outputFileName}-${i}`, i, numOfWorkers, settings.range, hiddenFolderId, settings.dimensions);
119
127
  return renderVideoOnPage(i, browser, server, url, progressTracker, progressCallback, settings.logProgress);
120
128
  }
121
129
  /**
122
130
  * Collects audio and video files from each worker and returns them.
123
131
  * If audio file does not exist, creates a silent audio file with the same duration as the video file.
124
132
  */
125
- async function collectAudioAndVideoFiles(numOfWorkers, projectName, hiddenFolderId) {
133
+ async function collectAudioAndVideoFiles(numOfWorkers, outputFileName, hiddenFolderId) {
126
134
  const audioFiles = [];
127
135
  const videoFiles = [];
128
136
  for (let i = 0; i < numOfWorkers; i++) {
129
- const videoFilePath = `${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}/visuals.mp4`;
130
- const audioFilePath = `${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}/audio.wav`;
137
+ const videoFilePath = `${os.tmpdir()}/revideo-${outputFileName}-${i}-${hiddenFolderId}/visuals.mp4`;
138
+ const audioFilePath = `${os.tmpdir()}/revideo-${outputFileName}-${i}-${hiddenFolderId}/audio.wav`;
131
139
  if (!(await (0, ffmpeg_1.doesFileExist)(audioFilePath))) {
132
140
  const videoDuration = await (0, ffmpeg_1.getVideoDuration)(videoFilePath);
133
141
  await (0, ffmpeg_1.createSilentAudioFile)(audioFilePath, videoDuration);
@@ -140,72 +148,73 @@ async function collectAudioAndVideoFiles(numOfWorkers, projectName, hiddenFolder
140
148
  /**
141
149
  * Concatenates audio and video files and merges them into a single video file.
142
150
  */
143
- async function concatenateAudioAndVideoFiles(projectName, audioFiles, videoFiles) {
144
- await (0, ffmpeg_1.concatenateMedia)(videoFiles, path.join(process.cwd(), `output/${projectName}-visuals.mp4`));
145
- await (0, ffmpeg_1.concatenateMedia)(audioFiles, path.join(process.cwd(), `output/${projectName}-audio.wav`));
146
- await (0, ffmpeg_1.mergeAudioWithVideo)(path.join(process.cwd(), `output/${projectName}-audio.wav`), path.join(process.cwd(), `output/${projectName}-visuals.mp4`), path.join(process.cwd(), `output/${projectName}.mp4`));
151
+ async function concatenateAudioAndVideoFiles(outputFileName, outputFolder, audioFiles, videoFiles) {
152
+ await (0, ffmpeg_1.concatenateMedia)(videoFiles, path.join(outputFolder, `${outputFileName}-visuals.mp4`));
153
+ await (0, ffmpeg_1.concatenateMedia)(audioFiles, path.join(outputFolder, `${outputFileName}-audio.wav`));
154
+ await (0, ffmpeg_1.mergeAudioWithVideo)(path.join(outputFolder, `${outputFileName}-audio.wav`), path.join(outputFolder, `${outputFileName}-visuals.mp4`), path.join(outputFolder, `${outputFileName}.mp4`));
147
155
  }
148
156
  /**
149
157
  * Deletes all partial files after concatenation is done
150
158
  */
151
- async function cleanup(projectName, numOfWorkers, hiddenFolderId) {
159
+ async function cleanup(outputFileName, outputFolderName, numOfWorkers, hiddenFolderId) {
152
160
  const cleanupFolders = [];
153
161
  const cleanupFiles = [];
154
162
  for (let i = 0; i < numOfWorkers; i++) {
155
- cleanupFolders.push(`${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}`);
156
- cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-${i}.mp4`));
163
+ cleanupFolders.push(`${os.tmpdir()}/revideo-${outputFileName}-${i}-${hiddenFolderId}`);
164
+ cleanupFiles.push(path.join(process.cwd(), outputFolderName, `${outputFileName}-${i}.mp4`));
157
165
  }
158
- cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-audio.wav`));
159
- cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-visuals.mp4`));
166
+ cleanupFiles.push(path.join(process.cwd(), outputFolderName, `${outputFileName}-audio.wav`));
167
+ cleanupFiles.push(path.join(process.cwd(), outputFolderName, `${outputFileName}-visuals.mp4`));
160
168
  const folderCleanupPromises = cleanupFolders.map(folder => fs.promises.rm(folder, { recursive: true, force: true }).catch(() => { }));
161
169
  const fileCleanupPromises = cleanupFiles.map(file => fs.promises.unlink(file).catch(() => { }));
162
170
  await Promise.all([...folderCleanupPromises, ...fileCleanupPromises]);
163
171
  }
164
- const renderPartialVideo = async (configFile, workerId, numWorkers, params, progressCallback, settings = {}) => {
165
- // Get settings
166
- const resolvedConfigPath = path.resolve(process.cwd(), configFile);
167
- const projectName = settings.name ?? 'project';
168
- const hiddenFolderId = (0, uuid_1.v4)();
169
- const numOfWorkers = numWorkers;
170
- await initializeBrowserAndStartRendering(resolvedConfigPath, projectName, workerId, numOfWorkers, settings, hiddenFolderId, params, progressCallback);
171
- const videoFilePath = `${os.tmpdir()}/revideo-${projectName}-${workerId}-${hiddenFolderId}/visuals.mp4`;
172
- const audioFilePath = `${os.tmpdir()}/revideo-${projectName}-${workerId}-${hiddenFolderId}/audio.wav`;
173
- if (!(await (0, ffmpeg_1.doesFileExist)(audioFilePath))) {
174
- const videoDuration = await (0, ffmpeg_1.getVideoDuration)(videoFilePath);
175
- await (0, ffmpeg_1.createSilentAudioFile)(audioFilePath, videoDuration);
172
+ function getPropDefaults(settings) {
173
+ if (settings.outFile && !settings.outFile.endsWith('.mp4')) {
174
+ throw new Error('outFile must end with ".mp4"');
176
175
  }
177
- return { audioFile: audioFilePath, videoFile: videoFilePath };
178
- };
179
- exports.renderPartialVideo = renderPartialVideo;
176
+ const outFile = settings.outFile?.slice(0, -4) ?? 'video';
177
+ return {
178
+ outputFileName: outFile,
179
+ outputFolderName: settings.outDir ?? './output',
180
+ numOfWorkers: settings.workers ?? 1,
181
+ hiddenFolderId: (0, uuid_1.v4)(),
182
+ };
183
+ }
180
184
  /**
181
185
  * Renders a video to a file.
182
- * @param configFile - Path to the vite config file (vite.config.ts).
183
- * @param params - Parameters to pass to your project (see https://docs.re.video/parameterized-video)
186
+ * @param projectFile - Path to the project.ts file.
187
+ * @param variables - Variables to pass to your project (see https://docs.re.video/parameterized-video)
184
188
  * @param progressCallback - Callback function to track rendering progress. Progress is a number between 0 and 1.
185
189
  * @param settings - Settings for the rendering process.
186
190
  * @returns - Path to the rendered video file.
187
191
  */
188
- const renderVideo = async (configFile, params, progressCallback, settings = {}) => {
189
- // Get settings
190
- const resolvedConfigPath = path.resolve(process.cwd(), configFile);
191
- const projectName = settings.name ?? 'project';
192
- const hiddenFolderId = (0, uuid_1.v4)();
193
- const numOfWorkers = settings.workers ?? 1;
192
+ const renderVideo = async ({ projectFile, variables, settings = {}, }) => {
193
+ const { outputFileName, outputFolderName, numOfWorkers, hiddenFolderId } = getPropDefaults(settings);
194
194
  // Start rendering
195
195
  const renderPromises = [];
196
196
  for (let i = 0; i < numOfWorkers; i++) {
197
- renderPromises.push(initializeBrowserAndStartRendering(resolvedConfigPath, projectName, i, numOfWorkers, settings, hiddenFolderId, params, progressCallback));
197
+ renderPromises.push(initializeBrowserAndStartRendering(projectFile, outputFileName, outputFolderName, i, numOfWorkers, settings, hiddenFolderId, variables, settings.progressCallback));
198
198
  }
199
199
  // Wait for workers to finish rendering
200
200
  await Promise.all(renderPromises);
201
201
  // Collect and concatenate audio and video files
202
- const { audioFiles, videoFiles } = await collectAudioAndVideoFiles(numOfWorkers, projectName, hiddenFolderId);
203
- await concatenateAudioAndVideoFiles(projectName, audioFiles, videoFiles);
204
- await cleanup(projectName, numOfWorkers, hiddenFolderId);
205
- return `output/${projectName}.mp4`;
202
+ const { audioFiles, videoFiles } = await collectAudioAndVideoFiles(numOfWorkers, outputFileName, hiddenFolderId);
203
+ await concatenateAudioAndVideoFiles(outputFileName, outputFolderName, audioFiles, videoFiles);
204
+ await cleanup(outputFileName, outputFolderName, numOfWorkers, hiddenFolderId);
205
+ return path.join(outputFolderName, `${outputFileName}.mp4`);
206
206
  };
207
207
  exports.renderVideo = renderVideo;
208
- function trackProgress(tracker, id, progress) {
209
- tracker.set(id, progress);
210
- }
211
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLXZpZGVvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc2VydmVyL3JlbmRlci12aWRlby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0Q0FPeUI7QUFDekIseUJBQXlCO0FBQ3pCLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IseUNBQTJFO0FBQzNFLCtCQUFrQztBQUNsQywrQkFBaUQ7QUFDakQsdURBQWlEO0FBRWpEOzs7R0FHRztBQUNILFNBQVMsUUFBUSxDQUNmLElBQVksRUFDWixRQUFnQixFQUNoQixRQUFnQixFQUNoQixpQkFBeUIsRUFDekIsUUFBMEIsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQ3ZDLGNBQXNCLEVBQ3RCLFVBQTZCO0lBRTdCLE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JELE1BQU0scUJBQXFCLEdBQUcsa0JBQWtCLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDakUsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVO1FBQ2pDLENBQUMsQ0FBQyxlQUFlLFVBQVUsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUM3RCxDQUFDLENBQUMsRUFBRSxDQUFDO0lBRVAsT0FBTyxDQUNMLG9CQUFvQixJQUFJLG9CQUFvQixlQUFlLGFBQWEsUUFBUSxzQkFBc0IsaUJBQWlCLG1CQUFtQixLQUFLLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixLQUFLLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixxQkFBcUIsRUFBRTtRQUNyTixnQkFBZ0IsQ0FDakIsQ0FBQztBQUNKLENBQUM7QUFrQkQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsb0JBQW9CLENBQ2pDLFNBQWlCLEVBQ2pCLGtCQUEwQixFQUMxQixRQUE2QixFQUM3QixNQUFnQztJQUVoQyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUM7SUFDNUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUVuRSxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUMxQyxtQkFBUyxDQUFDLE1BQU0sQ0FBQyxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksRUFBQyxDQUFDO1FBQy9ELElBQUEsbUJBQVksRUFBQztZQUNYLFVBQVUsRUFBRSxrQkFBa0I7WUFDOUIsTUFBTSxFQUFFO2dCQUNOLElBQUksRUFBRSxTQUFTO2FBQ2hCO1lBQ0QsT0FBTyxFQUFFLENBQUMsSUFBQSxnQ0FBYyxFQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDbkQsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztLQUNuQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QyxNQUFNLElBQUksR0FBRyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUUsSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxPQUFPLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsaUJBQWlCLENBQzlCLEVBQVUsRUFDVixPQUFnQixFQUNoQixNQUFxQixFQUNyQixHQUFXLEVBQ1gsZUFBb0MsRUFDcEMsZ0JBQTZELEVBQzdELFdBQXFCO0lBRXJCLFNBQVMsYUFBYTtRQUNwQixJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFDZCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksZUFBZSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDckQsSUFBSSxJQUFJLDJCQUEyQixHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUUsQ0FBQztRQUVELElBQUksSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ2hCLE9BQU87UUFDVCxDQUFDO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQixDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtRQUNoQyxhQUFhLEVBQUUsQ0FBQztJQUNsQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFVCxNQUFNLElBQUksR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QyxNQUFNLElBQUksR0FBRyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUUsSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCw0Q0FBNEM7SUFDNUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7UUFDdkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUMzQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLFNBQVM7WUFDWCxDQUFDO1lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsS0FBSyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBZ0IsRUFBRSxFQUFFO1FBQ3RELElBQUksZ0JBQWdCLEVBQUUsQ0FBQztZQUNyQixnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUNELElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsYUFBYSxDQUFDLGVBQWUsRUFBRSxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDL0MsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUM5RCxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2pELE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JELGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN4QixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsWUFBb0IsRUFBRSxFQUFFO1lBQ25FLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDakQsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFckIsT0FBTyxpQkFBaUIsQ0FBQztBQUMzQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsa0NBQWtDLENBQy9DLGtCQUEwQixFQUMxQixXQUFtQixFQUNuQixDQUFTLEVBQ1QsWUFBb0IsRUFDcEIsUUFBNkIsRUFDN0IsY0FBc0IsRUFDdEIsTUFBZ0MsRUFDaEMsZ0JBQTZEO0lBRTdELE1BQU0sSUFBSSxHQUNSLENBQUMsUUFBUSxDQUFDLFlBQVksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzRSxNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUVsRCxNQUFNLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBQyxHQUFHLE1BQU0sb0JBQW9CLENBQ2xELElBQUksRUFDSixrQkFBa0IsRUFDbEIsUUFBUSxFQUNSLE1BQU0sQ0FDUCxDQUFDO0lBRUYsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUNsQixJQUFJLEVBQ0osR0FBRyxXQUFXLElBQUksQ0FBQyxFQUFFLEVBQ3JCLENBQUMsRUFDRCxZQUFZLEVBQ1osUUFBUSxDQUFDLEtBQUssRUFDZCxjQUFjLEVBQ2QsUUFBUSxDQUFDLFVBQVUsQ0FDcEIsQ0FBQztJQUVGLE9BQU8saUJBQWlCLENBQ3RCLENBQUMsRUFDRCxPQUFPLEVBQ1AsTUFBTSxFQUNOLEdBQUcsRUFDSCxlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLFFBQVEsQ0FBQyxXQUFXLENBQ3JCLENBQUM7QUFDSixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsS0FBSyxVQUFVLHlCQUF5QixDQUN0QyxZQUFvQixFQUNwQixXQUFtQixFQUNuQixjQUFzQjtJQUV0QixNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFDdEIsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN0QyxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxXQUFXLElBQUksQ0FBQyxJQUFJLGNBQWMsY0FBYyxDQUFDO1FBQ2pHLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxZQUFZLFdBQVcsSUFBSSxDQUFDLElBQUksY0FBYyxZQUFZLENBQUM7UUFFL0YsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFBLHNCQUFhLEVBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzFDLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBQSx5QkFBZ0IsRUFBQyxhQUFhLENBQUMsQ0FBQztZQUM1RCxNQUFNLElBQUEsOEJBQXFCLEVBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQy9CLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELE9BQU8sRUFBQyxVQUFVLEVBQUUsVUFBVSxFQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLDZCQUE2QixDQUMxQyxXQUFtQixFQUNuQixVQUFvQixFQUNwQixVQUFvQjtJQUVwQixNQUFNLElBQUEseUJBQWdCLEVBQ3BCLFVBQVUsRUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLFdBQVcsY0FBYyxDQUFDLENBQzlELENBQUM7SUFDRixNQUFNLElBQUEseUJBQWdCLEVBQ3BCLFVBQVUsRUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLFdBQVcsWUFBWSxDQUFDLENBQzVELENBQUM7SUFDRixNQUFNLElBQUEsNEJBQW1CLEVBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFVBQVUsV0FBVyxZQUFZLENBQUMsRUFDM0QsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsVUFBVSxXQUFXLGNBQWMsQ0FBQyxFQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLFdBQVcsTUFBTSxDQUFDLENBQ3RELENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsT0FBTyxDQUNwQixXQUFtQixFQUNuQixZQUFvQixFQUNwQixjQUFzQjtJQUV0QixNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7SUFDMUIsTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN0QyxjQUFjLENBQUMsSUFBSSxDQUNqQixHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxXQUFXLElBQUksQ0FBQyxJQUFJLGNBQWMsRUFBRSxDQUMvRCxDQUFDO1FBQ0YsWUFBWSxDQUFDLElBQUksQ0FDZixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLFdBQVcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUMzRCxDQUFDO0lBQ0osQ0FBQztJQUVELFlBQVksQ0FBQyxJQUFJLENBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsVUFBVSxXQUFXLFlBQVksQ0FBQyxDQUM1RCxDQUFDO0lBQ0YsWUFBWSxDQUFDLElBQUksQ0FDZixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLFdBQVcsY0FBYyxDQUFDLENBQzlELENBQUM7SUFFRixNQUFNLHFCQUFxQixHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FDeEQsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQ3ZFLENBQUM7SUFFRixNQUFNLG1CQUFtQixHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDbEQsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUN6QyxDQUFDO0lBRUYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxxQkFBcUIsRUFBRSxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQztBQUN4RSxDQUFDO0FBRU0sTUFBTSxrQkFBa0IsR0FBRyxLQUFLLEVBQ3JDLFVBQWtCLEVBQ2xCLFFBQWdCLEVBQ2hCLFVBQWtCLEVBQ2xCLE1BQWdDLEVBQ2hDLGdCQUE2RCxFQUM3RCxXQUFnQyxFQUFFLEVBQ2xDLEVBQUU7SUFDRixlQUFlO0lBQ2YsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNuRSxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQztJQUMvQyxNQUFNLGNBQWMsR0FBRyxJQUFBLFNBQU0sR0FBRSxDQUFDO0lBQ2hDLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQztJQUVoQyxNQUFNLGtDQUFrQyxDQUN0QyxrQkFBa0IsRUFDbEIsV0FBVyxFQUNYLFFBQVEsRUFDUixZQUFZLEVBQ1osUUFBUSxFQUNSLGNBQWMsRUFDZCxNQUFNLEVBQ04sZ0JBQWdCLENBQ2pCLENBQUM7SUFFRixNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxXQUFXLElBQUksUUFBUSxJQUFJLGNBQWMsY0FBYyxDQUFDO0lBQ3hHLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxZQUFZLFdBQVcsSUFBSSxRQUFRLElBQUksY0FBYyxZQUFZLENBQUM7SUFFdEcsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFBLHNCQUFhLEVBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFDLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBQSx5QkFBZ0IsRUFBQyxhQUFhLENBQUMsQ0FBQztRQUM1RCxNQUFNLElBQUEsOEJBQXFCLEVBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxPQUFPLEVBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFDLENBQUM7QUFDOUQsQ0FBQyxDQUFDO0FBbENXLFFBQUEsa0JBQWtCLHNCQWtDN0I7QUFFRjs7Ozs7OztHQU9HO0FBQ0ksTUFBTSxXQUFXLEdBQUcsS0FBSyxFQUM5QixVQUFrQixFQUNsQixNQUFnQyxFQUNoQyxnQkFBNkQsRUFDN0QsV0FBZ0MsRUFBRSxFQUNsQyxFQUFFO0lBQ0YsZUFBZTtJQUNmLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDbkUsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLElBQUksSUFBSSxTQUFTLENBQUM7SUFDL0MsTUFBTSxjQUFjLEdBQUcsSUFBQSxTQUFNLEdBQUUsQ0FBQztJQUNoQyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUUzQyxrQkFBa0I7SUFDbEIsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0lBQzFCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN0QyxjQUFjLENBQUMsSUFBSSxDQUNqQixrQ0FBa0MsQ0FDaEMsa0JBQWtCLEVBQ2xCLFdBQVcsRUFDWCxDQUFDLEVBQ0QsWUFBWSxFQUNaLFFBQVEsRUFDUixjQUFjLEVBQ2QsTUFBTSxFQUNOLGdCQUFnQixDQUNqQixDQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUVsQyxnREFBZ0Q7SUFDaEQsTUFBTSxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUMsR0FBRyxNQUFNLHlCQUF5QixDQUM5RCxZQUFZLEVBQ1osV0FBVyxFQUNYLGNBQWMsQ0FDZixDQUFDO0lBQ0YsTUFBTSw2QkFBNkIsQ0FBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3pFLE1BQU0sT0FBTyxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFFekQsT0FBTyxVQUFVLFdBQVcsTUFBTSxDQUFDO0FBQ3JDLENBQUMsQ0FBQztBQTFDVyxRQUFBLFdBQVcsZUEwQ3RCO0FBRUYsU0FBUyxhQUFhLENBQ3BCLE9BQTRCLEVBQzVCLEVBQVUsRUFDVixRQUFnQjtJQUVoQixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM1QixDQUFDIn0=
208
+ const renderPartialVideo = async ({ projectFile, variables, settings, workerId, }) => {
209
+ const { outputFileName, outputFolderName, numOfWorkers, hiddenFolderId } = getPropDefaults(settings);
210
+ await initializeBrowserAndStartRendering(projectFile, outputFileName, outputFolderName, workerId, numOfWorkers, settings, hiddenFolderId, variables, settings.progressCallback);
211
+ const videoFilePath = `${os.tmpdir()}/revideo-${outputFileName}-${workerId}-${hiddenFolderId}/visuals.mp4`;
212
+ const audioFilePath = `${os.tmpdir()}/revideo-${outputFileName}-${workerId}-${hiddenFolderId}/audio.wav`;
213
+ if (!(await (0, ffmpeg_1.doesFileExist)(audioFilePath))) {
214
+ const videoDuration = await (0, ffmpeg_1.getVideoDuration)(videoFilePath);
215
+ await (0, ffmpeg_1.createSilentAudioFile)(audioFilePath, videoDuration);
216
+ }
217
+ return { audioFile: audioFilePath, videoFile: videoFilePath };
218
+ };
219
+ exports.renderPartialVideo = renderPartialVideo;
220
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLXZpZGVvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc2VydmVyL3JlbmRlci12aWRlby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0Q0FPeUI7QUFDekIsc0RBQWdEO0FBQ2hELHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHlDQUEyRTtBQUMzRSwrQkFBa0M7QUFDbEMsK0JBQWdFO0FBQ2hFLHVEQUFpRDtBQUVqRDs7O0dBR0c7QUFDSCxTQUFTLFFBQVEsQ0FDZixJQUFZLEVBQ1osUUFBZ0IsRUFDaEIsUUFBZ0IsRUFDaEIsaUJBQXlCLEVBQ3pCLFFBQTBCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUN2QyxjQUFzQixFQUN0QixVQUE2QjtJQUU3QixNQUFNLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyRCxNQUFNLHFCQUFxQixHQUFHLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sZ0JBQWdCLEdBQUcsVUFBVTtRQUNqQyxDQUFDLENBQUMsZUFBZSxVQUFVLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDN0QsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUVQLE9BQU8sQ0FDTCxvQkFBb0IsSUFBSSxvQkFBb0IsZUFBZSxhQUFhLFFBQVEsc0JBQXNCLGlCQUFpQixtQkFBbUIsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsS0FBSyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIscUJBQXFCLEVBQUU7UUFDck4sZ0JBQWdCLENBQ2pCLENBQUM7QUFDSixDQUFDO0FBZ0NEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLG9CQUFvQixDQUNqQyxTQUFpQixFQUNqQixXQUFtQixFQUNuQixnQkFBd0IsRUFDeEIsUUFBd0IsRUFDeEIsU0FBbUM7SUFFbkMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsSUFB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
@@ -0,0 +1,10 @@
1
+ import { BrowserLaunchArgumentOptions } from 'puppeteer';
2
+ interface RenderVideoSettings {
3
+ name?: string;
4
+ range?: [number, number];
5
+ puppeteer?: BrowserLaunchArgumentOptions;
6
+ workers?: number;
7
+ }
8
+ export declare const renderVideo: (configFile: string, params?: Record<string, unknown>, settings?: RenderVideoSettings) => Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=renderVideo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderVideo.d.ts","sourceRoot":"","sources":["../../server/renderVideo.ts"],"names":[],"mappings":"AAUA,OAAkB,EAAU,4BAA4B,EAAC,MAAM,WAAW,CAAC;AAiB3E,UAAU,mBAAmB;IAE3B,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzB,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,eACV,MAAM,WACT,OAAO,MAAM,EAAE,OAAO,CAAC,aACtB,mBAAmB,kBAmE9B,CAAC"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderVideo = void 0;
4
+ const ffmpeg_1 = require("@revideo/ffmpeg");
5
+ const fs = require("fs");
6
+ const os = require("os");
7
+ const path = require("path");
8
+ const puppeteer_1 = require("puppeteer");
9
+ const readline = require("readline");
10
+ const uuid_1 = require("uuid");
11
+ const vite_1 = require("vite");
12
+ const RendererPlugin_1 = require("./RendererPlugin");
13
+ function buildUrl(port, fileName, workerId, totalNumOfWorkers, range = [0, Infinity], hiddenFolderId) {
14
+ return `http://localhost:${port}/render?fileName=${fileName}&workerId=${workerId}&totalNumOfWorkers=${totalNumOfWorkers}&startInSeconds=${range[0]}&endInSeconds=${range[1]}&hiddenFolderId=${hiddenFolderId}`;
15
+ }
16
+ const renderVideo = async (configFile, params, settings = {}) => {
17
+ console.log('Rendering...');
18
+ const resolvedConfigPath = path.resolve(process.cwd(), configFile);
19
+ const projectName = settings.name ?? 'project';
20
+ const hiddenFolderId = (0, uuid_1.v4)();
21
+ const numOfWorkers = settings.workers ?? 1;
22
+ const renderPromises = [];
23
+ for (let i = 0; i < numOfWorkers; i++) {
24
+ const port = 9000 + i;
25
+ renderPromises.push(initBrowserAndServer(port, resolvedConfigPath, params, settings.puppeteer).then(({ browser, server }) => {
26
+ const url = buildUrl(port, `${projectName}-${i}`, i, numOfWorkers, settings.range, hiddenFolderId);
27
+ return renderVideoOnPage(browser, server, url);
28
+ }));
29
+ }
30
+ await Promise.all(renderPromises);
31
+ const audioFiles = [];
32
+ const videoFiles = [];
33
+ for (let i = 0; i < numOfWorkers; i++) {
34
+ const videoFilePath = `${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}/visuals.mp4`;
35
+ const audioFilePath = `${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}/audio.wav`;
36
+ if (!(await (0, ffmpeg_1.doesFileExist)(audioFilePath))) {
37
+ const videoDuration = await (0, ffmpeg_1.getVideoDuration)(videoFilePath);
38
+ await (0, ffmpeg_1.createSilentAudioFile)(audioFilePath, videoDuration);
39
+ }
40
+ videoFiles.push(videoFilePath);
41
+ audioFiles.push(audioFilePath);
42
+ }
43
+ await (0, ffmpeg_1.concatenateMedia)(videoFiles, path.join(process.cwd(), `output/${projectName}-visuals.mp4`));
44
+ await (0, ffmpeg_1.concatenateMedia)(audioFiles, path.join(process.cwd(), `output/${projectName}-audio.wav`));
45
+ await (0, ffmpeg_1.mergeAudioWithVideo)(path.join(process.cwd(), `output/${projectName}-audio.wav`), path.join(process.cwd(), `output/${projectName}-visuals.mp4`), path.join(process.cwd(), `output/${projectName}.mp4`));
46
+ console.log(`\nRendered successfully! Video saved to: ${path.join(process.cwd(), `output/${projectName}.mp4`)}`);
47
+ await cleanup(projectName, numOfWorkers, hiddenFolderId);
48
+ };
49
+ exports.renderVideo = renderVideo;
50
+ async function initBrowserAndServer(fixedPort, resolvedConfigPath, params, puppeteerOptions) {
51
+ const [browser, server] = await Promise.all([
52
+ puppeteer_1.default.launch({ headless: true, ...puppeteerOptions }),
53
+ (0, vite_1.createServer)({
54
+ configFile: resolvedConfigPath,
55
+ server: {
56
+ port: fixedPort,
57
+ },
58
+ plugins: [(0, RendererPlugin_1.rendererPlugin)(params)],
59
+ }).then(server => server.listen()),
60
+ ]);
61
+ if (!server.httpServer) {
62
+ throw new Error('HTTP server is not initialized');
63
+ }
64
+ const address = server.httpServer.address();
65
+ const port = address && typeof address === 'object' ? address.port : null;
66
+ if (port === null) {
67
+ throw new Error('Server address is null');
68
+ }
69
+ return { browser, server, port };
70
+ }
71
+ async function renderVideoOnPage(browser, server, url) {
72
+ const page = await browser.newPage();
73
+ if (!server.httpServer) {
74
+ throw new Error('HTTP server is not initialized');
75
+ }
76
+ const address = server.httpServer.address();
77
+ const port = address && typeof address === 'object' ? address.port : null;
78
+ if (port === null) {
79
+ throw new Error('Server address is null');
80
+ }
81
+ // Attach logs from puppeteer to the console
82
+ page.on('console', msg => {
83
+ for (let i = 0; i < msg.args().length; ++i) {
84
+ console.log(`${port}: ${msg.args()[i]}`);
85
+ }
86
+ });
87
+ page.exposeFunction('logProgress', (progress) => {
88
+ const percentage = Math.floor(progress * 100);
89
+ const barLength = 20;
90
+ const filledLength = Math.floor((percentage / 100) * barLength);
91
+ const bar = '█'.repeat(filledLength) + '-'.repeat(barLength - filledLength);
92
+ const consoleLine = process.stdout.rows + port - 9000;
93
+ readline.cursorTo(process.stdout, 0, consoleLine);
94
+ readline.clearLine(process.stdout, 0);
95
+ process.stdout.write(`Progress for worker on port ${port}: [${bar}] ${percentage}%`);
96
+ });
97
+ const renderingComplete = new Promise((resolve, reject) => {
98
+ page.exposeFunction('onRenderComplete', async () => {
99
+ await Promise.all([browser.close(), server.close()]);
100
+ resolve();
101
+ });
102
+ page.exposeFunction('onRenderFailed', async (errorMessage) => {
103
+ await Promise.all([browser.close(), server.close()]);
104
+ console.error('Rendering failed:', errorMessage);
105
+ reject(new Error(errorMessage));
106
+ });
107
+ });
108
+ await page.goto(url);
109
+ return renderingComplete;
110
+ }
111
+ async function cleanup(projectName, numOfWorkers, hiddenFolderId) {
112
+ const cleanupFolders = [];
113
+ const cleanupFiles = [];
114
+ for (let i = 0; i < numOfWorkers; i++) {
115
+ cleanupFolders.push(`${os.tmpdir()}/revideo-${projectName}-${i}-${hiddenFolderId}`);
116
+ cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-${i}.mp4`));
117
+ }
118
+ cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-audio.wav`));
119
+ cleanupFiles.push(path.join(process.cwd(), `output/${projectName}-visuals.mp4`));
120
+ const folderCleanupPromises = cleanupFolders.map(folder => fs.promises.rm(folder, { recursive: true, force: true }).catch(() => { }));
121
+ const fileCleanupPromises = cleanupFiles.map(file => fs.promises.unlink(file).catch(() => { }));
122
+ await Promise.all([...folderCleanupPromises, ...fileCleanupPromises]);
123
+ }
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyVmlkZW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zZXJ2ZXIvcmVuZGVyVmlkZW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNENBTXlCO0FBQ3pCLHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHlDQUEyRTtBQUMzRSxxQ0FBcUM7QUFDckMsK0JBQWtDO0FBQ2xDLCtCQUFpRDtBQUNqRCxxREFBZ0Q7QUFFaEQsU0FBUyxRQUFRLENBQ2YsSUFBWSxFQUNaLFFBQWdCLEVBQ2hCLFFBQWdCLEVBQ2hCLGlCQUF5QixFQUN6QixRQUEwQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFDdkMsY0FBc0I7SUFFdEIsT0FBTyxvQkFBb0IsSUFBSSxvQkFBb0IsUUFBUSxhQUFhLFFBQVEsc0JBQXNCLGlCQUFpQixtQkFBbUIsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsS0FBSyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsY0FBYyxFQUFFLENBQUM7QUFDak4sQ0FBQztBQWFNLE1BQU0sV0FBVyxHQUFHLEtBQUssRUFDOUIsVUFBa0IsRUFDbEIsTUFBZ0MsRUFDaEMsV0FBZ0MsRUFBRSxFQUNsQyxFQUFFO0lBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUU1QixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDO0lBQy9DLE1BQU0sY0FBYyxHQUFHLElBQUEsU0FBTSxHQUFFLENBQUM7SUFFaEMsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUM7SUFDM0MsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0lBRTFCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxF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