2018-11-08

Доступ к камере

Дайте доступ приложению JS к вашей камере

Сразу посмотрим на результат, который получим.

Если вы не видите изображения со своей камеры, то вам нужно попробовать:
- Зайти на страницу через HTTPS.
- Посмотреть на мои ошибки.
- Возможно у вас просто нет камеры...)))

Рабочий код (JavaScript)

Код проверен в браузере Chrome 70.0.3538.77 (Официальная сборка), (64 бит)

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

var constraints = {
    video: {
        mandatory: {
            maxWidth: 640,
            maxHeight: 480
        }
    }
};

navigator.getUserMedia(constraints, successCallback, errorCallback);

function successCallback(stream) {
    var video = document.querySelector('video');
    //video.src = window.URL.createObjectURL(stream);   // Устаревший метод из книг по WebRTC.
    video.srcObject = stream;   // Сейчас делают так.
}

function errorCallback(error) {
    console.log("navigator.getUserMedia error: ", error);
}

Разбор кода

Свойство getUserMedia является ссылкой на функцию, которая нужна для получения доступа к камере и/или микрофону. В разных браузерах может иметь дополнительный префикс в названии. Для того, чтобы наш код не был зависим от этих префиксов создадим/перезапишем в объекте Navigator свойство getUserMedia. Объект Navigator сам является свойством navigator глобального объекта Window, который можно не указывать в коде. Это тоже из книг по WebRTC. Сейчас похоже, что не особо актуально, но пока оставлю.

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

Указываем разрешение для выводимого видеопотока.

var constraints = {
    video: {
        mandatory: {
            maxWidth: 640,
            maxHeight: 480
        }
    }
};

Пробуем подключиться к камере. successCallback и errorCallback являются функциями обратного вызова для успешного и не очень вариантов подключения к видеопотоку с камеры.

navigator.getUserMedia(constraints, successCallback, errorCallback);

Функция обратного вызова для обработки успешного захвата потока. В неё первым аргументом передаётся объект MediaStream. Запрашиваем элемент, в котором будет выводится наш видеопоток. Указываем ему источник видеопотока.

РАЗОБРАТЬСЯ. Как система определяет какую именно камеру использовать, если их несколько?

function successCallback(stream) {
    var video = document.querySelector('video');

    //video.src = window.URL.createObjectURL(stream);   // Устаревший метод из книг по WebRTC.
    video.srcObject = stream;   // Сейчас делают так.
}

При использовании URL.createObjectURL в консоль JS вылезает предупреждение:

[Deprecation] URL.createObjectURL with media streams is deprecated and will be removed in M71, around December 2018. Please use HTMLMediaElement.srcObject instead. See https://www.chromestatus.com/features/5618491470118912 for more details.

Функция обратного вызова в случае неудачного подключения.

function errorCallback(error) {
    console.log("navigator.getUserMedia error: ", error);
}

Ошибки

Подключился к локальному сайту для разработки через HTTP:
navigator.getUserMedia error: DOMException: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV).
Обязательно подключение через защищённый протокол HTTPS!

Загрузил на сайт с сертификатом (самоподписанный сертификат). Подключился через HTTPS:
navigator.getUserMedia error: DOMException: Requested device not found
ОС: Mac OS X 10.10.5 Yosemite
Browser: Chrome Версия 69.0.3497.100 (Официальная сборка), (64 бит)
Приложение НЕ может получить доступ к камере FaceTime.
Проблема решилась после перезагрузки мака.

Успешное подключение

Подключился через HTTPS со смартфона с Android. Перед подключением камеры был запрос разрешения на доступ к камере. Видео показывает отлично.
ОС: Android 7.1.1
Browser: Chrome Версия 69.0.3497.100

Проблема на Mac-е решилась простой перезагрузкой.

Node.js

Сервер, который работает работает с WebSocket-ами.

Node.js