Parar / Fechar a webcam que é aberta pelo navigator.getUserMedia

139

Abri uma webcam usando o seguinte código JavaScript: navigator.getUserMedia

Existe algum código JavaScript para parar ou fechar a webcam? Obrigado a todos.

Shih-En Chou
fonte

Respostas:

199

EDITAR

Como esta resposta foi publicada originalmente, a API do navegador mudou. .stop()não está mais disponível no fluxo que é passado para o retorno de chamada. O desenvolvedor terá que acessar as faixas que compõem o fluxo (áudio ou vídeo) e interromper cada uma delas individualmente.

Mais informações aqui: https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=pt_PT#stop-ended-and-active

Exemplo (no link acima):

stream.getTracks().forEach(function(track) {
  track.stop();
});

O suporte ao navegador pode ser diferente.

Resposta original

navigator.getUserMediafornece um fluxo no retorno de chamada bem-sucedido, você pode chamá .stop()-lo para interromper a gravação (pelo menos no Chrome, parece que o FF não gosta)

andrei
fonte
2
Eu acho que stream.stop()não funciona para o chrome, mediaRecorder.stop()interrompe a gravação, enquanto não interrompe o fluxo fornecido pelo navegador. Você pode olhar para este stackoverflow.com/questions/34715357/…
Muthu
@ Ubuntu, eu acho que depende, para mim stream.stop () está funcionando (no chrome). Porque eu tenho um fluxo webRTC. Então, se você estiver gravando no navegador mediaRecorder.stop () funcionará?
Johan Hoeksma
sim, mas isso levanta outra questão. Esta função para interromper a gravação deve ocorrer após alguns segundos / minutos de gravação. Como você pode controlar isso: pará-lo após um tempo padrão de gravação? Obrigado!
Emanuela Colta
1
Isso interrompe os fluxos, mas o indicador de vídeo no chrome ainda permanece ativo até a recarga. Existe uma maneira de remover isso também?
Cybersupernova
@ Cybersupernova Você encontrou uma solução para isso? Eu acho que a página de atualização pode funcionar
samayo
59

Use qualquer uma destas funções:

// stop both mic and camera
function stopBothVideoAndAudio(stream) {
    stream.getTracks().forEach(function(track) {
        if (track.readyState == 'live') {
            track.stop();
        }
    });
}

// stop only camera
function stopVideoOnly(stream) {
    stream.getTracks().forEach(function(track) {
        if (track.readyState == 'live' && track.kind === 'video') {
            track.stop();
        }
    });
}

// stop only mic
function stopAudioOnly(stream) {
    stream.getTracks().forEach(function(track) {
        if (track.readyState == 'live' && track.kind === 'audio') {
            track.stop();
        }
    });
}

Nota: A resposta foi atualizada em: 06/09/2020

Muaz Khan
fonte
2
Obrigado por isso. O mediaStream.stop está sendo descontinuado.
Dan Brown
@ DanBrown, qual é a sua solução?
Webwoman
Eu desencorajaria fortemente a modificação do protótipo de uma API nativa para restaurar um recurso que foi oficialmente descontinuado e removido do navegador. É irregular e provavelmente causará confusão mais tarde. Quando você precisa parar todas as faixas em um fluxo, por que não fazer stream.getTracks().forEach(track => { track.stop() })? Ou, se você realmente está fazendo isso com frequência suficiente para justificar uma abreviação, sempre pode definir uma função auxiliar como stopAllTracks(stream).
callum
45

Não use stream.stop(), está obsoleto

Descontinuações do MediaStream

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

sol404
fonte
1
Muito obrigado ,, que está funcionando totalmente bem, devido à depreciação É confuso povo aquilo que se está a trabalhar, mas a partir de março-2019 a solução acima está funcionando bem em cromo .. 🙂
PANKAJ NAROLA
10

FF, Chrome e Opera começaram a expor getUserMediavia navigator.mediaDevicescomo padrão agora (pode mudar :)

demonstração online

navigator.mediaDevices.getUserMedia({audio:true,video:true})
    .then(stream => {
        window.localStream = stream;
    })
    .catch( (err) =>{
        console.log(err);
    });
// later you can do below
// stop both video and audio
localStream.getTracks().forEach( (track) => {
track.stop();
});
// stop only audio
localStream.getAudioTracks()[0].stop();
// stop only video
localStream.getVideoTracks()[0].stop();
Sasi Varunan
fonte
9

Iniciando o vídeo da webcam com diferentes navegadores

Para o Opera 12

window.navigator.getUserMedia(param, function(stream) {
                            video.src =window.URL.createObjectURL(stream);
                        }, videoError );

Para o Firefox Nightly 18.0

window.navigator.mozGetUserMedia(param, function(stream) {
                            video.mozSrcObject = stream;
                        }, videoError );

Para Chrome 22

window.navigator.webkitGetUserMedia(param, function(stream) {
                            video.src =window.webkitURL.createObjectURL(stream);
                        },  videoError );

Parando o vídeo da webcam com diferentes navegadores

Para o Opera 12

video.pause();
video.src=null;

Para o Firefox Nightly 18.0

video.pause();
video.mozSrcObject=null;

Para Chrome 22

video.pause();
video.src="";

Com isso, a luz da webcam se apaga toda vez ...

Alain Saurat
fonte
10
Isso só para de mostrar o vídeo na tag <video>, mas não para a câmera.
G. Führ
8

