【问题标题】:How to mix / combine multiple WebRTC media streams (screen capture + webcam) into a single stream?如何将多个 WebRTC 媒体流(屏幕捕获 + 网络摄像头)混合/组合成一个流?
【发布时间】:2021-04-10 05:05:18
【问题描述】:

我有一个从getDisplayMedia() 返回的实时屏幕截图媒体流,
以及从getUserMedia() 返回的实时网络摄像头媒体流。

我目前在屏幕共享视频上渲染网络摄像头视频,以创建画中画效果:

我想将它们混合/组合成一个视频流,以便在单个 HTML 视频元素中呈现它。
我想让两个流都保持活跃和直播,就好像它们是两个独立的视频,呈现两个不同的媒体流一样。
我还需要保持流位置 - 保持网络摄像头流小并位于屏幕共享流的顶部。保持原始分辨率和比特率对我来说也很重要。

我该怎么做?

【问题讨论】:

    标签: html5-canvas webrtc html5-video mediastream get-display-media


    【解决方案1】:

    您可以在 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, 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。

    【讨论】:

    • 感谢您的回复!保持原始流的分辨率和比特率对我来说非常重要。在渲染画布时我可以做哪些优化,这对于屏幕共享/网络摄像头流来说是理想的?
    • 没有。如果这很重要,请分别发送两个流,因为它们可能不会共享相同的比特率。
    【解决方案2】:

    我尝试在画布上渲染,但每当我更改/最小化我的网络应用程序选项卡时,刷新率都会下降。我可以使用audioTimerLoop 解决这个问题。 但它仍然无法在 Firefox 上运行。
    由于我现在仅限于 chrome,因此我使用PictureInPicture api 将 userMedia 显示为 PiP,然后只记录 screenMedia。 这让用户可以调整他们在 canvas 方法中固定的 cam 视频坐标。

    附:为了获得点子模式。我在屏幕上显示了 userMedia 并将其不透明度设置为 0%,并创建了一个按钮来切换它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 2017-05-24
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多