0

On my website I have a page which connects to the user's webcam using the Javascript method of navigator.getUserMedia and the similar methods for IE and Firefox. This works perfectly on all browsers apart from Safari on my iPhone and iPad and I found that Safari does not support any type of getUserMedia.

Because I know there is not a way round it, I need to just live with the fact it won't work. The only trouble is that for some reason, this Javascript has stopped my Geolocation Javascript further down the page to stop working when it worked perfectly before and on all the other web browsers.

I assume that there is some sort of way to check that if the browser is not Safari then the Javascript for my webcam CAN run and the Geolocation code on Safari can run as it should?

Thanks in advance.


Main PHP Page Code

 "Some html here"

<script src="photo.js"></script>

"Some html here"

      <script>
    var x = document.getElementById("demo");

    function getLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.watchPosition(showPosition);
        } else {
            x.innerHTML = "Geolocation is not supported by this browser.";
        }
    }


    function showPosition(position) {
     /*   x.innerHTML = "Latitude: " + position.coords.latitude + 
        "<br>Longitude: " + position.coords.longitude; */
        var lat = position.coords.latitude;
        var lon = position.coords.longitude;
        document.cookie = "lat" + "=" + lat + ";";
        document.cookie = "lon" + "=" + lon + ";";
    }

    </script>

Photo.js

(function() {
    var video = document.getElementById('video'),
        canvas = document.getElementById('canvas'),
        context = canvas.getContext('2d'),
        photo = document.getElementById('photo'),
        vendorUrl = window.URL || window.webkitURL;

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

    navigator.getMedia({
        video: true,
        audio: false
    }, function(stream) {
        video.src = vendorUrl.createObjectURL(stream);
        video.play();
    }, function(error) {
        // An error occured
        // error.code
    });

    document.getElementById('capture').addEventListener('click', function() {
        context.drawImage(video, 0, 0, 400, 300);
        photo.setAttribute('src', canvas.toDataURL('image/png'));
    });

})();
  • Maybe you should construct your code in a way that it doesn't block further scripts down the page. The simplest way is to move the geolocation script above the camera script. Following is a code that detects Safari only browsers: https://stackoverflow.com/a/23211158/4236374 – Airwavezx Aug 09 '17 at 11:07
  • @Airwavezx When I move the Geolocation script above, it stops working. The code on the other page detects if it IS Safari and I'm looking for a way to run the script if it is NOT Safari –  Aug 09 '17 at 11:14

3 Answers3

0

Use feature detection:

function hasUserMedia() {
  return !!navigator.getUserMedia;
}

function myLogic() {
  if(!hasUserMedia()} {
    return;  // short-circuit your webcam logic
  }
  // configure the webcam
}
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
0

You shouldn't check which browser it is, you should check if the feature is supported or not.

To put it simple:

if (typeof navigator.getUserMedia === "function") {
  runCode();
} else {
  // Don't run code
}

Also, navigator.getUserMedia() is deprecated and replaced with navigator.mediaDevices.getUserMedia() (https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia). Here's a more thorough example:

if (navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === "function") {
  // Run modern code using navigator.mediaDevices.getUserMedia()
  runModernCode();
} else if (typeof navigator.getUserMedia === "function") {
  // Run legacy code using navigator.getUserMedia()
  runLegacyCode();
} else {
  // Don't run code
}
Lennholm
  • 7,205
  • 1
  • 21
  • 30
  • Where the `runCode();` is, how do I say that I want it to run `photo.js`? –  Aug 09 '17 at 11:17
  • @SomeRandomGizza You need to wrap your code in `photo.js` in a global function so that it doesn't run until you choose to invoke it. Alternatively, simply wrap your code in `photo.js` with this if statement. – Lennholm Aug 09 '17 at 11:21
  • This is a bit of photo.js `(function() { //bits inside })();` –  Aug 09 '17 at 11:25
  • @SomeRandomGizza Added another answer where I suggest you add the feature detection logic to your `photo.js` file – Lennholm Aug 09 '17 at 11:35
0

Adding another answer after question was updated to include JS file

You can feature detect in your photo.js file, modify it like this:

(function() {
    var video = document.getElementById('video'),
        canvas = document.getElementById('canvas'),
        context = canvas.getContext('2d'),
        photo = document.getElementById('photo'),
        vendorUrl = window.URL || window.webkitURL;

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

    if (typeof navigator.getMedia === "function") {
        navigator.getMedia({
            video: true,
            audio: false
        }, function(stream) {
            video.src = vendorUrl.createObjectURL(stream);
            video.play();
        }, function(error) {
            // An error occured
            // error.code
        });

        document.getElementById('capture').addEventListener('click', function() {
            context.drawImage(video, 0, 0, 400, 300);
            photo.setAttribute('src', canvas.toDataURL('image/png'));
        });
    }

})();
Lennholm
  • 7,205
  • 1
  • 21
  • 30