javascript getdisplaymedia 以更高分辨率记录

标签 javascript node.js html5-canvas mediarecorder get-display-media

我试图用 MediaRecorder API 制作一个基本的媒体记录器这是相当直接的:从 getDisplayMedia 获取流,然后记录它。

问题:这仅记录最大屏幕尺寸,但没有更多。所以如果我的屏幕是 1280/720,它不会记录 1920/1080。

这可能看起来很明显,但我的意图是它应该在较大的分辨率内记录较小的分辨率。例如:enter image description here

红色矩形代表我的实际屏幕正在录制的内容,周围的黑色矩形只是黑色空间,但整个视频现在具有更高的分辨率,1920/1080,这对 youtube 很有用,因为 youtube 缩小了任何内容在 720 和 1080 分辨率之间,这是一个问题。

无论如何,我尝试简单地将来自 getDisplayMedia 的流添加到视频元素视频 vid.srcObject = stream ,然后制作了一个分辨率为 1920/1080 的新 Canvas ,并在动画循环中做了 ctx.drawImage(vid, offsetX, offsetY) ,并且在制作 MediaRecorder 的循环之外,简单地做了 newStream = myCanvas.captureStream()根据 documentation of the API ,并将其传递给 MediaRecorder;然而,问题是,由于巨大的 Canvas 开销,一切都非常缓慢,帧率绝对糟糕(没有视频示例,请自行测试)。

那么是否有某种方法可以优化 Canvas 以不影响帧率(尝试查看 OffscreenCanvas 但我找不到从它本身获取流以与 MediaRecorder 一起使用的方法,所以它并没有真正帮助),或者是否有更好的方法来捕获和记录 Canvas ,或者是否有更好的方法在客户端大小的 JavaScript 中以更大的分辨率记录屏幕?如果没有客户端大小的 JavaScript,是否有某种实时视频编码器(ffmpeg 太慢)可以在服务器上运行,并且 Canvas 的每一帧都可以发送到服务器并保存在那里?有没有更好的方法来使用任何类型的 JavaScript 制作视频录像机——客户端或服务器或两者兼而有之?

最佳答案

不知道你的代码是什么样的,但我设法通过这段代码获得了流畅的体验:
(你也可以在这里找到很好的例子:https://mozdevs.github.io/MediaRecorder-examples/)

<!doctype html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="script.js"></script>
</head>
<body>
  <canvas id="canvas" style="background: black"></canvas>
</body>
// DISCLAIMER: The structure of this code is largely based on examples
// given here: https://mozdevs.github.io/MediaRecorder-examples/.

window.onload = function () {
  navigator.mediaDevices.getDisplayMedia({
    video: true
  })
  .then(function (stream) {

    var video = document.createElement('video');
    // Use "video.srcObject = stream;" instead of "video.src = URL.createObjectURL(stream);" to avoid
    // errors in the examples of https://mozdevs.github.io/MediaRecorder-examples/
    // credits to https://stackoverflow.com/a/53821674/5203275
    video.srcObject = stream;
    video.addEventListener('loadedmetadata', function () {
      initCanvas(video);
    });
    video.play();
  });
};

function initCanvas(video) {

  var canvas = document.getElementById('canvas');

  // Margins around the video inside the canvas.
  var xMargin     = 100;
  var yMargin     = 100;
  
  var videoWidth  = video.videoWidth;
  var videoHeight = video.videoHeight;

  canvas.width  = videoWidth  + 2 * xMargin;
  canvas.height = videoHeight + 2 * yMargin;

  var context = canvas.getContext('2d');
  var draw = function () {
    // requestAnimationFrame(draw) will render the canvas as fast as possible
    // if you want to limit the framerate a particular value take a look at
    // https://stackoverflow.com/questions/19764018/controlling-fps-with-requestanimationframe
    requestAnimationFrame(draw);
    context.drawImage(video, xMargin, yMargin, videoWidth, videoHeight);
  };

  requestAnimationFrame(draw);
}

关于javascript getdisplaymedia 以更高分辨率记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61313375/

相关文章:

javascript - 在哪里/如何为我自己创建的表单(Vue)组件定义提交目的地?

javascript - 在新选项卡中打开链接在 IE10 中不起作用

node.js - 部署到heroku : Invalid end points

node.js - 使用 Angular.js 和 Node.js 构建实时应用程序的更好方法是什么?

javascript - 如何在 Fabric.js 中为事件文本添加轮廓

javascript - 使用 JQuery 仅显示小数点后 2 位

javascript - 如何判断节点类型

javascript - 升级 reactJS 后出现非法访问错误

javascript - 如何只保存 Canvas 的图像而不是所有 Canvas

javascript - HTML Canvas,缓慢且笨重