getDisplayMedia 给出“DOMException:关联的轨道处于无效状态”

问题描述 投票:0回答:1

我写了一段代码,可以在一段时间后截取屏幕截图。 密码是:

function captureScreenshot() {
    if (screenStream) {
        screenStream.getTracks().forEach(track => {
            track.stop();
        });
    }
    navigator.mediaDevices.getDisplayMedia({video: true})
    .then(stream => {
        track = stream.getVideoTracks()[0];
        screenStream = track;
        track.applyConstraints();
        (function(delay, callback){
            var loop = function(){
                callback();
                setTimeout(loop, delay);
            }; loop();
        })(5000, function(){
            imageCapture = new ImageCapture(track);
            imageCapture.grabFrame()
            .then(imageBitmap => {
                const canvas = document.querySelector('#image');
                drawCanvas(canvas, imageBitmap);
            })
            .catch(err => {
                console.error("Error grabbing frame: ", err);
            });
        });
    })
    .catch(err => {
        console.error("Error getting display media: ", err);
    });
}

问题是: 每当我尝试使用外部按钮运行此代码时,它都会显示此错误: “DOMException:关联的轨道处于无效状态”。

我们尝试将循环的计时器从 5000 更改为 800。 它会截取屏幕截图,一段时间内不会给出错误,但会在最后显示错误。

它将状态更改为 track.muted = true。 我希望它保持在 track.muted=false 状态。 所以,我的循环必须连续截图。

有什么方法可以强行让“track.muted=false”吗

javascript java screen-capture image-capture get-display-media
1个回答
0
投票

错误消息“DOMException:关联的轨道处于无效状态”通常在尝试访问停止或结束的媒体流轨道时发生。在您的代码中,每次调用 captureScreenshot() 时您都会停止跟踪,然后尝试再次使用同一轨道进行下一次捕获。这可能会导致轨道在尝试捕获时处于无效状态。

为避免此问题,您可以在每次要截取屏幕截图时创建一个新的 getDisplayMedia() 流,而不是重复使用相同的轨道。这将确保在您尝试捕获帧时轨道始终处于有效状态。

let screenStream;

function captureScreenshot() {
  navigator.mediaDevices.getDisplayMedia({video: true})
    .then(stream => {
      const track = stream.getVideoTracks()[0];
      track.applyConstraints();
      
      const captureLoop = setInterval(() => {
        const imageCapture = new ImageCapture(track);
        imageCapture.grabFrame()
          .then(imageBitmap => {
            const canvas = document.querySelector('#image');
            drawCanvas(canvas, imageBitmap);
          })
          .catch(err => {
            console.error("Error grabbing frame: ", err);
          });
      }, 5000);
      
      // Save the stream and loop interval so we can stop them later
      screenStream = stream;
      screenCaptureLoop = captureLoop;
    })
    .catch(err => {
      console.error("Error getting display media: ", err);
    });
}

function stopCapture() {
  if (screenStream) {
    screenStream.getTracks().forEach(track => track.stop());
    clearInterval(screenCaptureLoop);
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.