Javascript 画布-使用来自其他视频的alpha数据屏蔽视频速度较慢
在我的页面上,我有一个循环播放的视频。当点击播放时,另一个视频被屏蔽在上面,然后慢慢出现。简言之,我正在用另一个视频屏蔽一个视频(通过画布将黑白屏蔽转换为alphadata) 这是可行的,但是转换/视频速度非常慢,因为画布在所有像素之间循环。有没有人对实现这一点或加快这一过程的另一种方法有什么建议 HTML:Javascript 画布-使用来自其他视频的alpha数据屏蔽视频速度较慢,javascript,html,video,canvas,Javascript,Html,Video,Canvas,在我的页面上,我有一个循环播放的视频。当点击播放时,另一个视频被屏蔽在上面,然后慢慢出现。简言之,我正在用另一个视频屏蔽一个视频(通过画布将黑白屏蔽转换为alphadata) 这是可行的,但是转换/视频速度非常慢,因为画布在所有像素之间循环。有没有人对实现这一点或加快这一过程的另一种方法有什么建议 HTML: //Buffer canvas (stacked video's: result + alpha mask) <canvas style="display:none" width
//Buffer canvas (stacked video's: result + alpha mask)
<canvas style="display:none" width="1920" height="2160" id="buffer">
</canvas>
//Output canvas (combines mask with video)
<canvas class="video__output " width="1920" height="1080" id="output">
</canvas>
//buffer canvas uses this video to extract data
<video class="" id="video" preload="auto" style="display:none" >
<source src="assets/video/masking.mp4" type='video/mp4;codecs="avc1.42E01E"' />
</video>
//Video loop always playing
<video poster="assets/video/poster_desktop.jpg" class="video--top loop" autoplay loop>
<source src="assets/video/loop.mp4" type='video/mp4; codecs="avc1.42E01E"' />
</video>
//缓冲区画布(堆叠视频的:结果+alpha掩码)
//输出画布(将遮罩与视频相结合)
//缓冲区画布使用此视频提取数据
//视频循环总是在播放
JS:
函数processFrame(){
drawImage(视频,0,0);
//获取字母数据
让image=buffer.getImageData(0,0,宽度,高度),
imageData=image.data,
alphaData=buffer.getImageData(0,高度,宽度,高度).data;
//循环像素,用alpha通道替换数据
对于(设i=3,len=imageData.length;i
选项一是将两个getImageData()
s减少为一个调用。获取完整的位图,然后改用两个指针,一个指向RGB数据,另一个指向蒙版数据的开头
选项二是考虑使用WebM视频格式。这一功能目前仅在Chrome浏览器(我认为是较新的Opera)中得到支持。是否显著加快了这一过程?可能不是
getImageData
非常慢。在2个视频上同时做这件事太慢了!为了获得更好的性能,您需要至少预处理掩蔽视频,可能还需要预处理两个视频。此外,在操作视频像素时显著提高速度的一种方法是降低视频质量。首先将其绘制得更小,处理透明度并将其保存在某个位置(可能需要第二块画布)重新绘制全尺寸视频帧,将globalCompositeOperation
设置为“source in”
,最后以原始比例重新绘制小的透明帧。这里有一个全质量的视频,在alpha蒙版的边界上有一些粗糙的边缘,但这对视频来说应该没有太大影响。你为什么不干脆把两个视频元素交叉淡入淡出呢?
function processFrame() {
buffer.drawImage(video, 0, 0);
//Get alphadata
let image = buffer.getImageData(0, 0, width, height),
imageData = image.data,
alphaData = buffer.getImageData(0, height, width, height).data;
//Loop through pixels, replace data with alpha channel
for (let i = 3, len = imageData.length; i < len; i = i + 4) {
imageData[i] = alphaData[i-1];
}
//Output to second canvas
output.putImageData(image, 0, 0, 0, 0, width, height);
requestAnimationFrame(processFrame)
}