Javascript 使用canvas.captureStream()使用alpha通道捕获视频
我试图用alpha通道捕获画布元素的内容。当我这样做,我得到正确的RGB值,但阿尔法通道似乎得到下降时,播放产生的视频。有没有办法做到这一点 我正在运行以下代码:Javascript 使用canvas.captureStream()使用alpha通道捕获视频,javascript,html,google-chrome,canvas,mediarecorder-api,Javascript,Html,Google Chrome,Canvas,Mediarecorder Api,我试图用alpha通道捕获画布元素的内容。当我这样做,我得到正确的RGB值,但阿尔法通道似乎得到下降时,播放产生的视频。有没有办法做到这一点 我正在运行以下代码: var stream = canvas.captureStream(60); var recorder = new MediaRecorder(stream); recorder.addEventListener('dataavailable', finishCapturing); recorder.addEventListener
var stream = canvas.captureStream(60);
var recorder = new MediaRecorder(stream);
recorder.addEventListener('dataavailable', finishCapturing);
recorder.addEventListener('stop', function(e) {
video.oncanplay = video.play;
video.src = URL.createObjectURL(new Blob(blobs, {type:"video/webm; codecs=vp9"}));
});
startCapturing();
recorder.start();
以下是一个plnkr演示了这个问题:
目前没有从MediaRecorder API启用(VP8/9透明通道)的选项。
有人可能会在W3C git repo上提出一个问题 因此,我可以猜测几个原因:
- 据我所知,webm alpha频道是一个来自chrome的骇客,它并没有真正在编解码器中实现,也没有完全稳定
- MediaRecorder应该能够以多种格式编码,即使当前的实现仅支持视频webm/VP8和webm/VP9(仅限chrome)。因此,这意味着他们必须以某种方式将alpha通道保留在原始流中,仅用于这个新的
方法。从历史上看,MediaStream主要来自getUserMedia接口,不需要从中获得透明度。canvas.captureStream
[编辑:自编写此答案后,情况发生了变化,MediaStreams现在应该保留alpha频道,即使消费者可能无法使用它,Chrome现在也支持更多视频编解码器。] - Chrome是唯一一款在其稳定频道(FF在nightly 54中支持它)中支持YUVA webm显示的浏览器,在他们录制的文件中,让他们在添加hackish
之前解决这个问题alpha_mode=true
fillRect
)设置为不会在图形中其他位置出现的色度,在其上绘制原始文件并录制其流。录制完成后,使用ffmpeg对录制的视频重新编码,这次使用alpha通道:
// all #00FF00 pixels will become transparent.
ffmpeg -i in.webm -c:v libvpx -vf "chromakey=0x00ff00:0.1:0.1,format=yuva420p" -auto-alt-ref 0 out.webm
我个人需要-auto alt ref 0
标志,但不确定每个人都需要它
但正因为如此,您实际上也必须在屏幕上附加另一个画布,并用css隐藏它(opacity:0;width:0px;height:0px;
应该这样做)
TL;博士
这个API的实现还远未稳定,还没有人提出这样一个功能的要求,但它可能会在不久的将来出现,暂时可以在服务器端完成。什么视频格式支持透明?@dandavis webm确实支持alpha。这里的问题是,为了让录音机能够足够快地录制和编码以及制作小尺寸的视频,我猜他们已经放弃了对alpha通道的支持(IIRC仅闪烁浏览器支持播放这些视频)。很高兴知道,去闪烁,但它做了它所做的,在这一点上,我们很幸运能够制作视频。给它时间,不要把你的头发拔出来看;好吧,这是不可能的。作为旁白,Cr应该支持用alpha频道录制视频,并填写请求——我敢建议我们都将其明星化,这样它就可以得到优先权:-)你能详细说明一下这句话吗:“在它上面画上原来的那个”?谢谢。@TelmoMarques
recordingContext.fillStyle=uniqueColor;recordingContext.fillRect(0,0,visibleCanvas.width,visibleCanvas.height);recordingContext.drawImage(visibleCanvas,0,0)代码>谢谢!这是否适用于动画?我必须将drawImage()
放入setInterval()
中才能绘制所有帧,但这会导致一些粗制滥造的动画(因为clearRect()
在drawImage()
之前被调用)。忘了它,用requestAnimationFrame()
而不是setInterval()
解决了这个问题!