javascript getdisplaymedia record в более высоком разрешении - PullRequest
1 голос
/ 20 апреля 2020

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

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

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

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

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

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

1 Ответ

0 голосов
/ 03 мая 2020

Не знаю, как выглядит ваш код, но мне удалось получить плавный опыт с этим фрагментом кода:

(Вы также найдете очень хороший пример здесь: https://github.com/mozdevs/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://github.com/mozdevs/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://github.com/mozdevs/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);
}
...