2016-10-06 213 views
22

iOS版10出來之前我用的是下面的代碼爲我的錄像機的視頻和音頻採集:如何獲得前置攝像頭,後置攝像頭和音頻AVCaptureDeviceDiscoverySession

for device in AVCaptureDevice.devices() 
{ 
    if (device as AnyObject).hasMediaType(AVMediaTypeAudio) 
    { 
     self.audioCapture = device as? AVCaptureDevice 
    } 
    else if (device as AnyObject).hasMediaType(AVMediaTypeVideo) 
    { 
     if (device as AnyObject).position == AVCaptureDevicePosition.back 
     { 
      self.backCameraVideoCapture = device as? AVCaptureDevice 
     } 
     else 
     { 
      self.frontCameraVideoCapture = device as? AVCaptureDevice 
     } 
    } 
} 

當iOS的10終於來了在運行我的代碼時,我收到以下警告。請注意,我的錄像機仍在運行2周左右。

'devices()' was deprecated in iOS 10.0: Use AVCaptureDeviceDiscoverySession instead.

當我今天早上運行我的代碼時,我的錄像機停止工作。 xCode8不會給我任何錯誤,但相機捕獲的previewLayer是完全白色的。當我然後開始記錄我收到以下錯誤:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17554440 {Error Domain=NSOSStatusErrorDomain Code=-12780 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12780)}

我相信,有事可做的事實,我使用的是過時的做法AVCaptureDevice.devices()。因此,我想知道如何使用AVCaptureDeviceDiscoverySession代替?

非常感謝您的幫助!

回答

46

你可以得到的前置攝像頭具有以下:

AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front) 

背面攝像頭:

AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back) 

和麥克風:

AVCaptureDevice.defaultDevice(withDeviceType: .builtInMicrophone, mediaType: AVMediaTypeAudio, position: .unspecified) 
+0

原來,我在我的iPhone攝像頭被打破了,因此白顏色顯示在預覽圖層中。不過謝謝你的回答,至少我可以擺脫我的警告xcode8一直在給我。 – AndreasLukas

+1

你知道怎麼用Objective-C的後置攝像頭做同樣的事情嗎? – fi12

2

對於我的視頻捕捉程序,我」 m使用下面的代碼來獲取麥克風,前置和後置攝像頭,我已經測試了這個代碼從iOS 7到10.0.2。

 var frontCamera : AVCaptureDevice? 
     var rearCamera : AVCaptureDevice? 

     captureSession = AVCaptureSession() 

     let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) 

     let audioDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeAudio) 

     for mic in audioDevices { 
      audioDevice = mic as? AVCaptureDevice 
      audioCapturePossible = true 
     } 

     for device in devices { 
      if device.position == AVCaptureDevicePosition.Front { 
       frontCamera = device as? AVCaptureDevice 
       hasFrontCamera = true 
      } 
      else if device.position == AVCaptureDevicePosition.Back { 
       rearCamera = device as? AVCaptureDevice 
       hasRearCamera = true 
      } 

     } 
+0

你仍然可以用AVCaptureDevice.devicesWithMediaType –

8

這裏是我的代碼(SWIFT 3)獲得相機的位置:

// Find a camera with the specified AVCaptureDevicePosition, returning nil if one is not found 
func cameraWithPosition(_ position: AVCaptureDevicePosition) -> AVCaptureDevice? 
{ 
    if let deviceDescoverySession = AVCaptureDeviceDiscoverySession.init(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], 
                  mediaType: AVMediaTypeVideo, 
                  position: AVCaptureDevicePosition.unspecified) { 

     for device in deviceDescoverySession.devices { 
      if device.position == position { 
       return device 
      } 
     } 
    } 

    return nil 
} 

如果你願意,你也可以通過改變deviceTypes陣列得到iPhone 7+(雙攝像頭),新devicesTypes 。

這裏有一個很好看的:https://forums.developer.apple.com/thread/63347

2

嘗試下面的代碼來獲取攝像機ID:

NSString *cameraID = nil; 

NSArray *captureDeviceType = @[AVCaptureDeviceTypeBuiltInWideAngleCamera]; 
AVCaptureDeviceDiscoverySession *captureDevice = 
       [AVCaptureDeviceDiscoverySession 
       discoverySessionWithDeviceTypes:captureDeviceType 
       mediaType:AVMediaTypeVideo 
       position:AVCaptureDevicePositionUnspecified]; 

cameraID = [captureDevice.devices.lastObject localizedName]; 
2

斯威夫特3

對於選擇相機背面:(你也可以改變.back根據需要)

爲了選擇另一個deviceType,簡單地將它添加到[](即:

[deviceTypeCamera,AVCaptureDeviceType.builtInMicrophone]

(或創建一個私人設...像我與背相機的代碼)

private let position = AVCaptureDevicePosition.back 
private let deviceTypeBackCamera = AVCaptureDeviceType.builtInWideAngleCamera 

private func selectCaptureDevice() -> AVCaptureDevice? { 
    return AVCaptureDeviceDiscoverySession(deviceTypes: [deviceTypeBackCamera], mediaType: AVMediaTypeVideo, position: position).devices.first 

} 
+0

Xcode的9只問我用__deviceTypes過時的警告:不是deviceTypes:,除此之外,它的工作原理。 – epx

7

夫特4的iOS 10+和的Xcode 9的β5替換

if let cameraID = AVCaptureDevice.defaultDevice(withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)?.localizedName { 
     //cameraID = "Front Camera" 
} 

做了與AVCaptureDevice.DiscoverySession實施

if let cameraID = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front).devices.first?.localizedName{ 
     //cameraID = "Front Camera" 
} 

需要與#available(iOS的10,*)把它包檢查。

1

例如:iOS的11斯威夫特4

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Get the back-facing camera for capturing videos 

    // AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back) 
    let deviceDiscoverySession = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back) 

    guard let captureDevice = deviceDiscoverySession else { 
     print("Failed to get the camera device") 
     return 
    } 

    do { 
     // Get an instance of the AVCaptureDeviceInput class using the previous device object. 
     let input = try AVCaptureDeviceInput(device: captureDevice) 

     // Set the input device on the capture session. 
     captureSession.addInput(input) 

    } catch { 
     // If any error occurs, simply print it out and don't continue any more. 
     print(error) 
     return 
    } 

    // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer. 
    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
    videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill 
    videoPreviewLayer?.frame = view.layer.bounds 
    view.layer.addSublayer(videoPreviewLayer!) 

    // Start video capture. 
    captureSession.startRunning() 
+0

非常感謝! – GameDev

相關問題