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


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)


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


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


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

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


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;

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.


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

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

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.


2

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

localStream.getTracks().forEach(track => track.stop());

0

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


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;
}


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();
  }

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

-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();
});

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.