当前位置:网站首页>How to convert a recorded DOM to a video file

How to convert a recorded DOM to a video file

2022-06-25 15:35:00 Xiao Xin

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 :

 mapping 1.png

Environment configuration :

  1. install FFmpeg: It is used to convert frame by frame picture data into video .
  2. install puppeteer: Used to load web pages in the background .
  3. install rrweb-player: For playing rrweb Recorded events data .

    Use puppeteer Open a blank page :

  4. obtain browser Object instances :browser = await puppeteer.launch({ headless: true });;
  5. Open a new tab :page = await browser.newPage();&await page.goto("about:blank");;
  6. adopt page.exposeFunction stay window Object to start and end recording ;
  7. 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 :

  8. 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");
  9. 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 :

  10. Get the element object to be recorded :const wrapperEl = await page.$(".replayer-wrapper");
  11. 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 :

  12. 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,
      ]);
  13. Write the binary data obtained from the screenshot into ffmpegProcess In the standard input stream of the process :ffmpegProcess.stdin.write(buffer);

    A summary :

    1. That's right rrvideo Description of some key points of process disassembly , Complete code in GitHub.
    2. rrvideo Some common configuration items are also provided to facilitate the adjustment of video size and other information .
    3. 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 .

原网站

版权声明
本文为[Xiao Xin]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202192226584783.html