Получить необработанные пиксельные данные из видео 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:
-
В коде внизу я установил поток для видео тега. См. Https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm для получения дополнительной информации о веб-камере.
-
Я установил интервал в одну секунду (вызывает функцию каждую секунду), чтобы очистить холст, а затем нарисовать, какой поток был в этом кадре.
-
Теперь твоя очередь. Минимизация видео или холста не должна влиять на то, что делать. Теперь вы можете захватывать цвета пикселей на веб-камере или видео в любое время.
Вот рабочий код:
Примечание. Я обнаружил, что этот пример не работает со встроенным средством просмотра веб-страниц. Этот пример нуждается в собственной веб-странице.
<!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.