stop the webcam streaming of getUserMedia without page refreshing

46,696

Solution 1

You need to stop the LocalMediaStream object by executing its stop() method. I had similar problems. What you need to do is:

Keep a reference to the LocalMediaStream in the onSuccess callback function of the getUserMedia() execution:

var localStream;

onUserMediaSuccess = function(stream) {
   // attach to a video element
   ...
   // keep a reference
   localStream = stream;
};

Stop the LocalMediaStream where needed:

localStream.stop(); 

More info in my own question (and answer).

Solution 2

Saving a reference to the LocalMediaStream like asgoth suggests is correct, but for me in Chrome 47. localStream.stop(); gave me an error:

Uncaught TypeError: localStream.stop is not a function

I got it to work by calling:

localStream.getVideoTracks()[0].stop();

Solution 3

Addition to asgoth's answer

localStream.stop() is deprecated in Chrome 45, removed in Chrome 47

If u call .stop() from multiple places, you can use the following helper for the stop function to keep the logic at one place.

var localStream;

onUserMediaSuccess = function(stream) {

  // re-add the stop function
  if(!stream.stop && stream.getTracks) {
    stream.stop = function(){         
      this.getTracks().forEach(function (track) {
         track.stop();
      });
    };
  }

  // attach to a video element
  ...
  // keep a reference
  localStream = stream;
};

Solution 4

This seems to be a buggy area in Chrome, and the behavior is constantly changing. This seems to work, only if you are connected via http (not https):

var myStream;
function successCallback( stream ) {
    ...
    myStream = stream; // used to close the stream later
}

function closeStream(){
   myStream.stop(); 
   myStream = null;
}

For some strange reason this doesn't work on SSL (https) (Checked on Chrome for Linux, Ver 27 Dev)

Solution 5

I was having a problem closing the video stream track (front facing camera) and opening an alternate track (rear facing camera) in Chrome 49. I found that MediaStream.stop() has been deprecated since version 45, and has been replaced with MediaStreamTrack.stop(). You can read more from a posting on Google's developer site by Sam Dutton.

Share:
46,696
user2158954
Author by

user2158954

Updated on January 29, 2021

Comments

  • user2158954
    user2158954 over 3 years

    I am trying to close the webcam with javascript function (it has to be closed after receive some Ajax response), but it seems impossible to close without refreshing the page. All the methods for close it like video.src = null, video.pause...etc don't work at all in any browser. The unique way is to close the stream passed as parameter on the success functions, so there is any way to use this object outside the function success to close the webcam?

    I know that this question has been asked before (Stop/Close webcam using getUserMedia and RTCPeerConnection Chrome 25), but my needs are different, so I would need some help to solve this problem

    thanks!

    EDIT: My working code trying to close the webcam:

    navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia ||  navigator.webkitGetUserMedia || navigator.msGetUserMedia;
    if(navigator.getUserMedia){
      var video_constraints = {
        mandatory: {
           maxHeight: 480,
           maxWidth: 640 
        },
        optional: []
      };
      var self = this;
      self.navigator.getUserMedia({
          audio: false,
          video: video_constraints
      }, self.onSuccess, onError);
    }
    else{
      alert('An error has occurred starting the webcam stream, please revise the instructions to fix the problem');
    }
    
    function onSuccess(stream) {
      var video = document.getElementById('webcam');
    
      if(navigator.webkitGetUserMedia || navigator.mozGetUserMedia){
          video.src = window.URL.createObjectURL(stream);
      }
      else if(navigator.msGetUserMedia){
          //future implementation over internet explorer
      }
      else{
          video.src = stream;
      }
      self.localStream = stream;
      video.play();
    }
    function onError() {
      alert('There has been a problem retrieving the streams - did you allow access?');
    }
    
    function closeWebcamConnection(){
      this.localStream.stop();
    }
    

    uff..it's really complicated to post here the code XD

  • user2158954
    user2158954 about 11 years
    Mmmm ok, I have tried to put something similar in my code but I don't know how because your code is completely different. I have also seen your old problem but it's still more difficult to understand for me. Why are you saving the stream object in "self" object if then you use "this" to stop the stream? I will post my code here, thus may be you can tell me how to implement your solution:
  • asgoth
    asgoth about 11 years
    I admit using "self" might by confusing without the whole context. I've adapted my answer a bit. Just keep the reference in a global or scoped variable localStream.
  • user2158954
    user2158954 about 11 years
    sorry but your method doesn't work for me. I think that I saw something similar some time ago but it didn't work too. I have tried both Chrome and Firefox in latest versions.. Furthermore I will need to implement with HTTPS..
  • user2158954
    user2158954 about 11 years
    incredible! I have just tested in Chrome and Firefox and..it works perfectly!! Now that I remember, I tried also something identical one time ago, but it didn't work. Now it would perfect if I could send the canvas image capture as request without using the tedious ajax, but this is another topic jej. Thank you very match! The unique thing is: can I use that with HTTPS?
  • ACEGL
    ACEGL about 11 years
    I only tested it on Chrome 27 dev on Linux. What's your setup ? If you need HTTPS (like i do), It will not do for you anyway. I opened an issue on the WebRTC issue tracker. link
  • user2158954
    user2158954 about 11 years
    oh shit XD! My application has to run over HTTPS.. I use windows 7 64 bits, Enterprise edition. My web app is running in Eclipse Java EE IDE for Web Developers, version Indigo Service Release 2. I have tested on Firefox 19.0.2 and Chrome 26.0.1410.43. It also works in Opera 12.15.. Umm, it wouldn't be a problem for me if I could use request.getParameter functions from a servlet to take the image of canvas in dataURL format. I haven't found the way to do, may be it's is impossible. Did you try something like that?
  • ACEGL
    ACEGL about 11 years
    After additional tests, It should work with HTTPS as long as your implementation is simple and does not involve multiple windows using getUserMedia in sequence.
  • user2158954
    user2158954 about 11 years
    Ok, thanks for your help. Anyway, I have already stopped when I refresh the page via servlet. It was easy to send the captured canvas via request instead of using ajax. In fact it is a better way to manage sessions.
  • Bastian Venthur
    Bastian Venthur over 8 years
  • Daniel Zakrisson
    Daniel Zakrisson over 8 years
    Currently (as of December 2015) this is an important answer. We had this issue in a web app causing the tab in Chrome to crash with the "Aw, snap" message. This solved the issue for us.
  • Qwerty
    Qwerty over 8 years
    This is related to a TokBox / OpenTok error _webRTCStream.stop() is not a function.
  • Dtipson
    Dtipson over 7 years
    Still won't stop with this method. There's even a removeTrack function you can use to remove all the tracks, but my webcam light is still on.
  • peppy
    peppy about 6 years
    I extended the answer a bit more and used the following to successfully close all tracks, including audio: localStream.getTracks().forEach(track => track.stop());