Detener / Cerrar la cámara web que se abre por navigator.getUserMedia

139

Abrí una cámara web usando el siguiente código JavaScript: navigator.getUserMedia

¿Hay algún código JavaScript para detener o cerrar la cámara web? Gracias a todos.

Shih-En Chou
fuente

Respuestas:

199

EDITAR

Desde que esta respuesta se publicó originalmente, la API del navegador ha cambiado. .stop()ya no está disponible en la secuencia que se pasa a la devolución de llamada. El desarrollador tendrá que acceder a las pistas que componen la transmisión (audio o video) y detener cada una de ellas individualmente.

Más información aquí: https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=en#stop-ended-and-active

Ejemplo (del enlace de arriba):

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

El soporte del navegador puede diferir.

Respuesta original

navigator.getUserMediale proporciona una transmisión en la devolución de llamada exitosa, puede llamar .stop()a esa transmisión para detener la grabación (al menos en Chrome, parece que a FF no le gusta)

andrei
fuente
2
Creo que stream.stop()no funciona para Chrome, mediaRecorder.stop()detiene la grabación, mientras que no detiene la transmisión proporcionada por el navegador. ¿Puedes mirar este stackoverflow.com/questions/34715357/…
Muthu
@Muntu, creo que depende, para mí stream.stop () está funcionando (en Chrome). Porque tengo una transmisión webRTC. Entonces, si está grabando en el navegador, MediaRecorder.stop () funcionará?
Johan Hoeksma el
Sí, pero esto plantea otro problema. Esta función para detener la grabación debería ocurrir después de permitir unos segundos / minutos de grabación. ¿Cómo puede controlar esto: para detenerlo después de un tiempo predeterminado de grabación? ¡Gracias!
Emanuela Colta
1
Esto detiene las transmisiones, pero el indicador de video en Chrome sigue activo hasta la recarga. ¿Hay alguna manera de eliminar eso también?
Cybersupernova
@Cybersupernova ¿Encontraste una solución para esto? Creo que la actualización de la página podría funcionar
samayo
59

Use cualquiera de estas funciones:

// 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: La respuesta se actualizó el: 06/09/2020

Muaz Khan
fuente
2
Gracias por esto. mediaStream.stop está en desuso.
Dan Brown
@DanBrown ¿Cuál es tu solución?
Webwoman
Me desaconsejaría modificar el prototipo de una API nativa para restaurar una función que ha sido oficialmente desaprobada y eliminada del navegador. Es irregular y puede causar confusión más tarde. Cuando necesita detener todas las pistas en una secuencia, ¿por qué no simplemente hacerlo stream.getTracks().forEach(track => { track.stop() })? O si realmente está haciendo esto con la frecuencia suficiente para justificar una taquigrafía, siempre puede definir una función auxiliar como stopAllTracks(stream).
callum
45

No lo uses stream.stop(), está en desuso

Depreciaciones de MediaStream

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

sol404
fuente
1
Muchas gracias, está funcionando totalmente bien, debido a la depreciación confunde a las personas cuál está funcionando, pero a partir de marzo de 2019, la solución anterior funciona bien en cromo ... 🙂
PANKAJ NAROLA
10

FF, Chrome y Opera ha comenzado exponiendo getUserMediaa través navigator.mediaDevicesde serie ahora (podría cambiar :)

demostración en línea

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
fuente
9

Iniciar Webcam Video con diferentes navegadores

Para la ópera 12

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

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

Detener el video de la cámara web con diferentes navegadores

Para la ópera 12

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

Para Firefox Nightly 18.0

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

Para Chrome 22

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

Con esto, la luz de la cámara web se apaga cada vez ...

Alain Saurat
fuente
10
Esto solo deja de mostrar el video en la etiqueta <video>, pero no detiene la cámara.
G. Führ
8

Supongamos que tenemos streaming en la etiqueta de video y la identificación es video, <video id="video"></video>entonces deberíamos tener el siguiente 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
fuente
6

Puede finalizar la secuencia directamente utilizando el objeto de secuencia devuelto en el controlador de éxito para getUserMedia. p.ej

localMediaStream.stop()

video.src=""o nullsimplemente eliminaría la fuente de la etiqueta de video. No soltará el hardware.

Bhavin
fuente
Veo. Voy a intentarlo más tarde.
Shih-En Chou
1
En realidad no ... En firefox no funciona. Los documentos mencionan que este método no se implementa en todos los navegadores ...
Sdra
La solución anterior no funcionó para mí. Esto lo hizo
Scottmas
5

Pruebe el método a continuación:

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
fuente
4

Si .stop()está en desuso, entonces no creo que debamos volver a agregarlo como dosis @MuazKhan. Es una razón de por qué las cosas se desaprobaron y ya no deberían usarse. Simplemente cree una función auxiliar en su lugar ... Aquí hay una versión más es6

function stopStream (stream) {
    for (let track of stream.getTracks()) { 
        track.stop()
    }
}
Sin fin
fuente
1
for (let track of stream.getTracks()) { track.stop() }
guest271314
77
stream.getTracks().forEach(function (track) { track.stop() })en ES5, esto evita largas transformaciones de babelfor of
fregante
3

Como necesita las pistas para cerrar la transmisión, y necesita el streamobjeto para llegar a las pistas, el código que he usado con la ayuda de la respuesta de Muaz Khan anterior es el siguiente:

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

Por supuesto, esto cerrará todas las pistas de video activas. Si tiene múltiples, debe seleccionar en consecuencia.

mcy
fuente
2

Debe detener todas las pistas (desde la cámara web, el micrófono):

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

El uso de .stop () en la transmisión funciona en Chrome cuando se conecta a través de http. No funciona cuando se usa ssl (https).

ACEGL
fuente
0

Por favor verifique esto: https://jsfiddle.net/wazb1jks/3/

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

Para de grabar

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
fuente
0

El siguiente código funcionó para mí:

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
fuente
0

Iniciar y detener la cámara web, (Actualización 2020 React es6)

Iniciar cámara web

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

Detener la reproducción de cámara web o video en general

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

La función Stop Web Camera funciona incluso con transmisiones de video:

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

Tener una referencia de flujo de forma exitosa

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
fuente
1
Esta respuesta es esencialmente la misma que varias otras que ya se han dado.
Dan Dascalescu
Ni por asomo @DanDascalescu. Ver, en este ejemplo, demuestra claramente su capacidad para recordar la función del mapa.
charliebeckwith