Dear, Hello everyone , I am a “ Front end Xiaoxin ”, Engaged in front-end development for a long time , Android Development , Love technology , Go farther and farther on the road of programming ~
The background that :
I've been looking at GitHub Upper rrweb project , It's really a DOM Recorded artifact , The usage document provides many scenarios and corresponding examples that we will use , Let's take a look at one of the scenes today 《 Convert to video 》, although rrweb The effect of direct playback is the best, but there are still requirements to convert to video for storage , By looking at rrweb Provided rrvideo After the project, I decided to write down the whole conversion process , The general flow chart is as follows :
Environment configuration :
- install FFmpeg: It is used to convert frame by frame picture data into video .
- install puppeteer: Used to load web pages in the background .
install rrweb-player: For playing rrweb Recorded events data .
Use puppeteer Open a blank page :
- obtain browser Object instances :
browser = await puppeteer.launch({ headless: true });; - Open a new tab :
page = await browser.newPage();&await page.goto("about:blank");; - adopt
page.exposeFunctionstay window Object to start and end recording ; Will need to play events Data usage
page.setContent()Load into page .try { browser = await puppeteer.launch({ headless: true }); page = await browser.newPage(); await page.goto("about:blank"); // Extended start recording function await page.exposeFunction("onReplayStart", async () => { await startReplay(); }); // Extended end recording function await page.exposeFunction("onReplayFinish", async () => { await finishReplay(); }); // Read original data const events = JSON.parse( fs.readFileSync(path.resolve(process.cwd(), _input), "utf-8") ); await page.setContent(getHtml(events)); } catch (error) { console.log("openPage:", error); }The simplest assembly supports rrweb-player Played DOM structure :
Get installed to node_modules Internal rrweb-player The contents of the package , Easy to insert into DOM in ;
// obtain rrweb-player Insert your script into DOM in const rrwebScriptPath = path.resolve( require.resolve("rrweb-player"), "../../dist/index.js" ); const rrwebStylePath = path.resolve(rrwebScriptPath, "../style.css"); const rrwebRaw = fs.readFileSync(rrwebScriptPath, "utf-8"); const rrwebStyle = fs.readFileSync(rrwebStylePath, "utf-8");Assembly satisfaction rrweb-player The basis of playing DOM, Among them in replayer.play() The function starts recording before execution and ends recording after listening to the completion of playback :
const html = ` <html> <head> <style>${rrwebStyle}</style> </head> <body> <script> ${rrwebRaw}; /*<!--*/ const events = ${JSON.stringify(events).replace( /<\/script>/g, "<\\/script>" )}; /*-->*/ window.replayer = new rrwebPlayer({ target: document.body, props: { events, showController: false, }, }); window.onReplayStart(); window.replayer.play(); window.replayer.addEventListener('finish', () => { window.onReplayFinish() }); </script> </body> </html> `;adopt puppeteer Provided screenshot Function to capture the screen regularly to obtain the data stream :
- Get the element object to be recorded :
const wrapperEl = await page.$(".replayer-wrapper"); adopt screenshot To capture the picture of the current frame , The returned data type is binary data .
const buffer = await wrapperEl?.screenshot({ encoding: "binary", });perform ffmpeg Command and enter the screenshot data into ffmpeg process :
We use NodeJs Provided spawn Function to execute FFmpeg command , The environment variable is not configured here and is directly referenced FFmpeg The absolute path of :
const ffmpegProcess = spawn("D:\\ffmpeg\\bin\\ffmpeg", [ // fps "-framerate", "15", // input "-f", "image2pipe", "-i", "-", // output "-y", _output, ]);Write the binary data obtained from the screenshot into ffmpegProcess In the standard input stream of the process :
ffmpegProcess.stdin.write(buffer);A summary :
- That's right rrvideo Description of some key points of process disassembly , Complete code in GitHub.
- rrvideo Some common configuration items are also provided to facilitate the adjustment of video size and other information .
- puppeteer This is the second use since the last automatic generation of skeleton screen .
Welcome to my official account. “ Front end Xiaoxin ”, Original technical articles are pushed at the first time .






![[paper notes] poly yolo: higher speed, more precise detection and instance segmentation for yolov3](/img/28/6d58759a4a4b18923a5ed5ed573956.jpg)


