如何手动停止getDisplayMedia流以结束屏幕捕获?

时间:2019-10-10 16:44:02

标签: browser webrtc screen-capture webpage-screenshot get-display-media

我有兴趣从用户那里获取屏幕截图,并且我正在使用getDisplayMedia API来捕获用户的屏幕:

const constraints = { video: true, audio: false };

if (navigator.mediaDevices["getDisplayMedia"]) {
  navigator.mediaDevices["getDisplayMedia"](constraints).then(startStream).catch(error);
} else {
  navigator.getDisplayMedia(constraints).then(startStream).catch(error);
}

执行后,浏览器会提示用户是否要共享其显示。用户接受提示后,提供的回调将收到MediaStream。为了可视化,我将其直接绑定到元素:

  const startStream = (stream: MediaStream) => {
    this.video.nativeElement.srcObject = stream;
  };

到目前为止,这很简单而且非常有效。不过,我只对单个帧感兴趣,因此,我想在处理完流后立即手动停止该流。

我试图从DOM中删除video元素,但是Chrome一直显示一条消息,指出当前正在捕获屏幕。因此,这只会影响视频元素,而不会影响流本身:

Screen Capturing in Progress (German)

我看过Screen Capture API article on MDN,但找不到有关如何停止流的任何提示。

如何正确结束流,使提示也停止?

2 个答案:

答案 0 :(得分:3)

您可以停止流的曲目,而不是停止流本身。
使用getTracks方法遍历轨道,并在每个轨道上调用stop()

stream.getTracks()
  .forEach(track => track.stop())

所有曲目停止播放后,Chrome的捕获提示也会消失。

答案 1 :(得分:0)

开始屏幕截图示例代码:

async function startCapture() {
  logElem.innerHTML = "";

  try {
    videoElem.srcObject = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
    dumpOptionsInfo();
  } catch(err) {
    console.error("Error: " + err);
  }
}

停止截屏示例代码:

function stopCapture(evt) {
  let tracks = videoElem.srcObject.getTracks();

  tracks.forEach(track => track.stop());
  videoElem.srcObject = null;
}

更多信息:MDN - Stopping display capture