javascript getdisplaymedia запись в более высоком разрешении

Я пытался создать базовый медиа-рекордер с помощью MediaRecorder API что довольно просто: получите поток из getDisplayMedia, затем запишите его.

Проблема: записывается только максимальный размер экрана, но не более того. Так что, если мой экран 1280/720, он не будет записывать 1920/1080.

Это может показаться довольно очевидным, но я намерен записать меньшее разрешение внутри большего. Например:  введите описание изображения здесь

Красный прямоугольник представляет то, что записывает мой фактический экран, а окружающий его черный прямоугольник представляет собой просто черное пространство, но все видео теперь имеет более высокое разрешение, 1920/1080, что полезно для YouTube, поскольку YouTube уменьшает все, что находится в между разрешением 720 и 1080, что является проблемой.

В любом случае я попытался просто добавить поток из getDisplayMedia в видеоэлемент video vid.srcObject = stream, затем создал новый холст с разрешением 1920/1080, и в цикле анимации просто сделал ctx.drawImage(vid, offsetX, offsetY), а вне цикла, где был создан MediaRecorder, просто сделал newStream = myCanvas.captureStream() согласно документации API, и передал это в MediaRecorder; однако проблема в том, что из-за огромных накладных расходов на холст все работает очень медленно, а частота кадров абсолютно ужасна (нет видео-примера, просто проверьте его сами).

Итак, есть ли способ оптимизировать холст, чтобы не влиять на частоту кадров (пытался заглянуть в OffscreenCanvas, но я не смог найти способ получить поток из него для использования с MediaRecorder, поэтому это не помогло), или есть лучший способ захвата и записи холста, или есть ли лучший способ записать экран с большим разрешением в клиентском JavaScript? Если не с клиентским JavaScript, существует ли какой-нибудь кодировщик видео в реальном времени (ffmpeg слишком медленный), который можно было бы запустить на сервере, и каждый кадр холста можно было бы отправить на сервер и сохранить там? Есть ли лучший способ сделать видеомагнитофон с любым видом JavaScript - клиентом или сервером, или обоими?


person bluejayke    schedule 20.04.2020    source источник


Ответы (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);
}
person geauser    schedule 03.05.2020
comment
Привет, похоже, это то же самое, что было упомянуто в вопросе, что три холста были предприняты, но это не сработало и т. Д. Из-за больших накладных расходов, это другой способ сделать это? - person John Goshen; 22.04.2021