web-dev-qa-db-ja.com

AVCaptureDeviceDiscoverySessionでフロントカメラ、バックカメラ、オーディオを取得する方法

IOS 10が登場する前は、ビデオレコーダーのビデオとオーディオのキャプチャを取得するために次のコードを使用していました。

 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()」はiOS 10.0で廃止されました。代わりにAVCaptureDeviceDiscoverySessionを使用してください。

今朝、コードを実行していたため、ビデオレコーダーが動作しなくなりました。 xCode8はエラーを表示しませんが、カメラキャプチャのpreviewLayerは完全に白です。その後、録音を開始すると、次のエラーが表示されます。

Error Domain = AVFoundationErrorDomain Code = -11800 "操作を完了できませんでした" UserInfo = {NSLocalizedDescription =操作を完了できませんでした、NSUnderlyingError = 0x17554440 {Error Domain = NSOSStatusErrorDomain Code = -12780 "(null)"}、NSLocalizedFailureReason = An不明なエラーが発生しました(-12780)}

これは、非推奨のアプローチAVCaptureDevice.devices()を使用しているという事実と関係があると思います。したがって、代わりにAVCaptureDeviceDiscoverySessionを使用する方法を疑問に思っていましたか?

よろしくお願いします!

39
AndreasLukas

次の方法でフロントカメラを取得できます。

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .front)

バックカメラ:

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)

マイク:

AVCaptureDevice.default(.builtInMicrophone, for: AVMediaType.audio, position: .unspecified)
77
born_stubborn

Swift 4、iOS 10以降、およびXcode 10.1の置き換え

if let cameraID = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)?.localizedName {
       //cameraID = "Front Camera"
}

AVCaptureDevice.DiscoverySession実装

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

#available(iOS 10、*) checkでラップする必要があります。

13

カメラの位置を取得するためのコード(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

11
hefgi

Xcode 9.2およびSwift 4で動作します

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)

https://developer.Apple.com/documentation/avfoundation/avcapturedevice/2361508-default

8
atereshkov

例:iOS 11 Swift 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()
3
Harry McGovern

Swift

バックカメラを選択するには:(必要に応じて.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

 }
3
MLBDG

以下のコードを試して、カメラIDを取得してください。

NSString *cameraID = nil;

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

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

ビデオキャプチャアプリでは、次のコードを使用してマイク、フロントカメラ、リアカメラを取得し、このコードを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
            }

        }
1
Hammadzafar

Swift 4(xCode 10.1)

これは、Swiftの最新バージョンで私のために働いたものです。私はこの答えを知りませんでした、そして、それを突き出すのに私はしばらく時間がかかりました、それでここに正面カメラを得る方法があります。

 if let device = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera , mediaType: AVMediaTypeVideo, position: .front)  {
    //Do the camera thing here..
}
1
Dave Levy

5/2019:

 //video
        self.session = AVCaptureSession()
        guard
            let videoDeviceInput = try? AVCaptureDeviceInput(device: device!),
            self.session!.canAddInput(videoDeviceInput)
            else { return }
        self.session!.addInput(videoDeviceInput)

  //audio
        guard
            let audioDeviceInput = try? AVCaptureDeviceInput(device: mic!),
            self.session!.canAddInput(audioDeviceInput)
            else { return }
        self.session!.addInput(audioDeviceInput) 
0
Boris Detry