相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I opened a webcam by using the following JavaScript code:

const stream = await navigator.mediaDevices.getUserMedia({ /* ... */ });

Is there any JavaScript code to stop or close the webcam?

Since this answer has been originally posted the browser API has changed. .stop() is no longer available on the stream that gets passed to the callback. The developer will have to access the tracks that make up the stream (audio or video) and stop each of them individually.

More info here: https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=en#stop-ended-and-active

Example (from the link above):

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

Browser support may differ.

Previously, navigator.getUserMedia provided you with a stream in the success callback, you could call .stop() on that stream to stop the recording (at least in Chrome, seems FF doesn't like it)

I think stream.stop() doen't work for chrome, mediaRecorder.stop() stops the recording , whereas it doesn't stop the stream provided by browser. Can you look on to this stackoverflow.com/questions/34715357/… – Muthu Jan 11, 2016 at 7:03 @Muntu, I think it depends, for me stream.stop() is working (in chrome). Because I have a webRTC stream. So if you are recording in browser mediaRecorder.stop() will work? – Johan Hoeksma Jan 11, 2018 at 19:38 yes, but this raises another issue. This function to stop recording should occur after allowing a few seconds/minutes of recording. How can you control this: to stop it after a default time of recording? Thank you! – Emanuela Colta Jul 17, 2018 at 15:53 This stops the streams but the video indicator on chrome still remains active untill reload. Is there a way to remove that too? – Cybersupernova Sep 17, 2019 at 13:49

Use any of these functions:

// stop both mic and camera
function stopBothVideoAndAudio(stream) {
    stream.getTracks().forEach((track) => {
        if (track.readyState == 'live') {
            track.stop();
// stop only camera
function stopVideoOnly(stream) {
    stream.getTracks().forEach((track) => {
        if (track.readyState == 'live' && track.kind === 'video') {
            track.stop();
// stop only mic
function stopAudioOnly(stream) {
    stream.getTracks().forEach((track) => {
        if (track.readyState == 'live' && track.kind === 'audio') {
            track.stop();
                I would strongly discourage modifying the prototype of a native API to restore a feature that has been officially deprecated and removed from the browser. It's irregular and likely to cause confusion later. When you need to stop all the tracks in a stream, why not just do stream.getTracks().forEach(track => { track.stop() })? Or if you're really doing this often enough to justify a shorthand, you can always define a helper function like stopAllTracks(stream).
– callum
                Jun 9, 2020 at 11:01
                Thank you so much,, it's working totally fine, due to the depreciation it's confusing people that which one is working but as of march-2019 the above solution is working fine in chrome.. 🙂
– PANKAJ NAROLA
                Mar 9, 2019 at 14:09

FF, Chrome and Opera has started exposing getUserMedia via navigator.mediaDevices as standard now (Might change :)

online demo

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

Suppose we have streaming in video tag and id is video - <video id="video"></video> then we should have following code -

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;
window.navigator.getUserMedia(param, function(stream) {
                            video.src =window.URL.createObjectURL(stream);
                        }, videoError );

For Firefox Nightly 18.0

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

For Chrome 22

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

Stopping Webcam Video with different browsers

For Opera 12

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

For Firefox Nightly 18.0

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

For Chrome 22

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

With this the Webcam light go down everytime...

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

You can end the stream directly using the stream object returned in the success handler to getUserMedia. e.g.

localMediaStream.stop()

video.src="" or null would just remove the source from video tag. It wont release the hardware.

Not really... On firefox does not work. The docs mention that this method is not implemented in all browsers... – Sdra Mar 28, 2014 at 16:01

Since you need the tracks to close the streaming, and you need the stream boject to get to the tracks, the code I have used with the help of the Muaz Khan's answer above is as follows:

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

Of course this will close all the active video tracks. If you have multiple, you should select accordingly.

If the .stop() is deprecated then I don't think we should re-add it like @MuazKhan dose. It's a reason as to why things get deprecated and should not be used anymore. Just create a helper function instead... Here is a more es6 version

function stopStream (stream) {
    for (let track of stream.getTracks()) { 
        track.stop()
                stream.getTracks().forEach(function (track) { track.stop() }) in ES5, this avoids lengthy babel transforms of for of
– fregante
                Sep 1, 2016 at 8:29
       //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();

Stop Web Camera or Video playback in 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());

Stop Web Camera function works even with video streams:

  this.video.src = this.state.videoToTest;
  this.video.play();
                Is it possible to stop and then re-start a screen capture share without making the user choose the window again?
– amiregelz
                Dec 25, 2020 at 19:04
navigator.getUserMedia(mediaConstraints, function(stream) {
    window.streamReference = stream;
}, onMediaError);
if (!window.streamReference) return; window.streamReference.getAudioTracks().forEach(function(track) { track.stop(); window.streamReference.getVideoTracks().forEach(function(track) { track.stop(); window.streamReference = null;

I tried everything, but it worked only intermittently. It was not until I close the component in React that the camera light disappears. I would suggest create your component where you hide/show the component, in order to remove the camera completely.

const stream = document.querySelector("video").srcObject; console.log("videoElement", stream, stream.active); stream?.getVideoTracks()?.forEach((track) => { console.log("track 1", track); track.stop(); stream?.removeTrack(track); track = null; console.log("track 2", track); stream?.getTracks()?.forEach((track) => { console.log("track 3", track); track.stop(); stream?.removeTrack(track); track = null; console.log("track 4", track); stream?.getAudioTracks()?.forEach((track) => { console.log("track 5", track); track.stop(); stream?.removeTrack(track); track = null; console.log("track 6", track); console.log("videoElement 2", stream, stream.active); stream = null; const videoElem = document.querySelector("video"); if (videoElem) { console.log("element exists", videoElem); videoElem.pause(); videoElem.removeAttribute("src"); videoElem.src = ""; videoElem.remove(); console.log("element exists 2", videoElem);

Because the above didn't close the camera completely, I would suggest you would have your component

const [isCameraOn, setCameraOn] = useState(false)

set your video component like this

{isCameraOn && (<YourVideoComponent/>)}
                I tried this for an audio component, but even if the component is not rendered, the microphone is still open and listening. The only way to stop is to refresh the page. I'm sure this is possible to stop, because tools like Google Meet does so without any refresh. Maybe it's just a bug in the implementation of navigator.mediaDevices?
– ADTC
                Jul 31 at 16:13
                same, I also had to do a refresh. the only thing I could think of is that this is happening because of different libraries being used in my code, and there's a conflict somewhere in code.
– guest
                Aug 1 at 0:49
                Hey, I couldn't update you yesterday, but I figured out the solution. It's because we didn't close the correct resource properly. I think you already know this, since you say "It was not until I close the component in React that the camera light disappears.". You just have to make sure the correct stream is closed when the component unmounts (or in response to something else like user clicking "turn off" or "mute"). Initially it didn't work because I was creating a new stream and closing that instead of the original stream. Now I put the original stream in a Ref (useRef hook) and close that.
– ADTC
                Aug 1 at 6:17
//this will stop video and audio both track
streamRef.getTracks().map(function (val) {
    val.stop();
                Not by a long shot @DanDascalescu. See, in this example he clearly demonstrates his ability to recall the map function.
– charliebeckwith
                Oct 21, 2019 at 16:56
 
推荐文章