Получить необработанные пиксельные данные из видео HTML5

Я хотел бы получить необработанные данные (TypedArray или что-то) из видеоэлемента и манипулировать ими с помощью JavaScript.

В настоящее время я создаю новый холст, рисую видео в холст, а затем получаю данные изображения.

ctx.drawImage(myVideo);
var data = ctx.getImageData(0, 0, w, h).data;

Он отлично работает, но он истощает процессор (помещая видео в холст и копируя его с холста), и он создает много мусора (около 50 МБ в секунду). Есть ли еще более простое решение? Было бы здорово, если бы я мог передать свой собственный буфер getImageData (...).

BTW. рисование видео с помощью WebGL и загрузка его с GPU не быстрее:(http://jsperf.com/getting-raw-data-from-video

Ответ 1

Пожалуйста, прочитайте

https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript

Поскольку вы на самом деле не показываете какой-либо код, укажите браузер или выдайте информацию о видео (разрешение, FPS, кодирование), невозможно сказать, почему ваш код медленный или почему он создает много мусора. Видеоэффекты в реальном времени с Javasrcipt возможны с ограничением разрешения.

Вот пример использования фильтрации видео в режиме реального времени в Mozilla.

https://developer.mozilla.org/samples/video/chroma-key/index.xhtml

Вы не получите никакого необработанного доступа к видеоданных без смещения видеокадра на <canvas>. Тем не менее, я считаю, что эта операция должна быть ускорена HW, как это происходит в памяти GPU. Загрузка пикселей с графического процессора, манипулирующего ими в Javascript, а затем загрузка обратно в память дисплея может быть самым медленным шагом для высокого разрешения.

Советы по оптимизации

Ответ 2

clearRect() - это то, что, я думаю, вы ищете.

Насколько я знаю, загрузка изображений на холсты занимает место, но clearRect() удаляет всю память на холсте.

Что я сделал с кодом JS:

  1. В коде внизу я установил поток для видео тега. См. Https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm для получения дополнительной информации о веб-камере.

  2. Я установил интервал в одну секунду (вызывает функцию каждую секунду), чтобы очистить холст, а затем нарисовать, какой поток был в этом кадре.

  3. Теперь твоя очередь. Минимизация видео или холста не должна влиять на то, что делать. Теперь вы можете захватывать цвета пикселей на веб-камере или видео в любое время.

Вот рабочий код:

Примечание. Я обнаружил, что этот пример не работает со встроенным средством просмотра веб-страниц. Этот пример нуждается в собственной веб-странице.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="stuff, to, help, search, engines, not" name="keywords">
<meta content="What this page is about." name="description">
<meta content="Display Webcam Stream" name="title">
<title>Display Webcam Stream</title>
  
<style>
#container {
    margin: 0px auto;
    width: 500px;
    height: 375px;
    border: 10px #333 solid;
}
#videoElement {
    width: 500px;
    height: 375px;
    background-color: #666;
}
#canvas {
  background-color: #666;
}
</style>
</head>
  
<body>
    <video autoplay="true" id="videoElement"></video>
    <canvas id="canvas" onclick= canvasOnclick()></canvas>

<script>
var video = document.querySelector("#videoElement");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
if (navigator.mediaDevices.getUserMedia) {       
    navigator.mediaDevices.getUserMedia({video: true})
  .then(function(stream) {
    video.srcObject = stream;
  })
  .catch(function(err0r) {
    console.log("Something went wrong!");
  });
}



var myVar = setInterval(intervalTimer, 1000);

function intervalTimer() {
  ctx.clearRect(0,0,400,400);
  ctx.drawImage(video,0,0,400,400);

}

//var data = ctx.getImageData(0, 0, w, h).data;
</script>
</body>
</html>

Ответ 3

canvas{display:none} может помочь уменьшить некоторые накладные расходы. Холст остается доступным для JS.