Renderizador de Fotogramas de Carrete Paint Frame
Renderiza fotogramas de video vertical de 1080x1920 perfectos en píxeles en Chrome sin cabeza, construye un script de concat demuxer de FFmpeg con microtiempos, y codifica el MP4 final en H.264 con audio AAC a 320 kbps.
flowchart TD
A[Interfaz Canvas Web 1080x1920] --> B[Captura sin cabeza con Puppeteer]
B --> C[Capturas de pantalla de fases visuales]
C --> D[Script de concat demuxer]
D --> E[Codificación FFmpeg libx264 + AAC + faststart]
E --> F[Carrete MP4 terminado]
¿Por qué Puppeteer + Concat Demuxer?
- Cero cuadros perdidos: Elimina la pérdida de cuadros y el tartamudeo de la grabación de pantalla.
- Precisión de microsegundos: A cada palabra o estado de fotograma se le asigna una duración flotante exacta en segundos.
- Ondulación de tinta por turbulencia: Usa
feTurbulenceyfeDisplacementMapde SVG con semillas rotativas para dar vida de marcador dibujado a mano al texto estático. - Velocidad: La codificación se ejecuta a 3x–6x la velocidad en tiempo real en comparación con la grabación de pantalla a 1x.
Estructura principal del script de renderizado
const puppeteer = require('puppeteer-core');
const { spawnSync } = require('child_process');
// 1. Iniciar Puppeteer a 1080x1920
const browser = await puppeteer.launch({
executablePath: CHROME_PATH,
args: ['--no-sandbox', '--disable-gpu']
});
const page = await browser.newPage();
await page.setViewport({ width: 1080, height: 1920, deviceScaleFactor: 1 });
await page.goto('file:///' + HTML_PATH);
// 2. Capturar estados de palabras / líneas
const concatLines = [];
for (const line of linesData) {
// Capturar captura de pantalla...
concatLines.push(`file '${framePath}'`);
concatLines.push(`duration ${duration.toFixed(3)}`);
}
// 3. Requisito del concat demuxer (repetir el último fotograma)
concatLines.push(concatLines[concatLines.length - 2]);
fs.writeFileSync('concat.txt', concatLines.join('\n'));
// 4. Codificar con FFmpeg
spawnSync(FFMPEG_PATH, [
'-f', 'concat', '-safe', '0', '-i', 'concat.txt',
'-ss', String(audioStartOffset),
'-i', songAudioPath,
'-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-r', '30',
'-c:a', 'aac', '-b:a', '320k',
'-shortest', '-movflags', '+faststart',
'-y', outputMp4Path
]);
Reglas clave de optimización
- Revelaciones rápidas: Las animaciones de revelación no deben superar los 0.24s durante el canto rápido.
- Factor de escala del dispositivo: Establece
deviceScaleFactor: 1para garantizar una resolución exacta de 1080x1920 sin hinchazón de memoria. - +faststart: Incluye siempre
-movflags +faststartpara que los carretes se almacenen en búfer al instante en Instagram y Telegram.