7

On my nexus4 (Android 4.4.4) I am trying to switch between 'user' facing camera and 'environment' facing camera.

Accessing either one directly works. Switching between them bij making another call to navigator.getUserMedia() setting new constraints fails. The failure results in a black screen video & MediaStream.ended=true.

Why is MediaStream.ended=true on my second call to getUserMedia?

In my view I dynamically create buttons for the number of video sources. Two in this case. Clicking the buttons will call camera.getUserMedia() and passes in a media source:

    camera.getUserMedia = function(source){
        var constraints = {
            video: true,
            audio: false
        };
        if(source){
            constraints.video = {optional: [{
                sourceId: source.id
            }]};
        }
        navigator.getMedia(
            constraints,
            function(stream) {
                var vendorURL = window.URL || window.webkitURL;
                video.src = vendorURL.createObjectURL(stream);
                video.play();
                streaming = true;
            },
            function(err) {
                ...
            }
        );
    };

enter image description here

Timo
  • 930
  • 2
  • 10
  • 22
  • I am assuming because you can only have one camera at a time and killing the other one kills the original stream...You will need to renegotiate the entire peer connection once adding the new stream that was created with the other camera. – Benjamin Trent Oct 08 '14 at 00:52
  • @BenjaminTrent You are talking about 'renegotiating peer connection'. I do call 'navigator.getUserMedia()' again (renegotiate?) with new constraints containing the other camera id. Isn't that what you mean with 'renegotiating peer connection'? – Timo Oct 08 '14 at 18:17
  • Ignore my previous comment...I am completely wrong :). What is the source ID for both calls? – Benjamin Trent Oct 08 '14 at 18:48

1 Answers1

0

I have solved this problem by storing the stream on the camera object and then before binding the stream to the video element I will call stop on it. Not really sure what is exactly happening though (maybe somebody can add the explanation in the comments).

    camera.getUserMedia = function(source){
        if(camera.stream){
            camera.stream.stop();
        }
        ...
        navigator.getMedia(
            constraints,
            function(stream) {
                camera.stream = stream;
                ...
            },
            function(err) {
                ...
            }
        );
    };
Timo
  • 930
  • 2
  • 10
  • 22
  • Stopping the stream had no effect for me – pthalacker Apr 13 '17 at 21:07
  • 1
    Hey, I know some time passed already but I used this topic when I struggle with the exact same problem. @pthalacker your issue might have been caused due to the fact that some streams are not off yet, and you are already trying to access the next one. this is the bit of code that I used for my solution ` if (window.stream) { window.stream.getTracks().forEach(function (track) { track.stop(); }); }` You need to operate on MediaTracks. – Adrian Grzywaczewski Jul 26 '17 at 13:15