【问题标题】:AVFoundation Camera Check and Flip VariableAVFoundation 相机检查和翻转变量
【发布时间】:2016-04-18 10:03:47
【问题描述】:

我创建了一个自定义相机工具。现在,我正在尝试检查是否存在摄像头,但是,我只有模拟器(没有摄像头)和 iphone(两个摄像头)。我没有处理任何相机,但我不明白它是如何在一台相机上工作的,所以我也不知道如何帮助用户翻转相机

目前我正在使用dojo custom camera 使用以下外部库

位置.Back.Front 有效,我没有处理相机,但我不知道如何处理

  • 处理 1 个摄像头的检查

  • 根据前后摄像头的存在情况分配一个变量来控制前后摄像头(这样我就可以在 VC 中创建一个 uibutton 并控制前后摄像头的翻转)。


// I call addVideoInput() while initializing

func addVideoInput() {
    if let device: AVCaptureDevice = self.deviceWithMediaTypeWithPosition(AVMediaTypeVideo, position: AVCaptureDevicePosition.Front) {
        do {
            let input = try AVCaptureDeviceInput(device: device)
            if self.session.canAddInput(input) {
                self.session.addInput(input)
            }
        } catch {
            print(error)
        }
    }
}

func deviceWithMediaTypeWithPosition(mediaType: NSString, position: AVCaptureDevicePosition) -> AVCaptureDevice? {
    let devices: NSArray = AVCaptureDevice.devicesWithMediaType(mediaType as String)
    if devices.count != 0 {
        if var captureDevice: AVCaptureDevice = devices.firstObject as? AVCaptureDevice {

            for device in devices {
                let d = device as! AVCaptureDevice
                if d.position == position {
                    captureDevice = d
                    break;
                }
            }
            print(captureDevice)
            return captureDevice
        }
    }
    print("doesnt have any camera")
    return nil

}

【问题讨论】:

  • 您是否要保留指向前后摄像头的指针?
  • “指针”是什么意思?我想分配一个变量来使用视图中的 UIButton 来控制前后摄像头之间的翻转。我可以在我的 ViewController 中初始化这个类时这样做。对于示例场景,'如果用户有 2 个摄像头 - 一个变量知道 Front 和 Back 都存在,并且显示最初从 Front 开始,然后 uibutton 在第一次运行时翻转到后置摄像头,依此类推..'; '否则,如果用户只有后置摄像头,隐藏用于翻转的 uibutton 并仅显示后置摄像头' - 这种方法
  • 一个指针 = 指向一个对象的变量。

标签: ios iphone swift camera avfoundation


【解决方案1】:

您需要删除对象并使用少量值和布尔值创建新对象。

这里我贴出创建相机位置时的代码AVCaptureDevicePosition

在类的顶部添加enum

enum CameraType {
    case Front
    case Back
}

初始化变量。

var cameraCheck = CameraType.Back

只需更改以下函数即可。

func addVideoInput() {
        if cameraCheck ==  CameraType.Front  {
            cameraCheck = CameraType.Back
            let device: AVCaptureDevice = self.deviceWithMediaTypeWithPosition(AVMediaTypeVideo, position: AVCaptureDevicePosition.Front)
            do {
                let input = try AVCaptureDeviceInput(device: device)
                if self.session.canAddInput(input) {
                    self.session.addInput(input)
                }
            } catch {
                print(error)
            }
        }else{
            cameraCheck = CameraType.Front
            let device: AVCaptureDevice = self.deviceWithMediaTypeWithPosition(AVMediaTypeVideo, position: AVCaptureDevicePosition.Back)
            do {
                let input = try AVCaptureDeviceInput(device: device)
                if self.session.canAddInput(input) {
                    self.session.addInput(input)
                }
            } catch {
                print(error)
            }
        }        
    }

在您的storyboard 中创建一个按钮。

现在进入你的viewcontroller 创建一个@IBAction 函数。

@IBAction func changeCamera(){
        self.camera = nil

        self.initializeCamera()
        self.establishVideoPreviewArea()

        if isBackCamera == true {
           isBackCamera = false
            self.camera?.cameraCheck = CameraType.Front
        }else{
            isBackCamera = true
            self.camera?.cameraCheck = CameraType.Back
        }
    }

