-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathserver.tsx
103 lines (93 loc) · 2.58 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
101
102
103
/**
* 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 fs from "fs";
import os from "os";
import path from "path";
import { bundle } from "@remotion/bundler";
import {
getCompositions,
renderFrames,
stitchFramesToVideo,
} from "@remotion/renderer";
import express from "express";
import { webpackOverride } from "./webpack-override";
const app = express();
const port = process.env.PORT || 8000;
const compositionId = "Main";
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({
entryPoint: path.join(__dirname, "./src/index.tsx"),
webpackOverride: webpackOverride,
});
const comps = await getCompositions(bundled, { inputProps: req.query });
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({
composition: video,
serveUrl: bundled,
onStart: () => console.log("Rendering frames..."),
onFrameUpdate: (f) => {
if (f % 10 === 0) {
console.log(`Rendered frame ${f}`);
}
},
concurrency: null,
outputDir: tmpDir,
inputProps: req.query,
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,
assetsInfo,
});
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")
);