diff --git a/.gitignore b/.gitignore index 44d646d..01314a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules dist/ +tmp/ \ No newline at end of file diff --git a/assets/comic.ttf b/assets/comic.ttf new file mode 100644 index 0000000..9edb03a Binary files /dev/null and b/assets/comic.ttf differ diff --git a/assets/spongebob.png b/assets/spongebob.png new file mode 100644 index 0000000..589b3ba Binary files /dev/null and b/assets/spongebob.png differ diff --git a/out.mp4 b/out.mp4 new file mode 100644 index 0000000..61e02a7 Binary files /dev/null and b/out.mp4 differ diff --git a/src/ffmpeg.ts b/src/ffmpeg.ts new file mode 100644 index 0000000..5205663 --- /dev/null +++ b/src/ffmpeg.ts @@ -0,0 +1,64 @@ +import FFmpeg from 'fluent-ffmpeg'; +import path from 'path'; +import fs from 'fs'; +import EventEmitter from 'events'; + +let inProgress: Array = []; +let funnyListener = new EventEmitter(); + +export default function(ip: string): Promise { + return new Promise((resolve, reject) => { + let outPath = path.join(__dirname, '..', 'tmp', ip + '.mp4'); + + if (inProgress.indexOf(ip) > -1) { + console.log('Sending video for ' + ip + ' (awaiting)'); + funnyListener.on(ip, () => { + resolve(outPath); + }); + } else { + if (fs.existsSync(outPath)) { + console.log('Sending video for ' + ip); + resolve(outPath); + return; + } + + console.log('Generating video for: ' + ip); + + inProgress.push(ip); + + let command = FFmpeg(); + + command + .input(path.join(__dirname, '..', 'assets', 'spongebob.png')) + .loop(1) + .input(path.join(__dirname, '..', 'assets', 'coconut.wav')) + .videoFilter( + "drawtext=fontfile=assets/comic.ttf:" + + `text='${ip.replace(new RegExp(':', 'g'), '\\:')}':` + + "fontcolor=white:" + + `fontsize=${ip.length > 15 ? '80' : '150'}:` + + "box=1:" + + "boxcolor=black@0.3:" + + "boxborderw=5:" + + "x=(w-text_w)/2:y=(h-text_h)/2:" + + "enable='gte(t,8)'") + .addOption('-t 0:21') + .addOption('-tune stillimage') + .addOption('-pix_fmt yuv420p') + .addOption('-shortest') + .addOption('-preset veryfast') + .videoCodec('libx264') + .audioCodec('aac') + .output(outPath); + + command.run(); + + command.on('end', () => { + funnyListener.emit(ip); + funnyListener.removeAllListeners(ip); + inProgress.splice(inProgress.indexOf(ip), 1); + resolve(outPath); + }); + } + }); +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index e745532..5fa5dfc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,17 @@ import Express from 'express'; -import ffmpeg from 'fluent-ffmpeg'; +import fs from 'fs'; import path from 'path'; +import makeVideo from './ffmpeg'; + +let p = path.join(__dirname, '..', 'tmp'); +if (!fs.existsSync(p)) fs.mkdirSync(p); const app = Express(); -let h = 0; - -app.get('/', (req, res) => { - h++; - res.send('aaa: ' + h); -}); - -app.get('/video', (req, res) => { - res.sendFile(path.join(__dirname, '..', 'assets', 'coconut.wav')); +app.get('/', async (req, res) => { + let ip = req.header('X-Forwarded-For')?.split(', ')[0] || req.ip; + let filePath = await makeVideo(ip); + res.sendFile(filePath); }); app.listen(6969); \ No newline at end of file