iOS设备未被AVCaptureDevice.devices()列出,除非打开Quicktime

时间:2018-02-06 15:27:09

标签: ios swift avfoundation quicktime

我正在尝试使用Swift游乐场中的AVCaptureDevice.devices()列出连接到我的计算机的设备。

import Cocoa
import Foundation
import AVFoundation
import CoreMediaIO

var prop = CMIOObjectPropertyAddress(
    mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyAllowScreenCaptureDevices),
    mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
    mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementMaster))

var allow : UInt32 = 1
let dataSize : UInt32 = 4
let zero : UInt32 = 0
CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &prop, zero, nil, dataSize, &allow)


var session = AVCaptureSession()
session.sessionPreset = AVCaptureSession.Preset.low

let devices = AVCaptureDevice.devices()
for device in devices {
    let deviceID = device.uniqueID
    let deviceName = device.localizedName
    print("\(deviceID): \(deviceName)")
}

即使我的iPhone连接到我的电脑,这也会给我以下结果

04-52-c7-c1-65-c4:input: Bose Tito
AppleHDAEngineInput:1B,0,1,0:1: Built-in Microphone
CC26311ECFEG1HNBA: FaceTime HD Camera

现在我注意到的是,如果我启动Quicktime Player,选择New Movie Recording并选择我的设备作为Camera source,那么我的设备就会列出

04-52-c7-c1-65-c4:input: Bose Tito
AppleHDAEngineInput:1B,0,1,0:1: Built-in Microphone
CC26311ECFEG1HNBA: FaceTime HD Camera
12345b7406eeb053e2d5cded2527315d6110a16e: tito

有没有阻止这个?

3 个答案:

答案 0 :(得分:1)

您需要等待设备出现。

注册AVCaptureDeviceWasConnectedNotification,一旦可用,即会收到通知。

答案 1 :(得分:1)

您如何实施检查以确保可以使用iOS设备? 我遇到了同样的问题,并且正在研究一个项目。

目前,如果我打开quicktime,它可以工作(我也对设备ID进行了硬编码,但需要删除它)

 override func viewDidLoad() {

    super.viewDidLoad()
    enableDalDevices()

    camera.layer = CALayer()
    let session:AVCaptureSession = AVCaptureSession()
    session.sessionPreset = AVCaptureSession.Preset.high
    let listdevices:Array = (AVCaptureDevice.devices())


   // Grabs iOS device on system change value in array [X] depending on devices connected on your own Mac
    let device:AVCaptureDevice = listdevices[6]

 do {
   try session.addInput(AVCaptureDeviceInput(device: device))

    //Preview
    let previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
    let myView:NSView = self.view
    previewLayer.frame = myView.bounds
    previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
    previewLayer.connection?.videoOrientation = AVCaptureVideoOrientation.landscapeRight

    self.camera.layer?.addSublayer(previewLayer)
    session.startRunning()

            print(listdevices)

    } catch {

            }


}

答案 2 :(得分:0)

使用@Valerian的答案来帮助@adamprocter,这就是我最终解决它的方式。

override func viewDidLoad() {

    super.viewDidLoad()
    enableDalDevices()

    camera.layer = CALayer()
    let session:AVCaptureSession = AVCaptureSession()
    session.sessionPreset = AVCaptureSession.Preset.high

    let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.externalUnknown], mediaType: .muxed, position: .unspecified)
    //You get the devices here and their IDs and do whatever you want
    showDevices(devices: discoverySession.devices)

    //Register for a notification just like @Valerian said earlier
    NotificationCenter.default.addObserver(self, selector: #selector(newDevice), name: NSNotification.Name.AVCaptureDeviceWasConnected, object: nil)

}

@objc func newDevice() {
    let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.externalUnknown], mediaType: .muxed, position: .unspecified)
    showDevices(devices: discoverySession.devices)
}