问题描述
我有一个从 getDisplayMedia() 返回的实时屏幕截图媒体流,
以及从 getUserMedia() 返回的实时网络摄像头媒体流。
我目前在屏幕共享视频的顶部渲染网络摄像头视频,以创建画中画效果:
我想将它们混合/组合成一个视频流,以便在单个 HTML 视频元素中呈现它。
我想让两个流都保持活跃和直播,就像它们是呈现两个不同媒体流的两个独立视频一样。
我还需要保持流位置 - 保持网络摄像头流很小并位于屏幕共享流之上。保持原始分辨率和比特率对我来说也很重要。
我该怎么做?
解决方法
您可以在 HTMLCanvasElement 上绘制两个视频流,然后从该 HTMLCanvasElement 调用其 captureStream 方法创建 MediaStream。
要绘制两个视频流,您必须在
async function getOverlayedVideoStreams( stream1,stream2 ) {
// prepare both players
const vid1 = document.createElement("video");
const vid2 = document.createElement("video");
vid1.muted = vid2.muted = true;
vid1.srcObject = stream1;
vid2.srcObject = stream2;
await Promise.all( [
vid1.play(),vid2.play()
] );
// craete the renderer
const canvas = document.createElement("canvas");
let w = canvas.width = vid1.videoWidth;
let h = canvas.height = vid1.videoHeight;
const ctx = canvas.getContext("2d");
// MediaStreams can change size while streaming,so we need to handle it
vid1.onresize = (evt) => {
w = canvas.width = vid1.videoWidth;
h = canvas.height = vid1.videoHeight;
};
// start the animation loop
anim();
return canvas.captureStream();
function anim() {
// draw bg video
ctx.drawImage( vid1,0 );
// caculate size and position of small corner-vid (you may change it as you like)
const cam_w = vid2.videoWidth;
const cam_h = vid2.videoHeight;
const cam_ratio = cam_w / cam_h;
const out_h = h / 3;
const out_w = out_h * cam_ratio;
ctx.drawImage( vid2,w - out_w,h - out_h,out_w,out_h );
// do the same thing again at next screen paint
requestAnimationFrame( anim );
}
}
Live demo as a glitch 因为 StackSnippets 不允许捕获 API。