首页 > 解决方案 > 使用 MediaRecorder 与 ffmpeg.js 导出 HTML 视频

问题描述

TLDR

想象一下,我有一个视频和一个图像。我想创建另一个视频,在视频开头将图像(例如水印)覆盖 2 秒,并将其导出为最终视频。我只需要在客户端执行此操作。是否可以使用 MediaRecorder + Canvas 或者我应该求助于使用 ffmpeg.js?

语境

我正在制作一个基于浏览器的视频编辑器,用户可以在其中上传视频和图像并将它们组合起来。到目前为止,我通过将视频和图像适当地嵌入到画布元素中来实现这一点。数据表示看起来有点像这样:

video: {
  url: 'https://archive.com/video.mp4',
  duration: 34,
},
images: [{
  url: 'https://archive.com/img1.jpg',
  start_time: 0,
  end_time: 2,
  top: 30,
  left: 20,
  width: 50,
  height: 50,
}]

尝试

  1. 我在画布中播放视频并显示/隐藏图像。然后,我可以使用MediaRecorder来捕获画布的流并在最后将其导出为数据块。最终输出符合预期,但这种方法的问题是我需要从头到尾播放视频,以便我从画布中捕获流。如果视频是 60 秒,那么导出也需要 60 秒。

function record(canvas) {
  return new Promise(function (res, rej) {
    const stream = canvas.captureStream();
    const mediaRecorder = new MediaRecorder(stream);
    const recordedData = [];

    // Register recorder events
    mediaRecorder.ondataavailable = function (event) {
      recordedData.push(event.data);
    };
    mediaRecorder.onstop = function (event) {
      var blob = new Blob(recordedData, {
        type: "video/webm",
      });
      var url = URL.createObjectURL(blob);
      res(url);
    };

    // Start the video and start recording
    videoRef.current.currentTime = 0;
    videoRef.current.addEventListener(
      "play",
      (e) => {
        mediaRecorder.start();
      },
      {
        once: true,
      }
    );
    videoRef.current.addEventListener(
      "ended",
      (e) => {
        mediaRecorder.stop();
      },
      {
        once: true,
      }
    );
    videoRef.current.play();
  });
}

  1. 我可以使用ffmpeg.js对视频进行编码。我还没有尝试过这种方法,因为我必须将我的图像表示转换为 ffmpeg args(我想知道这是多少工作)。

标签: javascriptffmpegmediarecorder

解决方案


推荐阅读