-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.tsx
100 lines (92 loc) · 2.48 KB
/
server.tsx
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
/**
* This is an example of a server that returns dynamic video.
* Run `npm run server` 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';
const app = express();
const port = 8000;
const compositionId = 'HelloWorld';
const cache = new Map<string, string>();
app.get('/', async (req, res) => {
const sendFile = (file: string) => {
fs.createReadStream(file)
.pipe(res)
.on('close', () => {
res.end();
});
};
try {
if (cache.get(JSON.stringify(req.query))) {
sendFile(cache.get(JSON.stringify(req.query)) as string);
return;
}
const bundled = await bundle(path.join(__dirname, './src/index.tsx'), () => {
/* intentionally blank */
});
const comps = await getCompositions(bundled);
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-')
);
await renderFrames({
config: video,
webpackBundle: bundled,
onStart: () => console.log('Rendering frames...'),
onFrameUpdate: (f) => {
if (f % 10 === 0) {
console.log(`Rendered frame ${f}`);
}
},
parallelism: null,
outputDir: tmpDir,
userProps: req.query,
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',
});
cache.set(JSON.stringify(req.query), finalOutput);
sendFile(finalOutput);
console.log('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.',
'',
'If you are running Hello World, try this:',
'',
`http://localhost:${port}?titleText=Hello,+World!&titleColor=red`,
'',
].join('\n')
);