这就是你实现的目标。

Also you can download the source code from here.

【讨论】:

    【解决方案2】:

    您可以在相机视图首次加载时使用布尔变量isUsingFrontCamera,

    设置,

    isUsingFrontCamera = false;
    

    然后点击相机切换按钮,

    -(IBAction)switchCameras:(id)sender {
      AVCaptureDevicePosition desiredPosition;
      if (isUsingFrontFacingCamera)
          desiredPosition = AVCaptureDevicePositionBack;
      else
          desiredPosition = AVCaptureDevicePositionFront;
    
      for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
          if ([d position] == desiredPosition) {
              [[captureVideoPreviewLayer session] beginConfiguration];
              AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil];
              for (AVCaptureInput *oldInput in [[captureVideoPreviewLayer session] inputs]) {
                  [[captureVideoPreviewLayer session] removeInput:oldInput];
              }
              [[captureVideoPreviewLayer session] addInput:input];
              [[captureVideoPreviewLayer session] commitConfiguration];
              break;
          }
      }
      isUsingFrontFacingCamera = !isUsingFrontFacingCamera;
    }
    

    captureVideoPreviewLayer 在哪里,

    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer
    

    另外,您可以使用

    获取相机的计数
    [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count]
    

    然后相应地显示和隐藏按钮

    【讨论】:

    【解决方案3】:

    最好保留一个枚举 IMO。

    private enum CameraPosition {
        case Front, Back
    }
    

    然后当你按下按钮时

    var currentState: CameraPostition
    

    切换到另一个摄像头位置。

    然后在 currentState 的 didSet 上配置相机

    var currentState: CameraPostition {
        didSet {
           configCamera(state: currentState)
        }
    }
    

    编辑:提供更多信息后。

    如果你改变了

    func addVideoInput() {
            let device: AVCaptureDevice = self.deviceWithMediaTypeWithPosition(AVMediaTypeVideo, position: AVCaptureDevicePosition.Back)
            do {
                let input = try AVCaptureDeviceInput(device: device)
                if self.session.canAddInput(input) {
                    self.session.addInput(input)
                }
            } catch {
                print(error)
            }
        }
    

    func addVideoInput(position: AVCaptureDevicePosition) {
            let device: AVCaptureDevice = self.deviceWithMediaTypeWithPosition(AVMediaTypeVideo, position: position)
            do {
                let input = try AVCaptureDeviceInput(device: device)
                if self.session.canAddInput(input) {
                    self.session.addInput(input)
                }
            } catch {
                print(error)
            }
        }
    

    然后,当您的“CurrentState”在 currentState 的 didSet 上发生变化时,您可以调用该函数。

    func configCamera(state: CameraState) {
          switch state{
             case .Back:
                  addVideoInput(.Back)
             case .Front
                  addVideoInput(.Front)
          }
    }
    

    【讨论】:

    • 实现这个我有点迷失了。我正在尝试调整XMCCamera.swift,您会看到这两个功能。你能指导我实施你的方法吗?因为我也不知道如何检查是否有前置或后置摄像头,因为我没有一个有 1 个摄像头的设备。
    • 这比较困难,因为你需要熟悉 AVFoundation 的各个部分,听起来你使用的是你在 github 上找到的示例?
    • 实际上经过几个小时的阅读,我在 github 上找到了这个示例。我认为最好的办法是通过它,理解它并调整它。这是相当小的代码块。现在,我可以拍一张照片并将其设置为 UIImage,并立即呈现。我卡住的地方就是这一点,我需要根据相机的数量翻转相机(如果只有1个相机,隐藏翻转按钮)。如果您能帮我解决这个问题,我将不胜感激
    • 感谢您的详细回答,但我不知道您是如何检查用户是否有相机的。我的意思是如果相机为零或只有一台相机怎么办。你能在这个 github repo 上实现它吗(它只有 2 个文件),所以我了解你的枚举设置是如何工作的?对此我将不胜感激
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多