-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.tsx
99 lines (91 loc) · 2.49 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
/**
* 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 = process.env.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'))
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({
config: video,
webpackBundle: bundled,
onStart: () => console.log('Rendering frames...'),
onFrameUpdate: (f) => {
if (f % 10 === 0) {
console.log(`Rendered frame ${f}`)
}
},
parallelism: null,
outputDir: tmpDir,
inputProps: 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',
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')
)