Como gravar o MP4, quadro a quadro (Playwright + FFmpeg)

O arquivo HTML inclui a animação completa, todas as fontes e nenhuma dependência externa. window.render(t) posiciona qualquer quadro pelo tempo em milissegundos. Adicione ?rec ao endereço para desabilitar a reprodução automática durante a captura.

npm i playwright

// Salve como gravar.js, junto ao HTML:
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
(async () => {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage({ viewport: { width: 960, height: 720 }, deviceScaleFactor: 1 });
  await page.goto('file://' + path.resolve('whatscontabil_um_numero_vermelho.html') + '?rec');
  await page.evaluate(() => document.fonts.ready);
  fs.mkdirSync('frames', { recursive: true });
  for (let i = 0; i < 150; i++) {
    await page.evaluate(t => window.render(t), i * 40);
    await page.locator('#stage').screenshot({ path: `frames/frame_${String(i).padStart(4,'0')}.png`, animations: 'disabled' });
  }
  await browser.close();
})();

node gravar.js
ffmpeg -y -framerate 25 -i frames/frame_%04d.png -c:v libx264 -crf 23 -pix_fmt yuv420p -movflags +faststart whatscontabil_um_numero_vermelho.mp4