Как очистить html элемент видео при удалении дорожки - PullRequest
0 голосов
/ 24 марта 2020

Следующий код выполняет почти то, что я хочу:

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 секунд камера снова останавливается. Однако последнее изображение с камеры остается в качестве стоп-кадра в видео. Как очистить видеоэлемент?

(обратите внимание, что я удаляю только видео-треки, поэтому все еще могут воспроизводиться аудио-треки.)

РЕДАКТИРОВАТЬ: Я испортил аудио часть вопрос. В реальном коде есть звуковые дорожки, которые должны продолжать воспроизводиться, я просто забыл добавить их в пример.

1 Ответ

1 голос
/ 24 марта 2020

Ваш код удаляет все дорожки из MediaStream, не только видео. Чтобы удалить только видео, вы должны сделать

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

Обратите внимание, как getTracks заменяется на getVideoTracks.

Но даже в этом случае последний кадр видео-дорожки вполне может остаться в элементе <video>. Чтобы избавиться от этого, но сохранить звуковые дорожки, вам лучше создать новый MediaStream из звуковых дорожек и установить его как новый srcObject вашего <video>:

Код этого fiddle , поскольку iframe StackSnippet не может вызывать getUserMedia.

(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>

И если вы хотите заменить его на цвет solid (например, черную рамку), то вы можете передайте CanvasCaptureStreamTrack вместе со звуковыми дорожками и нарисуйте этот solid цвет на источнике <canvas>: fiddle

...