Zatrzymaj / zamknij kamerę internetową, którą otwiera navigator.getUserMedia


139

Otworzyłem kamerę internetową, używając następującego kodu JavaScript: navigator.getUserMedia

Czy istnieje kod JavaScript, aby zatrzymać lub zamknąć kamerę internetową? Dziękuję wszystkim.

Odpowiedzi:


199

EDYTOWAĆ

Od czasu opublikowania tej odpowiedzi interfejs API przeglądarki uległ zmianie. .stop()nie jest już dostępny w strumieniu, który jest przekazywany do wywołania zwrotnego. Deweloper będzie musiał uzyskać dostęp do ścieżek tworzących strumień (audio lub wideo) i zatrzymać każdą z nich indywidualnie.

Więcej informacji tutaj: https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=en#stop-ended-and-active

Przykład (z linku powyżej):

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

Obsługa przeglądarek może się różnić.

Oryginalna odpowiedź

navigator.getUserMediazapewnia strumień w wywołaniu zwrotnym sukcesu, możesz wywołać .stop()ten strumień, aby zatrzymać nagrywanie (przynajmniej w Chrome wydaje się, że FF tego nie lubi)


2
Myślę, że stream.stop()nie działa na chrome, mediaRecorder.stop()zatrzymuje nagrywanie, podczas gdy nie zatrzymuje strumienia dostarczanego przez przeglądarkę. Czy możesz spojrzeć na ten stackoverflow.com/questions/34715357/ ...
Muthu

@Muntu, myślę, że to zależy, dla mnie stream.stop () działa (w chrome). Ponieważ mam strumień webRTC. Więc jeśli nagrywasz w przeglądarce, mediaRecorder.stop () będzie działać?
Johan Hoeksma,

tak, ale to rodzi inny problem. Ta funkcja zatrzymania nagrywania powinna nastąpić po odczekaniu kilku sekund / minut nagrywania. Jak możesz to kontrolować: zatrzymać to po domyślnym czasie nagrywania? Dziękuję Ci!
Emanuela Colta

1
Spowoduje to zatrzymanie strumieni, ale wskaźnik wideo w chrome pozostaje aktywny do ponownego załadowania. Czy jest sposób, aby to również usunąć?
Cybersupernova

@Cybersupernova Czy znalazłeś na to rozwiązanie? Myślę, że odświeżenie strony może zadziałać
samayo

59

Użyj dowolnej z tych funkcji:

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

Uwaga: odpowiedź została zaktualizowana w dniu: 09.06.2020


2
Dzięki za to. MediaStream.stop jest przestarzały.
Dan Brown

@DanBrown jakie jest Twoje rozwiązanie?
Webwoman

Zdecydowanie odradzam modyfikowanie prototypu natywnego interfejsu API w celu przywrócenia funkcji, która została oficjalnie wycofana i usunięta z przeglądarki. Jest nieregularny i prawdopodobnie spowoduje później zamieszanie. Kiedy musisz zatrzymać wszystkie ścieżki w strumieniu, dlaczego po prostu tego nie zrobić stream.getTracks().forEach(track => { track.stop() })? Lub jeśli naprawdę robisz to wystarczająco często, aby uzasadnić skrót, zawsze możesz zdefiniować funkcję pomocniczą, taką jak stopAllTracks(stream).
Callum

45

Nie używaj stream.stop(), jest przestarzały

Wycofania MediaStream

Posługiwać się stream.getTracks().forEach(track => track.stop())


1
Dziękuję bardzo, działa całkowicie dobrze, ze względu na amortyzację wprawia ludzi w zakłopotanie to, który z nich działa, ale od marca 2019 powyższe rozwiązanie działa dobrze w chromie .. 🙂
PANKAJ NAROLA

10

FF, Chrome i Opera rozpoczął wystawiając getUserMediapoprzez navigator.mediaDevicesstandardowo teraz (może się zmienić :)

