我想从视频元素中获取原始数据(TypedArray或其他内容)并使用JavaScript操作它们。
目前我创建了一个新画布,将视频绘制到画布中,然后获取图像数据。
ctx.drawImage(myVideo);
var data = ctx.getImageData(0, 0, w, h).data;
它工作正常,但它耗尽了CPU(将视频放到画布上并从画布复制回来)并且它会产生大量垃圾(每秒大约50 MB)。还有其他更简单的解决方案吗?如果我可以将自己的缓冲区传递给getImageData(...),那就太好了。
顺便说一句。使用WebGL绘制视频并从GPU加载它不会更快:( http://jsperf.com/getting-raw-data-from-video
答案 0 :(得分:4)
请阅读
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>
上放置视频帧,您将无法获得对视频数据的任何原始访问权限。但是,我相信这个操作应该是硬件加速,因为它发生在GPU内存中。从GPU下载像素,在Javascript中操作它们然后上传回显示内存可能是高分辨率的最慢步骤。
优化提示
考虑跳帧(较低FPS的过程效果)
服务器端HTML5视频呈现Rendering HTML5 animation server-side?
答案 1 :(得分:1)
clearRect()是我想要的。
据我所知,在画布上上传图像会占用空间,但是clearRect()会删除画布上的所有内存。
我对JS代码所做的事情:
在下面的代码下方,我在视频标签上设置了流。有关更多网络摄像头信息,请参见https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm。
我将间隔设置为一秒钟(每秒调用一次函数)以清除画布,然后绘制该帧上的流。
现在轮到您了。最小化视频或画布不会影响操作。现在,您可以随时在网络摄像头或视频上获取彩色图像。
这是工作代码:
注意:我发现此示例不适用于内置的Web查看器。此示例需要它自己的网页。
<!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>
答案 2 :(得分:0)
canvas{display:none}
可能有助于减少一些开销。画布仍然可供js访问。