AVCaptureDevice 对象代表一个物理的捕获设备 和 设备相关的属性。你使用捕获设备配置底层硬件的特性。还提供了输入数据捕捉设备(比如音频或视频)AVCaptureSession对象。
你可以使用 AVCaptureDevice 类的相关方法去列举可用设备, 查询设备的能力,了解设备更多的相关信息。在你试着去设置捕获设备的相关属性之前(聚焦,曝光,等等)你必须先通过 lockForConfiguration()
方法去获取一个锁。 你还应该查询设备的能力,去确保设置的新模式在设备上是有效的。然后你可以设置这些属性,在调用 unlockForConfiguration()
方法来关闭这个锁。你可以持有这个锁,如果你想要所有的可设置设备的属性都保持不变。然而,持有不必要的,设备锁定可能降低捕获质量在其他应用程序共享设备, 不推荐这么干。
最常见的配置捕捉设置可以通过 AVCaptureSession 对象, 他是可以进行预先设置的。 然而,在iOS 设备上,一些指定的选项(例如高帧速率)需要直接设置捕获格式AVCaptureDevice实例。
下面的代码示例演示了如何选择一个iOS设备的最高可能的帧率:
// 为最高配置的相机帧速率
- (void)configureCameraForHighestFrameRate:(AVCaptureDevice *)device
{
// 捕获设备格式
AVCaptureDeviceFormat *bestFormat = nil;
// 帧率范围
AVFrameRateRange *bestFrameRateRange = nil;
for ( AVCaptureDeviceFormat *format in [device formats] ) {
for ( AVFrameRateRange *range in format.videoSupportedFrameRateRanges ) {
// 和最大帧率配置
if ( range.maxFrameRate > bestFrameRateRange.maxFrameRate ) {
bestFormat = format;
bestFrameRateRange = range;
}
}
}
if ( bestFormat ) {
if ( [device lockForConfiguration:NULL] == YES ) {
device.activeFormat = bestFormat;
device.activeVideoMinFrameDuration = bestFrameRateRange.minFrameDuration;
device.activeVideoMaxFrameDuration = bestFrameRateRange.minFrameDuration;
[device unlockForConfiguration];
}
}
}
注意事项
在iOS 中, 直接配置一个捕获设备的activeFormat
属性需要改变 捕获会话的预设AVCaptureSessionPresetInputPriority
。 在做这些改变后,捕获会话不再自动配置捕获格式,当你改变 session 的拓扑结构后 调用startRunning()
方法 或者commitConfiguration()
。
发现设备
class func defaultDevice(withDeviceType: AVCaptureDeviceType!, mediaType: String!, position: AVCaptureDevicePosition)
// 根据指定的设备类型,媒体类型,设备位置来返回一个默认的设备。
/*
deviceType : 请求的捕获设备类型。builtInWideAngleCamera(一个内置的广角镜头。这些设备是适合一般用途使用 ) 。
AVCaptureDeviceType: type 类型的值用来标识一般类型的捕获设备。
使用 defaultDevice(withDeviceType:mediaType:position:) 或者 AVCaptureDeviceDiscoverySession 类。
static let builtInMicrophone: AVCaptureDeviceType
// 一个内置的麦克风。
static let builtInWideAngleCamera: AVCaptureDeviceType
// 一个内置的广角镜头。这些设备是适合一般用途使用。
static let builtInTelephotoCamera: AVCaptureDeviceType
// 内置摄像头设备有更长的比广角相机焦距。
static let builtInDualCamera: AVCaptureDeviceType
// 双摄像头设备,结合内置的广角和长焦相机,一起工作作为一个捕获设备。
mediaType : 请求捕获的媒体类型,比如AVMediaTypeAudio。
let AVMediaTypeVideo: String
// 指定视屏
let AVMediaTypeAudio: String
// 指定音频
let AVMediaTypeText: String
// 指定文本
let AVMediaTypeClosedCaption: String
// 指定闭路内容。
let AVMediaTypeSubtitle: String
// 指定子标题
let AVMediaTypeTimecode: String
// 指定一个时间代码。
let AVMediaTypeMetadata: String
// 指定元数据类型
let AVMediaTypeMuxed: String
指定mux媒体。
position :捕获设备请求的位置相对于系统硬件(或前置)。 不指定这个值就不会再在意这个设置。
返回值: 指定的设备类型、媒体类型,位置系统默认设备。如果没有现有设备满足指定的条件。
*/
class func devices()
// 返回一个数组系统上可用的捕获设备
init!(uniqueID: String!)
// 根据给定的唯一标识来获取设备
/*
// 后置摄像头
let backCamera = AVCaptureDevice(uniqueID: "com.apple.avfoundation.avcapturedevice.built-in_video:0")
// 前置摄像头
let frontCamera = AVCaptureDevice(uniqueID: "com.apple.avfoundation.avcapturedevice.built-in_video:1")
// 麦克风
let microphone = AVCaptureDevice(uniqueID: "com.apple.avfoundation.avcapturedevice.built-in_audio:0")
*/
class func defaultDevice(withMediaType: String!)
// 返回给定的默认设备用于捕获数据媒体类型。
/*
let device1 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
// 后置摄像头
let device2 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)
// 麦克风
let device3 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeText)
// nil
let device4 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeClosedCaption)
// nil
let device5 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeSubtitle)
// nil
let device6 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeTimecode)
// nil
let device7 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeMetadata)
// nil
let device8 = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeMuxed)
// nil
*/
class func devices(withMediaType: String!)
// 返回一个能够捕获数据的一个给定的媒体类型数据的设备数组。
验证授权
class func requestAccess(forMediaType: String!, completionHandler: ((Bool) -> Void)!)
// 请求用户的权限,如果需要,记录指定的媒体类型。
/*
mediaType : 一个媒体常量,是 AVMediaTypeVideo 或者 AVMediaTypeAudio。
如果另外一些媒体类型是支持的, 那么就会抛出一个无效参数异常。
handler : 一旦许可请求被授予,或者拒绝,这个回调 block 就会调用。
回调可以在任何队列上调用。 客户端有责任确保任何 UI 相关的调用在主线程或者主队列上调用。
block 接受一个 授权的参数 如果用户授予许可使用硬件返回真,否则错误的。块将立即返回。
*/
class func authorizationStatus(forMediaType: String!)
// 返回一个常数.表示应用程序是否允许,记录指定的媒体类型
/*
mediaType : 一个媒体常量,是 AVMediaTypeVideo 或者 AVMediaTypeAudio。
返回值标识授权状态。
录制音频总是需要明确的用户许可,录制视频也总是请求用户许可。 在第一次你创建任何 AVCaptureDeviceInput 对象会有许可请求。
系统自动显示一个弹框去记录许可请求。
AVAuthorizationStatus
case notDetermined : 不确定:用户权限需要媒体捕捉,但是用户尚未允许还是拒绝这样的许可。
case restricted : 限制:用户不允许访问媒体捕获设备。 这种状态通常是设备不可用。
case denied : 否认: 用户已经明确拒绝媒体捕捉。
case authorized : 已经授权 : 用户已经明确授予权限,或显式的用户权限不需要媒体类型的问题。
*/
管理设配配置
func lockForConfiguration()
// 请求单独的访问设备的硬件属性(获取锁,开始对捕获设备进行配置)
func unlockForConfiguration()
// 放弃独家控制设备的配置。(取消锁,完成对设配的配置)
var isInUseByAnotherApplication: Bool
// 设备是否完全被另一个app 占用。
var isSuspended: Bool
// 是否是暂停的
var inputSources: [Any]!
// AVCaptureDeviceInputSource对象数组代表输入源支持的设备。
var activeInputSource: AVCaptureDeviceInputSource!
// 当前激活的输入源
var linkedDevices: [Any]!
var transportType: Int32
// 传输类型的接收器。