demo 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

Uruchamianie wideo z kamery internetowej w różnych przeglądarkach

W przypadku Opery 12

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

W przypadku przeglądarki Firefox Nightly 18.0

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

Chrome 22

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

Zatrzymywanie wideo z kamery internetowej w różnych przeglądarkach

W przypadku Opery 12

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

W przypadku przeglądarki Firefox Nightly 18.0

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

Chrome 22

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

Dzięki temu lampka kamery internetowej gaśnie za każdym razem ...


10
Spowoduje to tylko zatrzymanie wyświetlania wideo w tagu <video>, ale nie zatrzyma kamery.
G. Führ

8

Załóżmy, że mamy przesyłanie strumieniowe w tagu wideo, a id to wideo - <video id="video"></video>wtedy powinniśmy mieć następujący kod -

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

Strumień można zakończyć bezpośrednio za pomocą obiektu stream zwróconego w procedurze obsługi sukcesu do getUserMedia. na przykład

localMediaStream.stop()

video.src=""lub nullpo prostu usunie źródło z tagu wideo. Nie zwolni sprzętu.


Widzę. Spróbuję później.
Shih-En Chou

1
Nie bardzo ... W przeglądarce Firefox nie działa. Dokumenty wspominają, że ta metoda nie jest zaimplementowana we wszystkich przeglądarkach ...
Sdra

Powyższe rozwiązanie u mnie nie działa. Zrobiło to.
Scottmas,

5

Wypróbuj poniższą metodę:

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

Jeśli .stop()jest przestarzały, nie sądzę, abyśmy ponownie dodawali go, jak dawka @MuazKhan. To powód, dla którego rzeczy stają się przestarzałe i nie powinny być już używane. Zamiast tego po prostu utwórz funkcję pomocniczą ... Oto bardziej wersja es6

function stopStream (stream) {
    for (let track of stream.getTracks()) { 
        track.stop()
    }
}

1
for (let track of stream.getTracks()) { track.stop() }
gość271314

7
stream.getTracks().forEach(function (track) { track.stop() })w ES5 pozwala to uniknąć długich transformacji babelfor of
fregante

3

Ponieważ potrzebujesz ścieżek, aby zamknąć strumieniowanie, i potrzebujesz streamboject, aby dostać się do ścieżek, kod, którego użyłem z pomocą odpowiedzi Muaz Khana powyżej, jest następujący:

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

Oczywiście spowoduje to zamknięcie wszystkich aktywnych ścieżek wideo. Jeśli masz wiele, wybierz odpowiednio.


2

Musisz zatrzymać wszystkie ścieżki (z kamery internetowej, mikrofonu):

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

0

Użycie .stop () w strumieniu działa w przeglądarce Chrome po połączeniu przez http. Nie działa przy korzystaniu z protokołu SSL (https).


0

Sprawdź to: https://jsfiddle.net/wazb1jks/3/

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

Zatrzymaj nagrywanie

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

Poniższy kod zadziałał dla mnie:

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

Uruchom i zatrzymaj kamerę internetową (aktualizacja 2020 React es6)

Uruchom kamerę internetową

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

Ogólne zatrzymanie odtwarzania kamery internetowej lub wideo

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

Funkcja zatrzymania kamery internetowej działa nawet w przypadku strumieni wideo:

  this.video.src = this.state.videoToTest;
  this.video.play();

-1

Miej odniesienie do strumienia SuccessHandle

var streamRef;

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

//this will stop video and audio both track
streamRef.getTracks().map(function (val) {
    val.stop();
});

1
Ta odpowiedź jest zasadniczo taka sama, jak kilka innych, które zostały już podane.
Dan Dascalescu

Nie przez długi czas @DanDascalescu. Widzicie, w tym przykładzie wyraźnie demonstruje on swoją zdolność przywoływania funkcji mapy.
charliebeckwith
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.