如何将媒体流复制到弹出窗口 window?

How can I duplicate a media stream to a popup window?

我想通过调用 getDisplayMedia 在我的主选项卡中启动屏幕共享,然后将其克隆到我从我的应用程序打开的另一个弹出窗口 window(使用 window.open) , 有效地同时显示两次屏幕截图。

根据 this thread, this snippet 应该可行 - 但它不可行:

async function startCapture() {
  return await navigator.mediaDevices.getDisplayMedia();
}

function openPopup() {
  startCapture().then((stream) => {
    let video = document.getElementById("source");
    video.srcObject = stream;
    let popUpWindow = window.open("", "_blank", "x=y");
    let videoElem = document.createElement("video");
    videoElem.autoplay = true;
    let remoteVideo = popUpWindow.document.body.appendChild(videoElem);
    remoteVideo.srcObject = stream;
  });
}

我错过了什么?

不,不是直接的,因为MediaStreamTrack是不可转让的。它与创建它的文档相关联。

解决方法是在两个选项卡之间建立一个 RTCPeerConnection 并将屏幕捕获轨道从有它的选项卡传输到没有的选项卡。这应该是相对高效的,因为这些位永远不会离开您的网卡。

您可以使用 BroadcastChannel 来获得必要的信号来建立这样的连接,或者像我 here 使用相机那样使用 localStorage 来发送信号,但是它适用于任何来源(首先在两个选项卡中打开,然后在一个选项卡中单击 Call 按钮)。

此解决方法的一个限制是,如果您关闭原始选项卡,那么您将丢失两个曲目。

正如@Kaiido 在评论中提到的,问题是我需要将 muted 属性添加到目标视频,以便在复制流时自动播放。

更多信息在这里:https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide

Autoplay availability
As a general rule, you can assume that media will be allowed to autoplay only if at least one of the following is true:

  • The audio is muted or its volume is set to 0
  • The user has interacted with the site (by clicking, tapping, pressing keys, etc.)
  • If the site has been whitelisted; this may happen either automatically if the browser determines that the user engages with media frequently, or manually through preferences or other user interface features
  • If the autoplay feature policy is used to grant autoplay support to a and its document. Otherwise, the playback will likely be blocked. The exact situations that result in blocking, and the specifics of how sites become whitelisted vary from browser to browser, but the above are good guidelines to go by.