最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - MediaDevices.getUserMedia() support for ios - Stack Overflow

programmeradmin3浏览0评论

I was trying to get browser settings details (Camera, Microphone permission) in ReactJS project. Based on that I will show some error message in the UI if it is blocked. I use the following code.

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

This is working in the windows and android browsers but not in the ios browsers. I did not test it in the mac ios. The popup is not showing in ios browsers. How to fix this.

I was trying to get browser settings details (Camera, Microphone permission) in ReactJS project. Based on that I will show some error message in the UI if it is blocked. I use the following code.

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

This is working in the windows and android browsers but not in the ios browsers. I did not test it in the mac ios. The popup is not showing in ios browsers. How to fix this.

Share Improve this question edited Aug 13, 2020 at 13:20 O. Jones 109k17 gold badges131 silver badges183 bronze badges asked Aug 7, 2020 at 13:37 deluxandeluxan 4222 gold badges9 silver badges23 bronze badges 2
  • hat does setCamera(true); do? Did you try to set the srcObj of a video element to the stream you get to verify camera is working or not? – sçuçu Commented Aug 8, 2020 at 20:47
  • Facing the same issue.. Were u able to resolve this? – Feroz Siddiqui Commented Apr 5, 2022 at 15:49
Add a ment  | 

2 Answers 2

Reset to default 3

getUserMedia() works properly on recent version of iOS. Generally 11.1 and beyond are OK.

To troubleshoot this stuff, you need to connect your iOS device to a Mac and use the Safari remote debugging setup. That way you can get a console and javascript debugger.

enumerateDevices() works if you have already used getUserMedia() to ask the user for permission to use the camera and/or mic. Without that permission, the emumerateDevices() results are vague or missing. This is to prevent browser fingerprinting. Because cybercreeps.

In the versions of iOS where getUserMedia actually works, you don't need to look around in various namespaces to find it. navigator.mediaDevices.getUserMedia() is sufficient.

Here's code like what I've used to enumerate media sources on all kinds of different browser platforms incl. iOS, Android, and various desktops. I've used async / await because it's an easy way to handle the Promise returned by getUserMedia(). But you could use the Promise directly if you wish. (Please note I've edited this code to remove my application-specific stuff, but I haven't debugged it.)

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')
}

The new API works like

navigator.mediaDevices.getUserMedia()

I suggest you to add to the support logic statement of yours to supersede all the others which are the old API.

You then need to to use the stream that promise resolve with. You can have a video element in our DOM and set its srcObj property with the stream.

navigator.getMedia(
      { video: true },
      (stream) => {
        video.srcObj = stream;
        setCamera(true);
        console.log("Permission_", "camera ON");
      },
      () => {
        console.log("Permission_", "Camera OFF");
      }
    );
发布评论

评论列表(0)

  1. 暂无评论