You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift自定义相机设置闪光灯模式为开启后不生效如何解决?

核心原因

你设置的AVCaptureDevice.flashMode仅对AVCapturePhotoOutput触发的官方拍照动作生效,你当前使用AVCaptureVideoDataOutput的实时视频流回调取帧实现拍照,属于视频流捕获场景,闪光灯的普通拍照模式不会作用于视频流帧。

解决方案

方案1:继续使用VideoDataOutput方案,改用手电筒(Torch)模式控制闪光灯

闪光灯在视频流场景下需要通过手电筒模式控制,如果你需要拍照瞬间亮一下,按照如下逻辑修改:

  1. 触发拍照时先开启手电筒,避免帧捕获时闪光灯还未启动
// 拍照按钮点击触发逻辑
@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实现拍照

这是苹果官方推荐的拍照实现方案,原生支持闪光灯模式,无需手动控制时序,和系统相机行为完全一致:

  1. 先将PhotoOutput添加到捕获会话
let photoOutput = AVCapturePhotoOutput()
if captureSession.canAddOutput(photoOutput) {
    captureSession.addOutput(photoOutput)
}
  1. 拍照触发时直接设置闪光灯模式
let settings = AVCapturePhotoSettings()
if photoOutput.supportedFlashModes.contains(.on) {
    settings.flashMode = .on
}
photoOutput.capturePhoto(with: settings, delegate: self)
  1. 实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:48:02