我有一台使用AVFoundation和Swift定制的相机.当相机启动时,它最初是放大的.大约一秒钟后,它会缩小到正常状态.我不确定为什么会发生这种情况,我根本没有修改放大倍数,我也没有改变输入相机.也许我的setUp()函数中有问题.

struct CameraPreview: UIViewRepresentable {
   @EnvironmentObject var cameraModel : CameraViewModel
   var size: CGSize
   
   func makeUIView(context: Context) -> UIView {
       let view = UIView(frame: CGRect(origin: .zero, size: size))
       guard let preview = cameraModel.preview else { return view }

       preview.frame = view.bounds
       preview.videoGravity = .resizeAspectFill
       view.layer.addSublayer(preview)

       DispatchQueue.global(qos: .userInitiated).async {
           if !self.cameraModel.session.isRunning {
               self.cameraModel.session.startRunning()
           }
       }
       
       return view
   }
   
   func updateUIView(_ uiView: UIView, context: Context) { }
}


class CameraViewModel: NSObject, ObservableObject, AVCaptureFileOutputRecordingDelegate, AVCapturePhotoCaptureDelegate {
   @Published var session = AVCaptureSession()
   @Published var alert = false
   @Published var output = AVCaptureMovieFileOutput()
   @Published var preview: AVCaptureVideoPreviewLayer!
   @Published var isRecording: Bool = false
   @Published var recordedURLs: [URL] = []
   @Published var previewURL: URL?
   @Published var showPreview: Bool = false
   @Published var recordedDuration: CGFloat = 0
   @Published var maxDuration: CGFloat = 25
   @Published var capturedImage: UIImage?
   @Published var photoOutput = AVCapturePhotoOutput()
   @Published var flashMode: AVCaptureDevice.TorchMode = .off
   var currentCameraPosition: AVCaptureDevice.Position = .back
   @Published var photoMode: Bool = true
   @Published var isVideoFlashOn: Bool = false
   
   override init() {
       super.init()
       self.checkPermission()
       self.preview = AVCaptureVideoPreviewLayer(session: session)
       self.preview.videoGravity = .resizeAspectFill
   }
   
   func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

   }
   
   func checkPermission(){
       switch AVCaptureDevice.authorizationStatus(for: .video) {
       case .authorized:
           checkAudioPermission()
           return
       case .notDetermined:
           AVCaptureDevice.requestAccess(for: .video) { (status) in
               if status {
                   self.checkAudioPermission()
               }
           }
       case .denied:
           self.alert.toggle()
           return
       default:
           return
       }
   }
   
   func checkAudioPermission() {
       switch AVCaptureDevice.authorizationStatus(for: .audio) {
       case .authorized:
           setUp()
           return
       case .notDetermined:
           AVCaptureDevice.requestAccess(for: .audio) { (audioStatus) in
               if audioStatus {
                   self.setUp()
               }
           }
       case .denied:
           self.alert.toggle()
           return
       default:
           return
       }
   }
   
   func setUp(){
       do {
           self.session.beginConfiguration()
           let cameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
           let videoInput = try AVCaptureDeviceInput(device: cameraDevice!)
           let audioDevice = AVCaptureDevice.default(for: .audio)
           let audioInput = try AVCaptureDeviceInput(device: audioDevice!)
           
           if self.session.canAddInput(videoInput) && self.session.canAddInput(audioInput){
               self.session.addInput(videoInput)
               self.session.addInput(audioInput)
           }

           if self.session.canAddOutput(self.output){
               self.session.addOutput(self.output)
           }
           
           if self.session.canAddOutput(self.photoOutput) {
               self.session.addOutput(self.photoOutput)
           }
           
           self.session.commitConfiguration()
       }
       catch {
           print(error.localizedDescription)
       }
   }
   
   func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

   }
}

推荐答案

这可能与AVCaptureSessionAVCaptureDevice的配置有关.

您可以try 在会话开始时明确设置摄像机的zoom 级别.这可以通过调整AVCaptureDevicevideoZoomFactor属性来实现,前提是它支持zoom .

您的setUp功能将是:

func setUp(){
    do {
        self.session.beginConfiguration()
        let cameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
        let videoInput = try AVCaptureDeviceInput(device: cameraDevice!)
        let audioDevice = AVCaptureDevice.default(for: .audio)
        let audioInput = try AVCaptureDeviceInput(device: audioDevice!)

        if self.session.canAddInput(videoInput) && self.session.canAddInput(audioInput){
            self.session.addInput(videoInput)
            self.session.addInput(audioInput)
        }

        if self.session.canAddOutput(self.output){
            self.session.addOutput(self.output)
        }

        if self.session.canAddOutput(self.photoOutput) {
            self.session.addOutput(self.photoOutput)
        }

        // Setting zoom level
        try cameraDevice?.lockForConfiguration()
        if cameraDevice?.activeFormat.videoMaxZoomFactor ?? 1 > 1 {
            cameraDevice?.videoZoomFactor = 1 // Set this to your desired zoom level
        }
        cameraDevice?.unlockForConfiguration()

        self.session.commitConfiguration()
    }
    catch {
            print(error.localizedDescription)
    }
}

我添加了一个判断,以确保相机设备支持变焦,然后将videoZoomFactor设置为1,这是正常的变焦级别.您可以根据需要调整此值.

请注意,操作videoZoomFactor需要锁定相机设备的配置,这就是使用lockForConfiguration()unlockForConfiguration()的原因.

Ios相关问答推荐

Flutter应用程序无法使用IOS/Swift的蓝牙核心库发现某些外围设备

在许多UIButton中对齐文本,即使SF Symbols(或其他图像)具有不同的宽度?

从后台线程调用DispatchObject的方法安全吗?

OnTapGesture在其修改的视图外部触发

当文本为空时,具有垂直轴的SwiftUI文本字段不会与FirstTextBaseline对齐

Swift locationManager.requestWhenInUseAuthorization() 不提示用户

比较 `某个协议` 实例时出现编译错误

SKScene 的更新功能似乎不起作用

将 URLCache 子类与 URLSession 一起使用

DllImport with .a file for iOS in MAUI

clipShape swift的三元

UIViewControllerRepresentable 在 Xcode 14 iOS 16 上崩溃

通过 iOS 创建和导出动画 gif?

如何将 iPhone OSStatus 代码转换为有用的东西?

标题为 UIImage 的导航栏

@IBDesignable 崩溃代理

如何以编程方式切换 UISegmentedControl?

iOS中的apk类似功能是什么?

Parse for iOS:try 运行应用程序时出错

我可以在 UIScrollView 中使用 UIRefreshControl 吗?