Swift自定义相机设置闪光灯模式为开启后不生效如何解决?
核心原因
你设置的AVCaptureDevice.flashMode仅对AVCapturePhotoOutput触发的官方拍照动作生效,你当前使用AVCaptureVideoDataOutput的实时视频流回调取帧实现拍照,属于视频流捕获场景,闪光灯的普通拍照模式不会作用于视频流帧。
解决方案
方案1:继续使用VideoDataOutput方案,改用手电筒(Torch)模式控制闪光灯
闪光灯在视频流场景下需要通过手电筒模式控制,如果你需要拍照瞬间亮一下,按照如下逻辑修改:
- 触发拍照时先开启手电筒,避免帧捕获时闪光灯还未启动
// 拍照按钮点击触发逻辑 @objc func handleCaptureAction() { guard let device = currentDevice, device.hasTorch, device.isTorchModeSupported(.on) else { takePicture = true return } do { try device.lockForConfiguration() try device.setTorchModeOn(level: 1.0) device.unlockForConfiguration() // 延迟50ms等闪光灯完全亮起,避免捕获到暗帧 DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { self.takePicture = true // 捕获完成后关闭手电筒 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { do { try device.lockForConfiguration() device.torchMode = .off device.unlockForConfiguration() } catch { print("关闭闪光灯失败: \(error.localizedDescription)") } } } } catch { print("开启闪光灯失败: \(error.localizedDescription)") takePicture = true } }
如果需要闪光灯常亮,直接在相机会话启动后设置torchMode = .on即可。
方案2(更推荐):替换为AVCapturePhotoOutput实现拍照
这是苹果官方推荐的拍照实现方案,原生支持闪光灯模式,无需手动控制时序,和系统相机行为完全一致:
- 先将PhotoOutput添加到捕获会话
let photoOutput = AVCapturePhotoOutput() if captureSession.canAddOutput(photoOutput) { captureSession.addOutput(photoOutput) }
- 拍照触发时直接设置闪光灯模式
let settings = AVCapturePhotoSettings() if photoOutput.supportedFlashModes.contains(.on) { settings.flashMode = .on } photoOutput.capturePhoto(with: settings, delegate: self)
- 实现
AVCapturePhotoCaptureDelegate代理获取照片
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { guard let imageData = photo.fileDataRepresentation(), let uiImage = UIImage(data: imageData) else { return } savePicture(image: uiImage) }
注意事项
- 只有后置摄像头支持闪光灯/手电筒功能,切换到前置摄像头时要做可用性判断,避免崩溃
- 所有
AVCaptureDevice的配置修改都要包裹在lockForConfiguration和unlockForConfiguration之间,并用do-catch捕获异常
内容的提问来源于stack exchange,提问作者Boyuan Wang
相关产品推荐
相关产品推荐

