Access an external USB camera from the webview in Android
Asked Answered
D

1

6

I have a webview in my Android app. From the webview, I am able to access default camera on the phone. The following code works fine.

webview.setWebChromeClient(new WebChromeClient(){
    // Need to accept permissions to use the camera
    @Override
    public void onPermissionRequest(final PermissionRequest request) {
        L.d("onPermissionRequest");
        request.grant(request.getResources());
    }
});

My issue is to access an external USB camera from this webview. Above permission opens up the default camera in the webview.

I haven't been able to find any documentation which even says this thing is possible. Is it because of some security issue ?

Duumvirate answered 30/8, 2018 at 8:56 Comment(6)
voted to close this (but not my down-vote), because it's too broad and probably does not have an actual relation to a WebView. see the documentation: developer.android.com/reference/android/hardware/usb/…Dallis
I am just asking if its possible or not.Duumvirate
@Duumvirate see my answer it's clear your doubts.Revolution
Or the external camera is picked up by Android and you just need to specify which camera to use. https://mcmap.net/q/721830/-how-can-i-get-a-list-of-video-cameras-attached-in-my-computer-using-javascript html5rocks.com/en/tutorials/getusermedia/introMarjoram
Try to access the camera from a regular view/activity, and, if possible, create an intent for said activity that you can call from the webview.Berkelium
The above commend sounds for me what you are searching for. I think your problem needs to be solved natively (in android) and provided by some kind of intent. Frameworks like React-Native get 100% onto the native system by interpreting JavaScript directly. Maybe you can look into the code base an find some way how to 'copy' the communication layer between native and webview.Rubel
H
2

You may have an issue with the USB camera driver and the camera selection rather than with permissions.

  1. USB Camera Drivers

The first step is to make sure that your USB camera is being detected and is working on your device. You didn't indicate whether you had confirmed this or not. My understanding is that android.hardware.camera2 support for USB cameras is still rather poor. If your camera is supported then hopefully it will enumerate along with the rest of the cameras. In my test with Android 8.1.0 the USB camera I attached was not enumerated with CameraManager, while it was with the library below.

The USB Camera library https://github.com/saki4510t/UVCCamera is frequently used to provide broader support for USB cameras, but from my limited experience with the library it writes to a TextureView and so will probably not play nicely with WebRTC in a WebView. In a very cursory investigation I did not see WebView hooks that would support connecting an external video source.

  1. Camera Selection

You mentioned that your test always used the default camera so it sounds like you might not be actively enumerating and selecting the target camera. WebRTC camera selection can be performed in Javascript using the navigator.mediaDevices interface. For example,

function chooseDevice(videoInDevices) {
    // return selected device
}

// Filter devices so we only consider video sources
function filterForVideoInputs(devices) {
    return devices.filter(d => d.kind === 'videoinput');
}

// Simply pull out deviceId from selected device struct
function getDeviceId(deviceInfo) {
    return deviceInfo.deviceId;
}

// Request video stream from selected deviceId
function requestDevice(deviceId) {
    return navigator.mediaDevices.getUserMedia({
        video: {
            deviceId: {
                exact: deviceId
            }
        }
    });
}

// Connect stream from getUserMedia to HTML5 video element
function startStream(stream) {
    let video = document.querySelector('video');
    video.srcObject = stream;
    video.onloadedmetadata = function () {
        video.play();
    }
}

navigator.mediaDevices.enumerateDevices()
    .then(filterForVideoInputs)
    .then(chooseDevice)
    .then(getDeviceId)
    .then(requestDevice)
    .then(startStream)
    .catch(err => console.log(err));

Since your permissions were sufficient for the internal camera, they should as far as I understand also be sufficient for a USB camera.

Note, as you may know, the documentation has a warning about not blinding granting Webkit permission. When you move toward production remember to replace

request.grant(request.getResources())

perhaps with something more like this

if (isRequestOriginOrWhateverApproved(request)) {
    request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE});
}
Hypothermia answered 12/9, 2018 at 7:31 Comment(3)
This is not the full story! There's actually an issue with Webview + USB (External Camera API) in Android 9+ on some devices. This is what I have inferred and since it is a fairly new problem and an uncommon one, along with it being pretty complicated to solve I haven't come across any solution. I am reviewing Chromium source. On our device we have a CSI camera and a USB Hub for other devices. The same Webview code that works for CSI camera (Internal) is not working for USB Cameras (External). We believe it's a problem with access permissions in the linux or system side.Artina
Here's a link to check how to implement USB camera (external) in Android 9+ groups.google.com/g/android-platform/c/Qx1P0I17uzs At the bottom of the discussion I explain all the information I haveArtina
Is this still possible? Can USB Cameras with UVC protocol be attached and work with WebRTC within a WebView? I don't want to touch the kernel configurationVahe

© 2022 - 2024 — McMap. All rights reserved.