Suponha que tenhamos streaming na tag de vídeo e o ID seja video. <video id="video"></video>Deveríamos ter o seguinte código:

var videoEl = document.getElementById('video');
// now get the steam 
stream = videoEl.srcObject;
// now get all tracks
tracks = stream.getTracks();
// now close each track by having forEach loop
tracks.forEach(function(track) {
   // stopping every track
   track.stop();
});
// assign null to srcObject of video
videoEl.srcObject = null;
Veshraj Joshi
fonte
6

Você pode finalizar o fluxo diretamente usando o objeto de fluxo retornado no manipulador de sucesso para getUserMedia. por exemplo

localMediaStream.stop()

video.src=""ou nullapenas removeria a fonte da tag de vídeo. Não vai liberar o hardware.

Bhavin
fonte
Entendo. Eu vou tentar mais tarde.
amigos estão dizendo sobre shih-en
1
Na verdade não ... No Firefox não funciona. Os docs mencionar que este método não é implementado em todos os navegadores ...
Sâra
A solução acima não funcionou para mim. Isso foi feito.
Scottmas
5

Experimente o método abaixo:

var mediaStream = null;
    navigator.getUserMedia(
        {
            audio: true,
            video: true
        },
        function (stream) {
            mediaStream = stream;
            mediaStream.stop = function () {
                this.getAudioTracks().forEach(function (track) {
                    track.stop();
                });
                this.getVideoTracks().forEach(function (track) { //in case... :)
                    track.stop();
                });
            };
            /*
             * Rest of your code.....
             * */
        });

    /*
    * somewhere insdie your code you call
    * */
    mediaStream.stop();
imal hasaranga perera
fonte
4

Se o .stop()item foi descontinuado, acho que não devemos adicioná-lo novamente como a dose do @MuazKhan. É uma razão pela qual as coisas ficam obsoletas e não devem mais ser usadas. Basta criar uma função auxiliar ... Aqui está uma versão mais es6

function stopStream (stream) {
    for (let track of stream.getTracks()) { 
        track.stop()
    }
}
Sem fim
fonte
1
for (let track of stream.getTracks()) { track.stop() }
guest271314
7
stream.getTracks().forEach(function (track) { track.stop() })em ES5, isso evita longas transforma babel defor of
fregante
3

Como você precisa das faixas para fechar a transmissão e do streambojeto para acessá-las, o código que usei com a ajuda da resposta de Muaz Khan acima é o seguinte:

if (navigator.getUserMedia) {
    navigator.getUserMedia(constraints, function (stream) {
        videoEl.src = stream;
        videoEl.play();
        document.getElementById('close').addEventListener('click', function () {
            stopStream(stream);
        });
    }, errBack);

function stopStream(stream) {
console.log('stop called');
stream.getVideoTracks().forEach(function (track) {
    track.stop();
});

Claro que isso fechará todas as faixas de vídeo ativas. Se você tiver vários, você deve selecionar de acordo.

mcy
fonte
2

Você precisa parar todas as faixas (da webcam, microfone):

localStream.getTracks().forEach(track => track.stop());
TopReseller
fonte
0

O uso de .stop () no fluxo funciona no chrome quando conectado via http. Não funciona ao usar SSL (https).

ACEGL
fonte
0

Verifique isso: https://jsfiddle.net/wazb1jks/3/

navigator.getUserMedia(mediaConstraints, function(stream) {
    window.streamReference = stream;
}, onMediaError);

Pare de gravar

function stopStream() {
    if (!window.streamReference) return;

    window.streamReference.getAudioTracks().forEach(function(track) {
        track.stop();
    });

    window.streamReference.getVideoTracks().forEach(function(track) {
        track.stop();
    });

    window.streamReference = null;
}

Akshay Italiya
fonte
0

O código a seguir funcionou para mim:

public vidOff() {

      let stream = this.video.nativeElement.srcObject;
      let tracks = stream.getTracks();

      tracks.forEach(function (track) {
          track.stop();
      });

      this.video.nativeElement.srcObject = null;
      this.video.nativeElement.stop();
  }
TechDo
fonte
0

Iniciar e parar a câmera da Web, (atualização 2020 React es6)

Iniciar Web Camera

stopWebCamera =()=>

       //Start Web Came
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        //use WebCam
        navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
          this.localStream = stream;
          this.video.srcObject = stream;
          this.video.play();
        });
      }
 }

Pare a reprodução da câmera Web ou do vídeo em geral

stopVideo =()=>
{
        this.video.pause();
        this.video.src = "";
        this.video.srcObject = null;

         // As per new API stop all streams
        if (this.localStream)
          this.localStream.getTracks().forEach(track => track.stop());
}

A função Stop Web Camera funciona mesmo com fluxos de vídeo:

  this.video.src = this.state.videoToTest;
  this.video.play();
Hitesh Sahu
fonte
-1

Ter uma referência ao sucesso do formulário de fluxo

var streamRef;

var handleVideo = function (stream) {
    streamRef = stream;
}

//this will stop video and audio both track
streamRef.getTracks().map(function (val) {
    val.stop();
});
Pankaj Anupam
fonte
1
Esta resposta é essencialmente a mesma que várias outras que já foram dadas.
Dan Dascalescu 12/09
Não por um longo tiro @DanDascalescu. Veja, neste exemplo, ele demonstra claramente sua capacidade de recuperar a função de mapa.
charliebeckwith