Chr*_*ich 1 javascript video canvas
我有一个视频将像素复制到画布并使用web worker应用实时位图过滤器.
使用网络工作者时,我无法在画布上看到结果发生的变化(应该是黑色的'白色).
这是我的代码:http: //www.dev.createdbychristian.com/filter-test/
我可以通过使用中间画布来解决这个问题,但我真的不想那样做.
我的代码松散地基于这个例子,就像我刚刚没有使用web worker进行图像过滤处理一样. http://techslides.com/demos/html5-video-canvas.html
我的代码出了什么问题?
注意:需要一个支持Web Workers和HTML5 Video/canvas的现代浏览器
发生这种情况是因为draw()
不等待WebWorker的返回值并使用requestAnimationFrame
.如果您想要连续过滤的图像draw
,则必须在应用过滤器后调用:
filterWorker.addEventListener('message', function(e) {
ctx.putImageData(e.data, 0, 0);
requestAnimationFrame(draw);
}, false);
Run Code Online (Sandbox Code Playgroud)
但是,如果过滤器需要很长时间,很可能draw
会在早期注意到更改时用彩色数据填充画布(我能够在当前版本中看到带有FF17的黑色'n白色版本).
我的代码出了什么问题?
在操作顺序很重要的场景中,您正在使用工具进行并行计算:您希望在显示每个图像之前应用滤镜.让我引用MDN:
关于线程安全
该工人接口派生实时操作系统级线程,并铭记程序员可能会担心并发可能会导致在你的代码"有趣"的效果,如果你不小心.
但是,由于Web工作者已经与其他线程仔细控制了通信点,因此实际上很难导致并发问题.无法访问非线程安全组件或DOM.并且您必须通过序列化对象将特定数据传入和传出线程.因此,您必须非常努力地在代码中导致问题.
与实际操作系统级线程一样,除非您使用某种阻塞机制,否则不会按执行顺序进行任何假设,但这不包含在JavaScript中.因此,您需要在同一个线程中绘制和操作图像.
看看下面的图片:
这是techdemo中基本上发生的事情.draw()
复制视频并立即过滤图像:
function draw(v,c,w,h,filter) {
if(v.paused || v.ended) return false;
c.drawImage(v,0,0,w,h);
if (typeof filter === 'undefined') {
// variable is undefined
} else {
var idata = c.getImageData(0,0,w,h);
newdata = filterdata(idata,filter);
c.putImageData(newdata,0,0);
}
setTimeout(draw,20,v,c,w,h,filter);
}
Run Code Online (Sandbox Code Playgroud)
如您所见drawImage
,以下过滤器的调用之间没有间隙.得到的图像显示大约20毫秒.即使过滤器需要1ms,用户也可能不会注意到这一点.
现在它变得有点复杂了.黑化文本框是直接修改画布的方法,白框表示触发事件或注册超时,黑框表示执行超时或事件处理:
现在,会发生什么?draw
仍大约每20毫秒调用一次并复制视频.然后它向工作人员发布消息.但是,在发送此消息时未说明.它可以立即放置在worker的事件循环中(如图所示),也可以放在"main"的事件循环中,稍后发送(更有可能).
与顺序方法相比,此过程需要非常长的时间.请记住,您还需要发回处理过的数据,filter
并且filterWorker
可能会在比您原先预期更晚的时间触发事件监听器.但即使您实际处理数据并显示它,以下调用draw
也会破坏您的所有辛苦工作.
要么不使用Web worker,要么使用隐藏的画布作为worker的源.
归档时间: |
|
查看次数: |
649 次 |
最近记录: |