Поддержка MediaDevices.getUserMedia() для ios

Я пытался получить сведения о настройках браузера (камера, разрешение микрофона) в проекте ReactJS. Исходя из этого, я покажу сообщение об ошибке в пользовательском интерфейсе, если оно заблокировано. Я использую следующий код.

useEffect(()=>{
collectUserLogData();
},[]);

const collectUserLogData = () => {
    navigator.getMedia =
      navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia ||
      navigator.msGetUserMedia;

    navigator.getMedia(
      { video: true },
      () => {
        setCamera(true);
        console.log("Permission_", "camera ON");
      },
      () => {
        console.log("Permission_", "Camera OFF");
      }
    );

    navigator.getMedia(
      { audio: true },
      () => {
        setMic(true);
        console.log("Permission_", "Mic ON");
      },
      () => {
        console.log("Permission_", "Mic OFF");
      }
    );

    navigator.geolocation.getCurrentPosition(
      () => {
        setLocation(true);
        console.log("Permission_", "Geo ON");
      },
      () => {
        console.log("Permission_", "Geo OFF");
      }
    );
  };

Это работает в браузерах Windows и Android, но не в браузерах ios. Я не тестировал его в Mac ios. Всплывающее окно не отображается в браузерах iOS. Как это исправить.


person deluxan    schedule 07.08.2020    source источник
comment
шляпа setCamera(true); делать? Вы пытались установить srcObj элемента видео в поток, который вы получаете, чтобы убедиться, что камера работает или нет?   -  person sçuçu    schedule 08.08.2020


Ответы (2)


getUserMedia() правильно работает в последней версии iOS. Обычно 11.1 и выше в порядке.

Чтобы устранить эту проблему, вам нужно подключить устройство iOS к Mac и использовать настройку удаленной отладки Safari. Таким образом, вы можете получить консоль и отладчик javascript.

enumerateDevices() работает, если вы уже использовали getUserMedia(), чтобы запросить у пользователя разрешение на использование камеры и/или микрофона. Без этого разрешения результаты emumerateDevices() будут расплывчатыми или отсутствующими. Это сделано для предотвращения снятия отпечатков пальцев браузера. Потому что киберпреступники.

В версиях iOS, где getUserMedia действительно работает, вам не нужно просматривать различные пространства имен, чтобы найти его. navigator.mediaDevices.getUserMedia() достаточно.

Вот код, подобный тому, который я использовал для перечисления источников мультимедиа на всех видах различных платформ браузера, включая. iOS, Android и различные настольные компьютеры. Я использовал async / await, потому что это простой способ обработки промиса, возвращаемого функцией getUserMedia(). Но вы можете использовать обещание напрямую, если хотите. (Обратите внимание, что я отредактировал этот код, чтобы удалить вещи, специфичные для моего приложения, но я не отлаживал его.)

async function enumerateSources() {
    if(      navigator 
          && navigator.mediaDevices 
          && typeof navigator.mediaDevices.enumerateDevices === 'function' ) {
      try {
        /* open a generic stream to get permission to see devices; 
         * Mobile Safari insists */
        const stream = await navigator.mediaDevices.getUserMedia(
                { video: true, audio: true} )
        let devices = await navigator.mediaDevices.enumerateDevices()
        const cameras = devices.filter( device => {
          return device.kind === 'videoinput'
        })
        if (cameras.length >= 1) console.log ('cameras avail')
        const mics = devices.filter( device => {
          return device.kind === 'audioinput'
        })
        if (mics.length >= 1) console.log ('mics avail')

       /* release stream */
        const tracks = stream.getTracks()
        if( tracks ) {
          for( let t = 0; t < tracks.length; t++ ) tracks[t].stop()
        }
        return ({cameras, mics})
      } catch(error) {
        /* user refused permission, or media busy, or some other problem */
        console.error(error.name, error.message)
        return {cameras:[], mics:[]})
      }
    }
    else throw ('media device stuff not available in this browser')
}

person O. Jones    schedule 13.08.2020

Новый API работает как

navigator.mediaDevices.getUserMedia()

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

Затем вам нужно использовать поток, с которым обещание разрешается. Вы можете иметь элемент video в нашей DOM и установить его свойство srcObj с потоком.

navigator.getMedia(
      { video: true },
      (stream) => {
        video.srcObj = stream;
        setCamera(true);
        console.log("Permission_", "camera ON");
      },
      () => {
        console.log("Permission_", "Camera OFF");
      }
    );
person sçuçu    schedule 07.08.2020
comment
Если я использую этот новый синтаксис, всплывающее окно отлично работает в настольных браузерах, и даже после предоставления разрешений камера не работает. - person deluxan; 08.08.2020
comment
Есть ли возможность получить информацию о браузере (камера, микрофон) без переопределения всплывающего окна по умолчанию. Потому что до использования этого класса навигатора он работал нормально. Теперь он переопределяет всплывающее окно по умолчанию и вызывает эту проблему в браузерах ios. - person deluxan; 10.08.2020
comment
Что вы имеете в виду под данными браузера? Устройства? navigator.mediaDevices.enumerateDevices() и navigator.mediaDevices.getSupportedConstraints() - person sçuçu; 10.08.2020
comment
Мне нужно знать, заблокированы ли камера или микрофон или нет - person deluxan; 11.08.2020