2024-02-18 18:32:58 +01:00
|
|
|
import { Command } from 'commander';
|
|
|
|
import puppeteer from 'puppeteer';
|
|
|
|
import fs from 'fs';
|
|
|
|
|
|
|
|
const program = new Command();
|
|
|
|
program
|
|
|
|
.requiredOption('-o, --output <output>', 'Output directory')
|
|
|
|
.requiredOption('--fps <fps>', 'Frames per second')
|
|
|
|
.requiredOption('--cycles <cycles>', 'Number of cycles')
|
|
|
|
.requiredOption('--size <size>', 'Size of the output in pixels')
|
|
|
|
.requiredOption('--url <url>', 'URL to render')
|
|
|
|
.parse(process.argv);
|
|
|
|
const options = program.opts();
|
|
|
|
|
|
|
|
// mkdir p output path
|
|
|
|
if (!fs.existsSync(options.output)) {
|
|
|
|
fs.mkdirSync(options.output, { recursive: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
const browser = await puppeteer.launch({
|
|
|
|
args: ['--no-sandbox']
|
|
|
|
});
|
|
|
|
const page = await browser.newPage();
|
|
|
|
|
|
|
|
await page.setViewport({ width: parseInt(options.size, 10), height: parseInt(options.size, 10) });
|
|
|
|
await page.goto(options.url);
|
|
|
|
|
|
|
|
await page.evaluate(async (fps) => {
|
|
|
|
// @ts-ignore
|
|
|
|
await window.setFps(fps);
|
|
|
|
}, options.fps);
|
|
|
|
|
|
|
|
const totalFrames = parseInt(options.fps) * parseInt(options.cycles);
|
|
|
|
for (let frame = 0; frame < totalFrames; frame++) {
|
|
|
|
let start = Date.now();
|
|
|
|
await page.evaluate(async (n) => {
|
|
|
|
// @ts-ignore
|
|
|
|
await window.setFrame(n);
|
|
|
|
}, frame);
|
|
|
|
const path = `${options.output}/${frame.toString().padStart(Math.log10(totalFrames) + 1, '0')}.png`;
|
|
|
|
await page.screenshot({ path, omitBackground: true });
|
|
|
|
let end = Date.now();
|
2024-02-18 22:22:38 +01:00
|
|
|
console.log(`Captured frame ${frame + 1}/${totalFrames} (took ${end - start}ms)`);
|
2024-02-18 18:32:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Done.');
|
|
|
|
|
|
|
|
await browser.close();
|