Доступ к внешней USB-камере из веб-просмотра в Android

У меня есть веб-просмотр в моем приложении для Android. Из веб-просмотра я могу получить доступ к камере по умолчанию на телефоне. Следующий код работает нормально.

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());
    }
});

Моя проблема заключается в том, чтобы получить доступ к внешней камере USB из этого веб-просмотра. Выше разрешения открывает камеру по умолчанию в веб-представлении.

Я не смог найти никакой документации, которая даже говорит, что это возможно. Это из-за проблем с безопасностью?

1 ответ

У вас могут быть проблемы с драйвером USB-камеры и выбором камеры, а не с разрешениями.

  1. USB-драйверы для камер

Первый шаг - убедиться, что ваша USB-камера обнаружена и работает на вашем устройстве. Вы не указали, подтвердили ли вы это или нет. Насколько я понимаю, поддержка android.hardware.camera2 для USB-камер все еще довольно слабая. Если ваша камера поддерживается, то, надеюсь, она будет перечислять вместе с остальными камерами. В моем тесте с Android 8.1.0 USB-камера, которую я подключил, не была перечислена с CameraManager, в то время как это было с библиотекой ниже.

Библиотека USB-камеры https://github.com/saki4510t/UVCCamera часто используется для обеспечения более широкой поддержки USB-камер, но из моего ограниченного опыта работы с библиотекой она пишет в TextureView и поэтому, вероятно, не будет хорошо работать с WebRTC в WebView. В очень беглом исследовании я не видел хуков WebView, которые бы поддерживали подключение внешнего источника видео.

  1. Выбор камеры

Вы упомянули, что в вашем тесте всегда использовалась камера по умолчанию, поэтому похоже, что вы не будете активно перечислять и выбирать целевую камеру. Выбор камеры WebRTC может быть выполнен в Javascript, используя navigator.mediaDevices интерфейс. Например,

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));

Поскольку ваши разрешения были достаточны для внутренней камеры, они, насколько я понимаю, должны быть достаточными и для камеры USB.

Обратите внимание, что, как вы, возможно, знаете, в документации есть предупреждение о не ослеплении при предоставлении разрешения Webkit. Когда вы движетесь к производству, не забудьте заменить

request.grant(request.getResources())

возможно, с чем-то вроде этого

if (isRequestOriginOrWhateverApproved(request)) {
    request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE});
}
Другие вопросы по тегам