-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.mjs
106 lines (97 loc) · 2.48 KB
/
server.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* This is an example of a server that returns dynamic video.
* Run `pnpm serve` to try it out!
* If you don't want to render videos on a server, you can safely
* delete this file.
*/
import {bundle} from '@remotion/bundler';
import {
getCompositions,
renderFrames,
stitchFramesToVideo,
} from '@remotion/renderer';
import express from 'express';
import fs from 'fs';
import os from 'os';
import path from 'path';
import cors from 'cors';
import bodyParser from 'body-parser';
const app = express();
const port = process.env.PORT || 8000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(
cors({
origin: 'https://social-video-generatorz.cleverapps.io',
optionsSuccessStatus: 200,
methods: 'POST',
})
);
app.post('/:compositionId/', async (req, res) => {
const sendFile = (file) => {
fs.createReadStream(file)
.pipe(res)
.on('close', () => {
res.end();
});
};
try {
const reqParams = req.params.compositionId;
const compositionId = reqParams.match(/([^&]+)/i)[0];
const bundled = await bundle('src/index.ts');
const comps = await getCompositions(bundled, {inputProps: req.body});
const video = comps.find((c) => c.id === compositionId);
if (!video) {
throw new Error(`No video called ${compositionId}`);
}
res.set('content-type', 'video/mp4');
const tmpDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), 'remotion-')
);
const {assetsInfo} = await renderFrames({
config: video,
webpackBundle: bundled,
onStart: () => console.log(req.body, 'Rendering frames...'),
onFrameUpdate: (f) => {
if (f % 10 === 0) {
console.log(req.body, `Rendered frame ${f}`);
}
},
parallelism: null,
outputDir: tmpDir,
inputProps: req.body,
compositionId,
imageFormat: 'jpeg',
});
const finalOutput = path.join(tmpDir, 'out.mp4');
await stitchFramesToVideo({
dir: tmpDir,
force: true,
fps: video.fps,
height: video.height,
width: video.width,
outputLocation: finalOutput,
imageFormat: 'jpeg',
assetsInfo,
});
sendFile(finalOutput);
console.log(req.body, 'Video rendered and sent!');
} catch (err) {
console.error(err);
res.json({
error: err,
});
}
});
app.listen(port);
console.log(
[
`The server has started on http://localhost:${port}!`,
'You can render a video by passing props as URL parameters.',
'',
'To generate a video, try this:',
'',
`http://localhost:${port}/CompositionId&firstProps=myprops&secondprops...`,
'',
].join('\n')
);