兼容 IOS

This commit is contained in:
2026-06-13 19:00:37 +08:00
parent 208920dfea
commit 8570486798
3 changed files with 79 additions and 13 deletions
+38 -9
View File
@@ -336,7 +336,9 @@ private final class RecordingCameraController: NSObject, AVCaptureFileOutputReco
}
do {
let nextZoom = self.clampedZoomRatio(ratio, for: device)
// 入参是显示倍率(1.0x = 主摄),按 S 基准换算回设备 zoomFactor。
let baseline = self.mainBaselineFactor(for: device)
let nextZoom = self.clampedZoomRatio(ratio * baseline, for: device)
try device.lockForConfiguration()
device.videoZoomFactor = nextZoom
device.unlockForConfiguration()
@@ -427,11 +429,7 @@ private final class RecordingCameraController: NSObject, AVCaptureFileOutputReco
return
}
guard
let videoDevice = AVCaptureDevice.default(
.builtInWideAngleCamera, for: .video, position: .back)
?? AVCaptureDevice.default(for: .video)
else {
guard let videoDevice = Self.preferredVideoDevice() else {
throw NSError(
domain: "RecordingCamera", code: 1,
userInfo: [NSLocalizedDescriptionKey: "No camera device available"])
@@ -461,10 +459,39 @@ private final class RecordingCameraController: NSObject, AVCaptureFileOutputReco
session.commitConfiguration()
configured = true
// 默认以主摄(显示 1.0x)开场:虚拟多摄设备里主摄对应的 zoomFactor 是 S。
currentZoomRatio = mainBaselineFactor(for: videoDevice)
try applyCurrentZoom()
try configureAudioInput(enabled: withAudio)
}
/// 优先选用包含超广角的虚拟多摄设备,使 minAvailableVideoZoomFactor 能低于主摄(从而支持 0.6x)。
private static func preferredVideoDevice() -> AVCaptureDevice? {
let preferredTypes: [AVCaptureDevice.DeviceType] = [
.builtInTripleCamera,
.builtInDualWideCamera,
.builtInWideAngleCamera,
]
for type in preferredTypes {
if let device = AVCaptureDevice.default(type, for: .video, position: .back) {
return device
}
}
return AVCaptureDevice.default(for: .video)
}
/// 虚拟多摄设备中「主摄(显示 1.0x)」对应的设备 zoomFactor 基准 S。
/// 取 ultra-wide → wide 的切换点;非虚拟设备无切换点时返回 1.0(向后兼容)。
private func mainBaselineFactor(for device: AVCaptureDevice) -> CGFloat {
if let first = device.virtualDeviceSwitchOverVideoZoomFactors.first {
let value = CGFloat(truncating: first)
if value > 0 {
return value
}
}
return 1.0
}
private func currentZoomCapabilitiesMap() -> [String: Any] {
guard let device = videoInput?.device else {
return [
@@ -474,14 +501,16 @@ private final class RecordingCameraController: NSObject, AVCaptureFileOutputReco
]
}
// 设备 zoomFactor 以 S 为基准换算成 App 使用的「显示倍率」(1.0x = 主摄)。
let baseline = mainBaselineFactor(for: device)
let minZoom = device.minAvailableVideoZoomFactor
let maxZoom = device.maxAvailableVideoZoomFactor
let zoom = clampedZoomRatio(device.videoZoomFactor, for: device)
currentZoomRatio = zoom
return [
"zoomRatio": Double(zoom),
"minZoomRatio": Double(minZoom),
"maxZoomRatio": Double(maxZoom),
"zoomRatio": Double(zoom / baseline),
"minZoomRatio": Double(minZoom / baseline),
"maxZoomRatio": Double(maxZoom / baseline),
]
}