0

I have tried every possible way to access camera on webview on cordova.

It work on android, but doesn't work on iOS.

Can someone explain how to implement access camera feature via cordova webview on iOS thanks.

Inappbrowser side (Angular)

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices
        .getUserMedia({ video: { facingMode: 'environment' } })
        .then(stream => {
          // this.videoDom.srcObject = stream;
          this.videoDom.srcObject = stream;
          this.videoDom.setAttribute('playsinline', 'true');
          this.videoDom.play();

          this.stream = stream.getTracks();

          requestAnimationFrame(tick);
        })
}

Cordova side

I have install cordova-plugin-camera and add permission in config.xml on ios platform.

Suraneti
  • 81
  • 2
  • 10
  • Yes image picker and camera works for iOS in webviews. You may have to see html or javascript support for iOS, or consult any web frontend developer – Amber K Mar 07 '19 at 10:32
  • @AmberK can you show me some code for explanation. right now on iOS my cordova inappbrowser cannot access camera. – Suraneti Mar 07 '19 at 10:44
  • Can you give us code you used for Android please ? – Enzo B. Mar 07 '19 at 10:58
  • @EnzoBLANCHON I have update camera access function, please guide me. – Suraneti Mar 07 '19 at 11:08
  • Possible duplicate of [Progressive Web App: Error Accessing navigator.mediaDevices.getUserMedia?](https://stackoverflow.com/questions/52978484/progressive-web-app-error-accessing-navigator-mediadevices-getusermedia) – Marcus Sep 14 '19 at 17:35

4 Answers4

2

On iOS11/12 navigator.getMediaDevices is not available for WKWebView and UIWebView. It is only available for Safari. (https://forums.developer.apple.com/thread/88052)

WebRTC is only supported in Safari. No WKWebView, not even SFSafariViewController.

You can try to use this plugin normally should solve your problem: https://github.com/phonegap/phonegap-plugin-media-stream

navigator.mediaDevices.getUserMedia({
    'audio': true,
    'video': {
        facingMode: 'environment'
    }
}).then(function(mediaStream) {
 // Do what you want with
}
Enzo B.
  • 2,341
  • 1
  • 11
  • 33
  • 1
    This plugin will add the functionality to the main Cordova app webview but not the Inappbrowser Webview, so the `navigator.mediaDevices` namespace will not be defined in pages loaded into the inappbrowser. – DaveAlden Mar 07 '19 at 11:52
2

There is a simpler way, just use input type file

This shows the camera for taking a picture

<input type="file" accept="image/*" capture>

This for recording video

<input type="file" accept="video/*" capture>

This will prompt to take a picture or video, choose from the photo library or explore files

<input type="file">

There are a few other combinations. But it probably doesn't work on Android

jcesarmobile
  • 51,328
  • 11
  • 132
  • 176
2

This is a duplicate of: NotReadableError: Could not start source (Please read this link as its related to Cordova and getUserMedia) and potentially Progressive Web App: Error Accessing navigator.mediaDevices.getUserMedia?

There are changes to Safari on iOS 13 & Safari 13: https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes

SFSafariViewController has gained getUserMedia functionality (!!!)

https://bugs.webkit.org/show_bug.cgi?id=183201

However WKWebView does not seem to gain getUserMedia functionality (this might be a bug, watch the webkit link closely):

https://bugs.chromium.org/p/chromium/issues/detail?id=752458 https://bugs.webkit.org/show_bug.cgi?id=185448

iOS 13 and Safari 13 release notes:

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes

Marcus
  • 1,880
  • 20
  • 27
0

I've thought of a hacky way you can make this work on iOS by using the new postMessage API feature of cordova-plugin-inappbrowser which enables you to send messages from pages loaded into the Inappbrowser Webview back to the main Cordova app Webview. This is not present in the latest release on npm (3.0.0), so you'd need to install the master version (3.1.0-dev) directly from Github:

cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser

In the page loaded into the inappbrowser, you can then post messages back to the Cordova app webview:

function openCamera(){
    postMessage({
        action: "camera"
    });
}

function postMessage(message){
    if(!webkit.messageHandlers.cordova_iab) throw "Cordova IAB postMessage API not found!";
    webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify(message));
}

<button onclick="openCamera()">Open camera<button>

On the Cordova app side, you can then listen for that message and respond to it:

var iab = cordova.InAppBrowser.open(myUrl, '_blank', iabOpts);

iab.addEventListener('message', function (e) {
    if(e.data.action === 'camera'){
        openCamera();
    }
});

function openCamera() {
    var animationDelay = 500; // delay to wait for camera window animation
    navigator.camera.getPicture(function(){
        log("successfully opened camera");
        if (device.platform === "iOS"){
            // unhide IAB
            iab.show();
        }
    }, function(cameraError){
        error("error opening camera: "+cameraError);
        if (device.platform === "iOS"){
            iab.show();
        }
    });
    if (device.platform === "iOS"){
        // hide IAB so camera window is in view
        setTimeout(iab.hide, animationDelay);
    }
}

This allows you to directly call cordova-plugin-camera from within the inappbrowser.

However it is hacky because on iOS, by default the camera window will appear below the inappbrowser window in the view hierarchy and hence not be visible. My hack is to hide the inappbrowser window upon opening the camera, which causes the camera window to be at the top of the visible view hierarcy and be displayed. However, upon dismissing the camera window, the Cordova app window will briefly be displayed while the inappbrowser window is being animated to show again.

I created a test case example in my inappbrowser test app repo: https://github.com/dpa99c/cordova-plugin-inappbrowser-test/tree/camera

You can try it like this:

git clone -b camera https://github.com/dpa99c/cordova-plugin-inappbrowser-test
cd cordova-plugin-inappbrowser-test
cordova platform add ios
cordova run ios
DaveAlden
  • 30,083
  • 11
  • 93
  • 155