【问题标题】:javascript getdisplaymedia record at higher resolutionjavascript getdisplaymedia 以更高分辨率记录
【发布时间】:2020-04-20 00:17:19
【问题描述】:

我试图用MediaRecorder API 制作一个基本的媒体记录器,这很简单:从 getDisplayMedia 获取流,然后记录它。

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

这似乎很明显,但我的意图是它应该在较大的分辨率中记录较小的分辨率。例如:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    不知道你的代码是什么样的,但我设法通过这段代码获得了流畅的体验:

    (你也可以在这里找到很好的例子: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);
    }
    

    【讨论】:

    • 嗨,这似乎与问题中提到的相同,尝试了三个画布但由于开销大而无法正常工作等,这是另一种方法吗?
    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多