8

Im testing some media features with ionic and im stuck while trying to set the camera output into a video tag using getUserMedia using this code:

navigator.getUserMedia = navigator.getUserMedia ||
                     navigator.webkitGetUserMedia ||
                     navigator.mozGetUserMedia;

if (navigator.getUserMedia) {
   navigator.getUserMedia({ audio: false, video: { width: 500, height: 500 } },
      function(stream) {
         console.log("Im streaming!!", stream);
         var video = document.querySelector('video');
         console.log("video element", video);
         video.src = window.URL.createObjectURL(stream);
         video.onloadedmetadata = function(e) {
            console.log("stream start");
            video.play();
         };
      },
      function(err) {
         console.log("The following error occurred: " + err.name);
      }
   );
} else {
   console.log("getUserMedia not supported");
}

this is the html:

    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
      </ion-header-bar>
      <ion-content>
        <video  id="video" autoplay="autoplay" width="500" height="500"></video>
      </ion-content>
    </ion-pane>

i can actually get only a black screen. Is my approach right or im missing something?

Vanojx1
  • 5,574
  • 2
  • 23
  • 37

2 Answers2

4

I managed to reproduce the problem and solved it by using the constraints options. Using constraints you can set the sourceId that allows you to select between front or rear camera. Im sure that your device has no front camera and i guess this is why you are getting the black screen.

First we create our constraint options:

var constraints = {};

MediaStreamTrack.getSources (function(sources) {
    sources.forEach(function(info) {
        if (info.facing == "environment") {
            constraints = {
              video: {
                optional: [{sourceId: info.id}]
              }
            };
        }
    })
})

Then we call the navigator.getUserMedia:

navigator.getUserMedia = navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia;

if (navigator.getUserMedia) {
   navigator.getUserMedia(constraints,
      function(stream) {
         console.log("Im streaming!!", stream);
         var video = document.querySelector('video');
         console.log("video element", video);
         video.src = window.URL.createObjectURL(stream);
         video.onloadedmetadata = function(e) {
            console.log("stream start");
            video.play();
         };
      },
      function(err) {
         console.log("The following error occurred: " + err.name);
      }
   );
} else {
   console.log("getUserMedia not supported");
}

Warning: MediaStreamTrack.getSources returns a promise so that means that if you try to run your navigator.getUserMedia code at once, it will fail. You will have to wrap it in a function and run it as a callback.

More info about camera and audio source selection can be found here: https://developers.google.com/web/updates/2015/10/media-devices

also a nice example here: https://simpl.info/getusermedia/sources/

Sarantis Tofas
  • 5,097
  • 1
  • 23
  • 36
  • Thanks, I will try your solution!! – Vanojx1 Sep 22 '16 at 18:39
  • @Vanojx1 yes sure mate tell me when u do – Sarantis Tofas Sep 23 '16 at 17:30
  • my device ve front camera, i ve tested your solution using ionic and it wont work ( still black screen )... but it works ( only with front camera ) using browser on simpl.info website. I think is something related to ionic – Vanojx1 Sep 26 '16 at 09:57
  • @Vanojx1 are you getting console errors? I am sure that the `constraints` options will solve your problem. Have a read on the articles i posted as well, they explain in details how things work – Sarantis Tofas Sep 26 '16 at 10:04
  • im having this in console "file:///android_asset/www/null" as a GET error – Vanojx1 Sep 26 '16 at 10:29
4

The final solution to this problem is that getUserMedia require a runtime permission check to work. To achieve that i used this plugin. Then this worked like a charm:

cordova.plugins.diagnostic.requestRuntimePermission(function(status){
    if(cordova.plugins.diagnostic.runtimePermissionStatus.GRANTED){
      navigator.getUserMedia({video: true, audio: false}, function(localMediaStream) {
        var video = document.querySelector('video');
        video.src = window.URL.createObjectURL(localMediaStream);

        video.onloadedmetadata = function(e) {
          console.log('Stream is on!!', e);
        };
      }, errorCallback);
    }

});
Vanojx1
  • 5,574
  • 2
  • 23
  • 37