Sel*_*çuk 5 canvas stream media-source mediastream
根据 MDN:
该
HTMLMediaElement
接口添加HTMLElement
了支持音频和视频常见的基本媒体相关功能所需的属性和方法。
HTMLMediaElement.captureStream()
. 它可以与<video>
和<canvas>
元素一起使用来捕获它们的流。
相反,一个可以添加一个视频流作为srcObject
一个<video>
元素,则它示出了它。是否有可能为<canvas>
元素呢?
是否可以将流作为源添加到 html<canvas>
元素?
不,任何 Canvas API 都不能使用 MediaStream。
画布 API 仅适用于原始像素,并且不包含任何类型的解码器。您必须使用能够进行此解码的 javascript 对象(例如 ImageBitmap)或 HTMLElements。
因此,在 MediaStream 的情况下,目前唯一能够解码其视频内容的对象将是 HTMLVideoElement,您将能够轻松地在画布上绘制。
该WebCodecs API最近已经取得了很大进展,并正在成为越来越成熟了,它现在是作为一个解决方案中提到值得的。
这个 API 提供了一个名为VideoFrame的新接口,它将很快成为CanvasImageSources类型的一部分,这意味着我们可以直接使用它drawImage
,texImage2D
并且可以在任何地方使用这样的CanvasImageSource。
该MediaCapture变换W3C集团已开发出MediaStreamTrackProcessor,它从视频MediaStreamTrack退回这些VideoFrames。
所以我们现在有一种更直接的方法来将 MediaStream 渲染到画布上,该方法目前仅适用于带有#enable-experimental-web-platform-features
标志的Chrome 浏览器...
if( window.MediaStreamTrackProcessor ) {
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const track = getCanvasTrack(); // MediaStream.getVideoTracks()[0]
const processor = new MediaStreamTrackProcessor( track );
const reader = processor.readable.getReader();
readChunk();
function readChunk() {
reader.read().then( ({ done, value }) => {
// the MediaStream video can have dynamic size
if( canvas.width !== value.displayWidth || canvas.height !== value.displayHeight ) {
canvas.width = value.displayWidth;
canvas.height = value.displayHeight;
}
ctx.clearRect( 0, 0, canvas.width, canvas.height );
// value is a VideoFrame
ctx.drawImage( value, 0, 0 );
value.close(); // close the VideoFrame when we're done with it
if( !done ) {
readChunk();
}
});
}
}
else {
console.error("Your browser doesn't support this API yet");
}
// We can't use getUserMedia in StackSnippets
// So here we use a simple canvas as source
// for our MediaStream.
function getCanvasTrack() {
// just some noise...
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const img = new ImageData(300, 150);
const data = new Uint32Array(img.data.buffer);
const track = canvas.captureStream().getVideoTracks()[0];
anim();
return track;
function anim() {
for( let i=0; i<data.length;i++ ) {
data[i] = Math.random() * 0xFFFFFF + 0xFF000000;
}
ctx.putImageData(img, 0, 0);
if( track.readyState === "live" ) {
requestAnimationFrame(anim);
}
}
}
Run Code Online (Sandbox Code Playgroud)
<canvas></canvas>
Run Code Online (Sandbox Code Playgroud)