javascript - Prevent iOS from Switching Between Back Camera Lenses in getUserMedia (SafariWebView, iOS 18) - Stack Overflow

I’m developing a hybrid app (WebViewTurbo Native) that uses getUserMedia to access the back camera f

I’m developing a hybrid app (WebView / Turbo Native) that uses getUserMedia to access the back camera for a PPG/heart rate measurement feature (the user places their finger on the camera).

Problem: Even when I specify constraints like:

{
  video: {
    deviceId: '...',
    facingMode: { exact: 'environment' },
    advanced: [{ zoom: 1.0 }]
  },
  audio: false
}

On iPhone 15 (iOS 18), iOS unexpectedly switches between the wide, ultra-wide, and telephoto lenses during the measurement.

This breaks the heart rate detection, and it forces the user to move their finger in the middle of the measurement.

Question: Is there any way, via getUserMedia/WebRTC, to force iOS to use only the wide-angle lens and prevent automatic lens switching?

I know that with AVFoundation (Swift) you can pick .builtInWideAngleCamera, but I’m hoping to avoid building a custom native layer and would prefer to stick with WebView/JavaScript if possible to save time and complexity.

Any suggestions, workarounds, or updates from Apple would be greatly appreciated!

Thanks a lot!

I’m developing a hybrid app (WebView / Turbo Native) that uses getUserMedia to access the back camera for a PPG/heart rate measurement feature (the user places their finger on the camera).

Problem: Even when I specify constraints like:

{
  video: {
    deviceId: '...',
    facingMode: { exact: 'environment' },
    advanced: [{ zoom: 1.0 }]
  },
  audio: false
}

On iPhone 15 (iOS 18), iOS unexpectedly switches between the wide, ultra-wide, and telephoto lenses during the measurement.

This breaks the heart rate detection, and it forces the user to move their finger in the middle of the measurement.

Question: Is there any way, via getUserMedia/WebRTC, to force iOS to use only the wide-angle lens and prevent automatic lens switching?

I know that with AVFoundation (Swift) you can pick .builtInWideAngleCamera, but I’m hoping to avoid building a custom native layer and would prefer to stick with WebView/JavaScript if possible to save time and complexity.

Any suggestions, workarounds, or updates from Apple would be greatly appreciated!

Thanks a lot!

Share Improve this question asked Mar 12 at 16:22 galgal 1514 gold badges22 silver badges40 bronze badges 1
  • Possibly helpful – James Commented Mar 12 at 18:04
Add a comment  | 

2 Answers 2

Reset to default 1

iPhones with multiple rear cameras (like 11peo) automatically switch between lenses based on lighting conditions and focus distance, even when facingMode: { exact: "environment" } is set. Unfortunately, getUserMedia in WebView doesn’t provide full control over which specific rear camera (wide, ultra-wide, or telephoto) is used.

Instead of you to rely on facingMode, you can try listing available cameras and selecting the one that matches the wide-angle lens.

You can achieve that by:

async function getWideAngleCamera() {
  const devices = await navigator.mediaDevices.enumerateDevices();
  const backCameras = devices.filter(device => device.kind === "videoinput" && device.label.toLowerCase().includes("back"));
  
  //pick the camera that has 'wide' in the label
  const wideCamera = backCameras.find(device => device.label.toLowerCase().includes("wide")) || backCameras[0];

  if (!wideCamera) {
    console.error("No suitable wide-angle camera found.");
    return null;
  }

  return wideCamera.deviceId;
}

async function startCamera() {
  const deviceId = await getWideAngleCamera();

  if (!deviceId) return;

  const stream = await navigator.mediaDevices.getUserMedia({
    video: {
      deviceId: { exact: deviceId },
      advanced: [{ zoom: 1.0 }]
    }
  });

  document.querySelector("video").srcObject = stream;
}

startCamera();

I recommend to use the ultra-wide angle lens for your use case. because the finger is very close from lenses so the camera will switch to Macro mode automatically

It is fairly easy, if you set the zoom to 0.5 it will keep using the ultra-wide angle lens no matter what.

Alternatively you can use exact with device ID

{
  video: {
    deviceId: { exact: '...'},
    facingMode: { exact: 'environment' },
    advanced: [{ zoom: 1.0 }]
  },
  audio: false
}

to require the specific camera, you would use:

getUserMedia({
 video: {
  deviceId: {
    exact: myExactCameraOrBustDeviceId,
  },
 },
});

See the documentation

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744740548a4591001.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信