Stop/Close webcam stream which is opened by navigator.mediaDevices.getUserMedia

186,427

Solution 1

EDIT

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.

Original answer

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

Solution 2

Use any of these functions:

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

Solution 3

Don't use stream.stop(), it's deprecated

MediaStream Deprecations

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

Solution 4

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

Solution 5

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;
Share:
186,427

Related videos on Youtube

Shih-En Chou
Author by

Shih-En Chou

Have you tried Facebook Wall Instant Search? Enjoy search =) https://apps.facebook.com/358181217571865/ Demo: http://www.youtube.com/watch?v=XZQFBbdOLRQ

Updated on October 16, 2020

Comments

  • Shih-En Chou
    Shih-En Chou over 3 years

    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? Thanks everyone.

  • Shih-En Chou
    Shih-En Chou about 11 years
    I see. I will try it later.
  • Sdra
    Sdra about 10 years
    Not really... On firefox does not work. The docs mention that this method is not implemented in all browsers...
  • Scottmas
    Scottmas over 9 years
    The above solution did not work for me. This did it.
  • Dan Brown
    Dan Brown over 8 years
    Thanks for this. mediaStream.stop is being deprecated.
  • G. Führ
    G. Führ over 8 years
    This only stops showing the video in the <video> tag, but doesn't stop the camera.
  • Muthu
    Muthu over 8 years
    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/…
  • guest271314
    guest271314 over 7 years
    for (let track of stream.getTracks()) { track.stop() }
  • fregante
    fregante over 7 years
    stream.getTracks().forEach(function (track) { track.stop() }) in ES5, this avoids lengthy babel transforms of for of
  • Dan Dascalescu
    Dan Dascalescu over 7 years
    This answer is essentially the same as several others that have been already given.
  • Johan Hoeksma
    Johan Hoeksma over 6 years
    @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?
  • Emanuela Colta
    Emanuela Colta almost 6 years
    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!
  • Webwoman
    Webwoman about 5 years
    @DanBrown what is your solution?
  • PANKAJ NAROLA
    PANKAJ NAROLA about 5 years
    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.. 🙂
  • Cybersupernova
    Cybersupernova over 4 years
    This stops the streams but the video indicator on chrome still remains active untill reload. Is there a way to remove that too?
  • samayo
    samayo over 4 years
    @Cybersupernova Did you find a solution for this? I think page refresh might work
  • Cybersupernova
    Cybersupernova over 4 years
    @samayo no i didn't found any and i cannot reload the page
  • charliebeckwith
    charliebeckwith over 4 years
    Not by a long shot @DanDascalescu. See, in this example he clearly demonstrates his ability to recall the map function.
  • callum
    callum almost 4 years
    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).
  • Shawn Eary
    Shawn Eary over 3 years
    @Muthu - The latest example on this answer seems to individually call track.stop() on all available tracks. When I use andrei's new code, the recording seems to "stop" and the stream gets fed all zeros but the success handler that was registered when I called getUserMedia won't stop running. Is that what you mean?
  • Neeraj Jain
    Neeraj Jain over 3 years
    How to resume the track ?
  • amiregelz
    amiregelz over 3 years
    Is it possible to stop and then re-start a screen capture share without making the user choose the window again?
  • sol404
    sol404 almost 3 years
  • codeboi
    codeboi over 2 years
    @NeerajJain once you close a mediaStreamTrack it can not exit the ended state