@revideo/renderer 0.3.7-red.988 → 0.4.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.
- package/lib/server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/lib/client/FFmpegExporterClient.d.ts +0 -46
- package/lib/client/FFmpegExporterClient.d.ts.map +0 -1
- package/lib/client/FFmpegExporterClient.js +0 -118
- package/lib/client/ffpmeg.d.ts +0 -3
- package/lib/client/ffpmeg.d.ts.map +0 -1
- package/lib/client/ffpmeg.js +0 -9
- package/lib/client/index.d.ts +0 -3
- package/lib/client/index.d.ts.map +0 -1
- package/lib/client/index.js +0 -9
- package/lib/index.js +0 -5
- package/lib/index.js.map +0 -1
- package/lib/server/RendererPlugin.d.ts +0 -3
- package/lib/server/RendererPlugin.d.ts.map +0 -1
- package/lib/server/RendererPlugin.js +0 -50
- package/lib/server/ffmpeg/FFmpegBridge.d.ts +0 -22
- package/lib/server/ffmpeg/FFmpegBridge.d.ts.map +0 -1
- package/lib/server/ffmpeg/FFmpegBridge.js +0 -92
- package/lib/server/ffmpeg/FFmpegExporterServer.d.ts +0 -39
- package/lib/server/ffmpeg/FFmpegExporterServer.d.ts.map +0 -1
- package/lib/server/ffmpeg/FFmpegExporterServer.js +0 -264
- package/lib/server/ffmpeg/FFmpegPlugin.d.ts +0 -3
- package/lib/server/ffmpeg/FFmpegPlugin.d.ts.map +0 -1
- package/lib/server/ffmpeg/FFmpegPlugin.js +0 -23
- package/lib/server/ffmpeg/ImageStream.d.ts +0 -10
- package/lib/server/ffmpeg/ImageStream.d.ts.map +0 -1
- package/lib/server/ffmpeg/ImageStream.js +0 -25
- package/lib/server/ffmpeg/VideoFrameExtractor.d.ts +0 -41
- package/lib/server/ffmpeg/VideoFrameExtractor.d.ts.map +0 -1
- package/lib/server/ffmpeg/VideoFrameExtractor.js +0 -148
- package/lib/server/ffmpeg/utils.d.ts +0 -8
- package/lib/server/ffmpeg/utils.d.ts.map +0 -1
- package/lib/server/ffmpeg/utils.js +0 -141
- package/lib/server/renderVideo.d.ts +0 -10
- package/lib/server/renderVideo.d.ts.map +0 -1
- package/lib/server/renderVideo.js +0 -124
- package/lib/server/utils.d.ts +0 -3
- package/lib/server/utils.d.ts.map +0 -1
- package/lib/server/utils.js +0 -20
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
type VideoFrameExtractorState = 'processing' | 'done' | 'error';
|
|
3
|
-
/**
|
|
4
|
-
* Walks through a video file and extracts frames.
|
|
5
|
-
*/
|
|
6
|
-
export declare class VideoFrameExtractor {
|
|
7
|
-
private static readonly jpegSOI;
|
|
8
|
-
private static readonly jpegEOI;
|
|
9
|
-
private static readonly chunkLengthInSeconds;
|
|
10
|
-
state: VideoFrameExtractorState;
|
|
11
|
-
filePath: string;
|
|
12
|
-
private buffer;
|
|
13
|
-
private imageBuffers;
|
|
14
|
-
private hooksWaiting;
|
|
15
|
-
private lastImage;
|
|
16
|
-
private startTime;
|
|
17
|
-
private duration;
|
|
18
|
-
private toTime;
|
|
19
|
-
private fps;
|
|
20
|
-
private process;
|
|
21
|
-
constructor(filePath: string, startTime: number, fps: number, duration: number);
|
|
22
|
-
private getEndTime;
|
|
23
|
-
private createFfmpegProcess;
|
|
24
|
-
/**
|
|
25
|
-
* We call this in the case that the time requested is greater than the
|
|
26
|
-
* duration of the video. In this case, we want to display the first frame
|
|
27
|
-
* of the video.
|
|
28
|
-
*
|
|
29
|
-
* Note: This does NOT match the behavior of the old implementation
|
|
30
|
-
* inside of 2d/src/lib/components/Video.ts. In the old implementation, the
|
|
31
|
-
* last frame is shown instead of the first frame.
|
|
32
|
-
*/
|
|
33
|
-
private createFfmpegProcessToExtractFirstFrame;
|
|
34
|
-
private processData;
|
|
35
|
-
popImage(): Promise<Buffer | null>;
|
|
36
|
-
private handleClose;
|
|
37
|
-
private handleError;
|
|
38
|
-
destroy(): void;
|
|
39
|
-
}
|
|
40
|
-
export {};
|
|
41
|
-
//# sourceMappingURL=VideoFrameExtractor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoFrameExtractor.d.ts","sourceRoot":"","sources":["../../../server/ffmpeg/VideoFrameExtractor.ts"],"names":[],"mappings":";AAIA,KAAK,wBAAwB,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAE5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAE3C,KAAK,EAAE,wBAAwB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,MAAM,CAA2B;IAGzC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,OAAO,CAA4C;gBAGzD,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM;IAwBlB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,mBAAmB;IAmC3B;;;;;;;;OAQG;IACH,OAAO,CAAC,sCAAsC;IA0B9C,OAAO,CAAC,WAAW;IAyBN,QAAQ;IAyCrB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAgBZ,OAAO;CAGf"}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VideoFrameExtractor = void 0;
|
|
4
|
-
const telemetry_1 = require("@revideo/telemetry");
|
|
5
|
-
const child_process_1 = require("child_process");
|
|
6
|
-
/**
|
|
7
|
-
* Walks through a video file and extracts frames.
|
|
8
|
-
*/
|
|
9
|
-
class VideoFrameExtractor {
|
|
10
|
-
constructor(filePath, startTime, fps, duration) {
|
|
11
|
-
this.buffer = Buffer.alloc(0);
|
|
12
|
-
// Images are buffered in memory until they are requested.
|
|
13
|
-
this.imageBuffers = [];
|
|
14
|
-
this.hooksWaiting = [];
|
|
15
|
-
this.lastImage = null;
|
|
16
|
-
this.state = 'processing';
|
|
17
|
-
this.filePath = filePath;
|
|
18
|
-
this.startTime = startTime;
|
|
19
|
-
this.duration = duration;
|
|
20
|
-
this.toTime = this.getEndTime(this.startTime);
|
|
21
|
-
this.fps = fps;
|
|
22
|
-
if (this.startTime >= this.duration) {
|
|
23
|
-
this.process = this.createFfmpegProcessToExtractFirstFrame(filePath);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
// Create a new ffmpeg process to extract the first 10 seconds of the video.
|
|
27
|
-
this.process = this.createFfmpegProcess(this.startTime, this.toTime, this.filePath, this.fps);
|
|
28
|
-
}
|
|
29
|
-
getEndTime(startTime) {
|
|
30
|
-
return Math.min(startTime + VideoFrameExtractor.chunkLengthInSeconds, this.duration);
|
|
31
|
-
}
|
|
32
|
-
createFfmpegProcess(startTime, toTime, filePath, fps) {
|
|
33
|
-
const process = (0, child_process_1.spawn)('ffmpeg', [
|
|
34
|
-
'-ss',
|
|
35
|
-
startTime.toString(),
|
|
36
|
-
'-to',
|
|
37
|
-
toTime.toString(),
|
|
38
|
-
'-i',
|
|
39
|
-
filePath,
|
|
40
|
-
'-vf',
|
|
41
|
-
`fps=fps=${fps}`,
|
|
42
|
-
'-f',
|
|
43
|
-
'image2pipe',
|
|
44
|
-
'-vcodec',
|
|
45
|
-
'mjpeg',
|
|
46
|
-
'-q:v',
|
|
47
|
-
'2',
|
|
48
|
-
'-',
|
|
49
|
-
], { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
50
|
-
process.stdout.on('data', this.processData.bind(this));
|
|
51
|
-
process.on('close', this.handleClose.bind(this));
|
|
52
|
-
process.on('error', this.handleError.bind(this));
|
|
53
|
-
return process;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* We call this in the case that the time requested is greater than the
|
|
57
|
-
* duration of the video. In this case, we want to display the first frame
|
|
58
|
-
* of the video.
|
|
59
|
-
*
|
|
60
|
-
* Note: This does NOT match the behavior of the old implementation
|
|
61
|
-
* inside of 2d/src/lib/components/Video.ts. In the old implementation, the
|
|
62
|
-
* last frame is shown instead of the first frame.
|
|
63
|
-
*/
|
|
64
|
-
createFfmpegProcessToExtractFirstFrame(filePath) {
|
|
65
|
-
const process = (0, child_process_1.spawn)('ffmpeg', [
|
|
66
|
-
'-i',
|
|
67
|
-
filePath,
|
|
68
|
-
'-vframes',
|
|
69
|
-
'1',
|
|
70
|
-
'-f',
|
|
71
|
-
'image2pipe',
|
|
72
|
-
'-vcodec',
|
|
73
|
-
'mjpeg',
|
|
74
|
-
'-q:v',
|
|
75
|
-
'2',
|
|
76
|
-
'-',
|
|
77
|
-
], { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
78
|
-
process.stdout.on('data', this.processData.bind(this));
|
|
79
|
-
process.on('close', this.handleClose.bind(this));
|
|
80
|
-
process.on('error', this.handleError.bind(this));
|
|
81
|
-
return process;
|
|
82
|
-
}
|
|
83
|
-
processData(data) {
|
|
84
|
-
this.buffer = Buffer.concat([this.buffer, data]);
|
|
85
|
-
let start = 0;
|
|
86
|
-
let end;
|
|
87
|
-
// Look for JPEG_SOI and JPEG_EOI markers to extract full frames
|
|
88
|
-
while ((start = this.buffer.indexOf(VideoFrameExtractor.jpegSOI, start)) !==
|
|
89
|
-
-1 &&
|
|
90
|
-
(end = this.buffer.indexOf(VideoFrameExtractor.jpegEOI, start)) !== -1) {
|
|
91
|
-
end += 2; // Include the EOI marker itself
|
|
92
|
-
const frame = this.buffer.subarray(start, end);
|
|
93
|
-
this.imageBuffers.push(frame);
|
|
94
|
-
this.hooksWaiting.forEach(hook => hook());
|
|
95
|
-
this.hooksWaiting = [];
|
|
96
|
-
this.buffer = this.buffer.subarray(end); // Remove the processed frame from buffer.
|
|
97
|
-
start = 0;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
async popImage() {
|
|
101
|
-
if (this.imageBuffers.length) {
|
|
102
|
-
const image = this.imageBuffers.shift();
|
|
103
|
-
this.lastImage = image;
|
|
104
|
-
return image;
|
|
105
|
-
}
|
|
106
|
-
if (this.state === 'error') {
|
|
107
|
-
throw new Error('An error occurred while extracting the video frames.');
|
|
108
|
-
}
|
|
109
|
-
// If the video is done and there are no more frames to extract, return the last frame.
|
|
110
|
-
if (this.state === 'done' && this.toTime >= this.duration) {
|
|
111
|
-
return this.lastImage;
|
|
112
|
-
}
|
|
113
|
-
// If there are more frames to extract, request the next chunk.
|
|
114
|
-
if (this.state === 'done') {
|
|
115
|
-
this.startTime = this.toTime;
|
|
116
|
-
this.toTime = Math.min(this.startTime + VideoFrameExtractor.chunkLengthInSeconds, this.duration);
|
|
117
|
-
this.process = this.createFfmpegProcess(this.startTime, this.toTime, this.filePath, this.fps);
|
|
118
|
-
this.state = 'processing';
|
|
119
|
-
}
|
|
120
|
-
return await new Promise(res => {
|
|
121
|
-
this.hooksWaiting.push(() => {
|
|
122
|
-
res(this.imageBuffers.shift());
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
handleClose(code) {
|
|
127
|
-
this.state = code === 0 ? 'done' : 'error';
|
|
128
|
-
}
|
|
129
|
-
handleError(err) {
|
|
130
|
-
const code = err.code;
|
|
131
|
-
if (code === 'ENOENT') {
|
|
132
|
-
console.error('Error: ffmpeg not found. Make sure ffmpeg is installed on your system.');
|
|
133
|
-
(0, telemetry_1.sendEvent)(telemetry_1.EventName.Error, { error: 'ffmpeg-not-found' });
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
console.error(`An ffmpeg error occurred while fetching frames from source video ${this.filePath}:`, err);
|
|
137
|
-
(0, telemetry_1.sendEvent)(telemetry_1.EventName.Error, { error: 'ffmpeg-error', message: err.message });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
destroy() {
|
|
141
|
-
this.process.kill();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
exports.VideoFrameExtractor = VideoFrameExtractor;
|
|
145
|
-
VideoFrameExtractor.jpegSOI = Buffer.from([0xff, 0xd8]); // Start of Image marker
|
|
146
|
-
VideoFrameExtractor.jpegEOI = Buffer.from([0xff, 0xd9]); // End of Image marker
|
|
147
|
-
VideoFrameExtractor.chunkLengthInSeconds = 45;
|
|
148
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVmlkZW9GcmFtZUV4dHJhY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NlcnZlci9mZm1wZWcvVmlkZW9GcmFtZUV4dHJhY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxrREFBd0Q7QUFDeEQsaURBQXlEO0FBS3pEOztHQUVHO0FBQ0gsTUFBYSxtQkFBbUI7SUF3QjlCLFlBQ0UsUUFBZ0IsRUFDaEIsU0FBaUIsRUFDakIsR0FBVyxFQUNYLFFBQWdCO1FBbkJWLFdBQU0sR0FBVyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpDLDBEQUEwRDtRQUNsRCxpQkFBWSxHQUFhLEVBQUUsQ0FBQztRQUM1QixpQkFBWSxHQUFrQixFQUFFLENBQUM7UUFFakMsY0FBUyxHQUFrQixJQUFJLENBQUM7UUFldEMsSUFBSSxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUM7UUFDMUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUVmLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsc0NBQXNDLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckUsT0FBTztRQUNULENBQUM7UUFFRCw0RUFBNEU7UUFDNUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQ3JDLElBQUksQ0FBQyxTQUFTLEVBQ2QsSUFBSSxDQUFDLE1BQU0sRUFDWCxJQUFJLENBQUMs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
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export declare function concatenateMedia(files: string[], outputFile: string): Promise<void>;
|
|
2
|
-
export declare function createSilentAudioFile(filePath: string, duration: number): Promise<unknown>;
|
|
3
|
-
export declare function getVideoDuration(filePath: string): Promise<number>;
|
|
4
|
-
export declare function doesFileExist(filePath: string): Promise<boolean>;
|
|
5
|
-
export declare function mergeAudioWithVideo(audioPath: string, videoPath: string, outputPath: string): Promise<void>;
|
|
6
|
-
export declare function checkForAudioStream(file: string): Promise<boolean>;
|
|
7
|
-
export declare function getSampleRate(filePath: string): Promise<number>;
|
|
8
|
-
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../server/ffmpeg/utils.ts"],"names":[],"mappings":"AAOA,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BvF;AAGH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAiB3E;AAEH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAetE;AAEH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOpE;AAEH,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAEH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBtE;AAEH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAenE"}
|
|
@@ -1,141 +0,0 @@
|
|
|
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,10 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,124 +0,0 @@
|
|
|
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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
|
package/lib/server/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../server/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAEzD;AAED,wBAAgB,aAAa,SAW5B"}
|
package/lib/server/utils.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.printProgress = exports.trackProgress = void 0;
|
|
4
|
-
const progressTracker = new Map();
|
|
5
|
-
function trackProgress(id, progress) {
|
|
6
|
-
progressTracker.set(id, progress);
|
|
7
|
-
}
|
|
8
|
-
exports.trackProgress = trackProgress;
|
|
9
|
-
function printProgress() {
|
|
10
|
-
let line = '';
|
|
11
|
-
for (const [key, value] of progressTracker.entries()) {
|
|
12
|
-
line += `Progress on worker ${key}: ${(value * 100).toFixed(0)}% `;
|
|
13
|
-
}
|
|
14
|
-
if (line === '') {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
console.log(line);
|
|
18
|
-
}
|
|
19
|
-
exports.printProgress = printProgress;
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zZXJ2ZXIvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7QUFFbEQsU0FBZ0IsYUFBYSxDQUFDLEVBQVUsRUFBRSxRQUFnQjtJQUN4RCxlQUFlLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRkQsc0NBRUM7QUFFRCxTQUFnQixhQUFhO0lBQzNCLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNkLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxlQUFlLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNyRCxJQUFJLElBQUksc0JBQXNCLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNyRSxDQUFDO0lBRUQsSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDaEIsT0FBTztJQUNULENBQUM7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3BCLENBQUM7QUFYRCxzQ0FXQyJ9
|