iOS 除非打开 Quicktime,否则 AVCaptureDevice.devices() 不会列出设备
iOS Device not listed by AVCaptureDevice.devices() unless Quicktime is opened
我正在尝试在 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,select 新电影录制和 select 将我的设备作为相机源,然后我的设备会被列出
04-52-c7-c1-65-c4:input: Bose Tito
AppleHDAEngineInput:1B,0,1,0:1: Built-in Microphone
CC26311ECFEG1HNBA: FaceTime HD Camera
12345b7406eeb053e2d5cded2527315d6110a16e: tito
有什么办法可以防止这种情况发生吗?
您需要稍等一下设备才会出现。
注册 AVCaptureDeviceWasConnectedNotification
可在可用时收到通知。
您如何检查 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 {
}
}
使用@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)
}
我正在尝试在 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,select 新电影录制和 select 将我的设备作为相机源,然后我的设备会被列出
04-52-c7-c1-65-c4:input: Bose Tito
AppleHDAEngineInput:1B,0,1,0:1: Built-in Microphone
CC26311ECFEG1HNBA: FaceTime HD Camera
12345b7406eeb053e2d5cded2527315d6110a16e: tito
有什么办法可以防止这种情况发生吗?
您需要稍等一下设备才会出现。
注册 AVCaptureDeviceWasConnectedNotification
可在可用时收到通知。
您如何检查 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 {
}
}
使用@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)
}