如何将录制的DOM转成视频文件

简介: 如何将录制的DOM转成视频文件

背景说明:


     最近有在看GitHub上的rrweb项目,确实是一款DOM录制的神器,在使用文档中提供了很多我们会用到的场景和对应的示例,我们今天来看一下其中一个场景《转换为视频》,虽然rrweb直接回放的效果最佳但还是会遇到需要转为视频进行存储的要求,通过查看rrweb提供的rrvideo项目后决定写一下整个转换的过程,大致的流程图如下:

1.png


环境配置:


  1. 安装FFmpeg:用于将逐帧的图片数据转换为视频。
  2. 安装puppeteer:用于在后台加载网页。
  3. 安装rrweb-player:用于播放rrweb录制的events数据。


使用puppeteer打开空白页面:


  1. 获取browser对象实例:browser = await puppeteer.launch({ headless: true });
  2. 打开新页签:page = await browser.newPage();&await page.goto("about:blank");
  3. 通过page.exposeFunction在window对象上挂载开始和结束录制的调用函数;
  4. 将需要播放的events数据使用page.setContent()加载进页面。
try {
  browser = await puppeteer.launch({ headless: true });
  page = await browser.newPage();
  await page.goto("about:blank");
  // 扩展启动录制函数
  await page.exposeFunction("onReplayStart", async () => {
    await startReplay();
  });
  // 扩展结束录制函数
  await page.exposeFunction("onReplayFinish", async () => {
    await finishReplay();
  });
  // 读取原数据
  const events = JSON.parse(
    fs.readFileSync(path.resolve(process.cwd(), _input), "utf-8")
  );
  await page.setContent(getHtml(events));
} catch (error) {
  console.log("openPage:", error);
}
复制代码


组装最简支持rrweb-player播放的DOM结构:


  1. 获取安装到node_modules内的rrweb-player包的内容,便于插入到DOM中;
// 获取rrweb-player的脚本插入到DOM中
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");
复制代码
  1. 拼装满足rrweb-player播放的基础DOM,其中在replayer.play()函数执行前开启录制并在监听到播放完成后结束录制:
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>
        `;
复制代码


通过puppeteer提供的screenshot函数定时截屏获取数据流:


  1. 获取到需要录制的元素对象:const wrapperEl = await page.$(".replayer-wrapper");
  2. 通过screenshot来截取当前帧的画面,返回数据类型为二进制数据。
const buffer = await wrapperEl?.screenshot({
  encoding: "binary",
});
复制代码


执行ffmpeg命令并将截屏数据输入到ffmpeg进程:


  1. 我们使用NodeJs提供的spawn函数来执行FFmpeg命令,此处未配置环境变量而直接引用的FFmpeg的绝对路径:
const ffmpegProcess = spawn("D:\\ffmpeg\\bin\\ffmpeg", [
    // fps
    "-framerate",
    "15",
    // input
    "-f",
    "image2pipe",
    "-i",
    "-",
    // output
    "-y",
    _output,
  ]);
复制代码
  1. 将截图得到的二进制数据写入ffmpegProcess进程的标准输入流中:ffmpegProcess.stdin.write(buffer);


总结说明:


  1. 以上就是对rrvideo流程拆解一些关键点说明,完整代码在GitHub
  2. rrvideo还提供了常用的一些配置项来便于调整视频的尺寸等信息。
  3. puppeteer是继上次做自动生成骨架屏后的第二次使用。



相关文章
|
存储 Cloud Native Linux
音视频 ffmpeg命令图片与视频互转
音视频 ffmpeg命令图片与视频互转
|
开发框架 JavaScript 前端开发
Javascript实现视频文件播放功能
Javascript实现视频文件播放功能
175 0
|
移动开发 JavaScript
JS指定音频audio在某个时间点进行播放,获取当前音频audio的长度,音频时长格式转化
JS指定音频audio在某个时间点进行播放,获取当前音频audio的长度,音频时长格式转化
771 0
JS指定音频audio在某个时间点进行播放,获取当前音频audio的长度,音频时长格式转化
|
编解码 iOS开发 内存技术
iOS 录音、音频的拼接剪切以及边录边压缩转码
iOS 录音、音频的拼接剪切以及边录边压缩转码
847 0
iOS 录音、音频的拼接剪切以及边录边压缩转码
|
Java Maven
获取MP3音频时长 | Java工具类
获取MP3音频时长 | Java工具类
获取MP3音频时长 | Java工具类
|
移动开发 编解码 前端开发
这段代码可以将Canvas录制为webm视频文件
2020年6月我做了一个给程序员专用的虚拟鼓励师插件叫“Rainbow Fart Waifu”,VSCode和HBuilderX的插件市场里都可以搜到。
437 0
这段代码可以将Canvas录制为webm视频文件
|
Python
将 PDF 转换为音频文件
将 PDF 转换为音频文件
449 0
几种播放音频文件的方式
几种播放音频文件的方式(一) —— 播放本地音乐几种播放音频文件的方式(二) —— 音效播放几种播放音频文件的方式(三) —— 网络音乐播放几种播放音频文件的方式(四) —— 音频队列服务(Audio Queue Services)(一)几种播放音频文...
1557 0
几种播放视频文件的方式
几种播放视频文件的方式(一) —— 总结播放视频的几种方式(一)几种播放视频文件的方式(二) —— 基于MediaPlayer框架的视频播放(一)几种播放视频文件的方式(三) —— 基于AVFoundation框架视频播放(一)几种播放视频文件的方式(...
1250 0