killapp/Assets/Plugins/iOS/CameraFocusHelper.mm
“虞渠成” 5c21080203 fix(ios): 修复iOS摄像头对焦异常,优化多摄选择逻辑
1. 重构iOS原生对焦插件,支持按摄像头名称精准匹配设备
2. 优化摄像头选择逻辑,优先选用后置主摄并排除长焦/超广角镜头
3. 修复连续自动对焦失效问题,增加延迟初始化和定期校验
4. 添加调试日志便于排查摄像头相关问题
2026-07-23 14:56:53 +08:00

104 lines
4.2 KiB
Plaintext

#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
/// 通过名称查找摄像头设备
static AVCaptureDevice *FindCameraByName(const char *cameraName)
{
if (cameraName == NULL || strlen(cameraName) == 0) {
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
NSString *name = [NSString stringWithUTF8String:cameraName];
// iOS 10+ DiscoverySession
if (@available(iOS 10.0, *)) {
AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera,
AVCaptureDeviceTypeBuiltInTelephotoCamera,
AVCaptureDeviceTypeBuiltInUltraWideCamera]
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified];
for (AVCaptureDevice *device in session.devices) {
if ([device.localizedName containsString:name] ||
[device.modelID containsString:name]) {
return device;
}
}
// 没找到精确匹配,返回第一个活跃的
for (AVCaptureDevice *device in session.devices) {
if (device.isConnected && !device.isSuspended) {
return device;
}
}
}
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
extern "C" {
/// 启用连续自动对焦和自动曝光(传入 C# 选中的摄像头名称)
void _EnableContinuousAutoFocus(const char *cameraName)
{
dispatch_async(dispatch_get_main_queue(), ^{
AVCaptureDevice *device = FindCameraByName(cameraName);
if (!device) {
NSLog(@"[CameraFocusHelper] 未找到摄像头设备");
return;
}
NSLog(@"[CameraFocusHelper] 配置设备: %@ (name=%@, model=%@)",
device.localizedName, device.localizedName, device.modelID);
NSError *error = nil;
if ([device lockForConfiguration:&error]) {
// 连续自动对焦
if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
NSLog(@"[CameraFocusHelper] 已设为连续自动对焦");
} else {
NSLog(@"[CameraFocusHelper] 设备不支持连续自动对焦");
}
// 连续自动曝光
if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
device.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
}
// 对焦范围限制为近距
if ([device respondsToSelector:@selector(isAutoFocusRangeRestrictionSupported)] &&
[device isAutoFocusRangeRestrictionSupported]) {
device.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;
NSLog(@"[CameraFocusHelper] 已设对焦范围为近距");
}
[device unlockForConfiguration];
NSLog(@"[CameraFocusHelper] 摄像头配置完成");
} else {
NSLog(@"[CameraFocusHelper] lockForConfiguration 失败: %@", error.localizedDescription);
}
});
}
/// 确保连续自动对焦仍在生效(传入 C# 选中的摄像头名称)
void _EnsureContinuousAutoFocus(const char *cameraName)
{
dispatch_async(dispatch_get_main_queue(), ^{
AVCaptureDevice *device = FindCameraByName(cameraName);
if (!device) return;
NSError *error = nil;
if ([device lockForConfiguration:&error]) {
if (device.focusMode != AVCaptureFocusModeContinuousAutoFocus &&
[device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
NSLog(@"[CameraFocusHelper] 重新设回连续自动对焦");
}
[device unlockForConfiguration];
}
});
}
}