iPhone 手機在圖片拍照和視頻錄制方面有很強大的功能典奉,小編認為如果很好使用 iPhone 拍攝出很好照片 & 錄制很有趣的視頻捶枢。本章將詳細講解 AVCaptureSession
肚医,并最后給出 FYCameraKit
項目Demo匙奴。
下面小編為大家講解 iOS 拍照和視頻錄制功能實現(xiàn)叙赚,下圖是鏡頭采集需要的類:
總體介紹
在整個鏡頭采集過程小編把整個過程比作我們常見發(fā)電過程:均是通過特定的步驟實現(xiàn)得到最后的產(chǎn)物怨咪。下面??做詳細解釋:
AVCaptureSession (發(fā)電機)
AVCaptureSession
:作為音視頻捕捉會話乏矾,把鏡頭和麥克風捕捉到的音視頻源輸出到設備中孟抗。
提示:可以有多個輸入和輸出。
AVCaptureDevice (發(fā)電設備)
AVCaptureDevice
:輸入設備钻心,包括:攝像頭和麥克風凄硼。可以通過設置一些參數(shù)來調(diào)節(jié)設備采集效果(例如:曝光捷沸,白平衡和聚焦等)摊沉。
AVCaptureInput (水風能源)
AVCaptureInput
:輸入數(shù)據(jù)管理對象,經(jīng)過 AVCaptureDevice 實現(xiàn)初始化痒给,然后添加到 AVCaptureSession (發(fā)電機) 中進行相應的輸出说墨。
子類:AVCaptureDeviceInput
骏全、AVCaptureScreenInput
和AVCaptureMetadataInput
。
AVCaptureOutput (電力)
AVCaptureOut
:數(shù)據(jù)輸出管理尼斧,通過 AVCaptureSession 中輸出姜贡。可以通過相關(guān)的協(xié)議實對應的數(shù)據(jù)輸出棺棵。
子類:AVCaptureFileOutput
鲁豪、AVCapturePhotoOutput
、AVCaptureStillImageOutput
律秃、AVCaptureVideoDataOutput
、AVCaptureAudioDataOutput
治唤、AVCaptureAudioPreviewOutput
棒动、AVCaptureDepthDataOutput
和AVCaptureMetadataOutput
。
AVCaptureVideoPreviewLayer (發(fā)電預覽)
AVCaptureVideoPreviewLayer
:可以支持在拍攝過程中進行相關(guān)的預覽宾添,只需要在初始時實現(xiàn)對應的 AVCaptureSession 即可船惨。
視頻錄制
下面展示在蘋果官方開發(fā)文檔給出的圖:
視頻錄制總概
- 創(chuàng)建
AVCaptureSession
對象 - 使用
AVCaptureDevice
靜態(tài)方法獲取設備常使用設備,例如:拍照和錄像需要的攝像頭缕陕,錄音所需的麥克風 - 利用輸入設備
AVCaptureDevice
初始化AVCaptureDeviceInput
對象 - 初始化輸出數(shù)據(jù)管理對象粱锐,拍照進行初始化
AVCaptureStillImageOutput
對象,拍照初始化AVCaptureMovieFileOutput
對象 - 將數(shù)據(jù)輸入對象
AVCaptureDeviceInput
和數(shù)據(jù)輸出對象AVCaptureDeviceOutput
添加到媒體會話管理對象AVCaptureSession
中 - 創(chuàng)建預覽的圖層
AVCaptureVideoPreviewLayer
指定媒體會話扛邑,添加圖層到容器怜浅,調(diào)用AVCaptureSession
中的StartRunning
方法開始捕捉 - 將捕捉到內(nèi)容保存到指定文件中
詳解鏡頭采集類
AVCaptureSession
小編查看 AVCaptureSession.h
文件看到,在鏡頭采集的過程中有兩種實現(xiàn)方式蔬崩。
- 使用系統(tǒng)
AVCaptureSession
自動配置輸入和輸出- 手動配置輸入和輸出之間的對應關(guān)系
(1) AVCaptureSession 初始化
- 使用
AVCaptureSession
自動配置輸入和輸出之間對應關(guān)系
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
[session beginConfiguration];
session.sessionPreset = AVCaptureSessionPresetPhoto;
if (audioInput) {
}else {
//// Handle the failure.
[session commitConfiguration];
}
if ([session canAddInput:audioInput]) {
[session addInput:audioInput];
}else {
// Handle the failure.
[session commitConfiguration];
}
上面代碼是 AVCaptureSession
進行初始化并且實現(xiàn)初始化麥克風進行相關(guān)音頻錄制恶座,并添加到 AVCaptureSession
中。
beginConfiguration
& commitConfiguration
在進行配置 AVCaptureSession
的相關(guān)屬性值時需要對這兩個函數(shù)調(diào)用沥阳,并且這兩個函數(shù)是成對出現(xiàn)跨琳。
- 手動配置
AVCaptureSession
輸入和輸出之間對應關(guān)系
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
NSError *error = nil;
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (!videoInput) {
//handle configuration video device
}
AVCaptureInputPort *videoPort = videoInput.ports[0];
error = nil;
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
if (!videoInput) {
//handle configuration audio device
}
AVCaptureInputPort *audioPort = audioInput.ports[0];
NSArray<AVCaptureInputPort *> *inputPorts = @[videoPort, audioPort];
AVCaptureVideoDataOutput *videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureConnection *connection = [AVCaptureConnection connectionWithInputPorts:inputPorts output:videoDataOutput];
if ([session canAddConnection:connection]) {
[session addConnection:connection];
}else {
//handle session can not add AVCaptureConnection
[session commitConfiguration];
return;
}
[session commitConfiguration];
上面??代碼是使用 AVCaptureConnection
實現(xiàn)在 AVCaptureSession
使輸入和輸出進行自己配置。
詳細的細節(jié)會在 FYCameraKit
進行詳細的講解桐罕。
注釋:
1)只有在調(diào)用beginConfiguration
時我們對AVCaptureSession
配置才會被真正開始修改脉让。
(2) AVCaptureSession 中斷
在音視頻錄制過程中可能對因為電話導致中斷,開發(fā)過程中提供中斷結(jié)束后獲取中斷產(chǎn)生的原因功炮。
- 注冊中斷監(jiān)聽 & 刪除監(jiān)聽
//監(jiān)聽注冊
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCaptureSession:) name:AVCaptureSessionInterruptionEndedNotification object:_session];
//監(jiān)聽清除
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionInterruptionEndedNotification object:_session];
- 從傳遞的
userInfo
通過關(guān)鍵key
獲取原因:
AVCaptureSessionInterruptionReasonKey
- 獲取具體的中斷原因:
typedef NS_ENUM(NSInteger, AVCaptureSessionInterruptionReason) {
AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground = 1,//從后臺運行開啟 camera溅潜,不夠 iOS 9.0 之后不提供中斷
AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient = 2,//音頻軟軟件被占用
AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient = 3,//視頻軟件被占用
AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps = 4,//全屏或者是錄制屏幕變化
}
- 監(jiān)聽事件的處理
- (void)handleCaptureSession:(NSNotification *)notification {
AVCaptureSessionInterruptionReason reason = [[notification.userInfo objectForKey:AVCaptureSessionInterruptionReasonKey] unsignedIntegerValue];
switch (reason) {
case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground:
{
//handle device not available background
break;
}
case AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient:
{
//handle that audio was occupied
break;
}
case AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient:
{
//handle that video was occupied
break;
}
case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps:
{
//handle that UI was multiple
break;
}
}
}
實現(xiàn)拍照和視頻錄制的 FYCameraKit
的下載地址: FYCameraKit
最后給出 AVFoundation
API
的總結(jié):
參考資料:
AVCaptureSession
AVCaptureDevice
AVCaptureConnection
第一次發(fā)布:2017/8/10 20:49:21 星期四
第二次發(fā)布:2017/8/10 23:36:34 星期四