[删除轨道时如何清除html视频元素

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

以下代码几乎完成了我想要的工作:

video = document.querySelector('video');
video.srcObject = new MediaStream();

navigator.mediaDevices.getUserMedia({video: true}).then(stream => {
  stream.getTracks().forEach(track => {
    video.srcObject.addTrack(track);
  });
});

setTimeout(() => {
  video.srcObject.getVideoTracks().forEach(track => {
    track.stop()
    video.srcObject.removeTrack(track);
  });
}, 5000);

它启动相机并在屏幕上显示结果。 5秒钟后,相机再次停止。但是,来自摄像机的最后一张图像仍保留为视频中的静止帧。如何清除视频元素?

((请注意,我仅删除视频轨道,因此可能仍在播放音频轨道。)

编辑:我弄混了问题的音频部分。在实际的代码中,应该继续播放are个音轨,我只是忘了将它们添加到示例中。

javascript html5-video getusermedia mediastream
1个回答
1
投票

您的代码正在从MediaStream中删除所有轨道,而不仅仅是视频轨道。要只删除视频,您可以

video.srcObject.getVideoTracks().forEach(track => {
  track.stop()
  video.srcObject.removeTrack(track);
});

注意getTracks如何用getVideoTracks代替。

但是即使那样,视频轨道的最后一帧也可能仍保留在<video>元素中。要摆脱它,但保留音轨,最好从音轨中创建一个新的MediaStream并将其设置为<video>

的新srcObject

由于StackSnippet的iframe不允许调用getUserMedia,因此this fiddle的代码。

(async ()=>{

  const video = document.querySelector('video');
  const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true } );
  video.srcObject = stream;
  video.play();

  btn.onclick = e => {
    stream.getVideoTracks().forEach( vidTrack => vidTrack.stop() );
    const new_stream = new MediaStream(stream.getAudioTracks());
    video.srcObject = new_stream;
    btn.remove();
  }

})();
<button id="btn">keep only audio</button>
<video controls autoplay></video>

并且如果您想用纯色(例如黑框)替换它,则可以将CanvasCaptureStreamTrack与音轨一起传递,并在源<canvas>fiddle上绘制该纯色>

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