使用AVFoundation拍照和錄制視頻
需要開發自定義的拍照和錄制視頻功能,可借助於AVFoundation框架來實現,該框架提供了大量的類來完成拍照和錄制視頻.主要使用如下類:
AVCaptureDevice:該對象代表物理輸入設備,包括攝像頭和麥克風.開發者可通過該對象來配置底層物理設備的屬性.需要指出的是,
我們不能直接創建該類的實例,只能通過該類的devices、defaultDeviceWithMediaType:(NSString *)mediaType、
devicesWithMediaType:(NSString *)mediaType方法來獲取對應的輸入設備數組,接下來即可獲取前置攝像頭、后置攝像頭或麥克風,
程序就可設置該對象的對焦模式、閃光燈模式、曝光補償、白平衡等各種拍照相關屬性。
注意:
在配置攝像頭的相關屬性之前,必須先調用lockForConfiguration:方法執行鎖定,配置完成后調用unlockForConfiguration方法解鎖。
AVCaptureSession:該對象負責把AVCaptureDevice捕捉得到的視頻或聲音數據輸出到輸出設備中.不管執行實時的還是離線的錄制,開發者都必須創建AVCaptureSession對象,並為該對象添加輸入設備(負責捕捉數據)和輸出端(負責接收數據).例如如下代碼片段
代 碼 片 段 |
![]() |
AVCaptureDeviceInput[BL2] :它是AVCaptureInput的子類,使用該對象從AVCaptureDevice設備獲取數據,該對象將會被添加給AVCaptureSession管理.
AVCaptureScreenInput[BL3] :它是AVCaptureInput的子類,使用該對象從屏幕獲取數據(用於錄制屏幕動作).該對象將會被添加給AVCaptureSeesion管理
AVCaptureAudioDataOutput、AVCaptureAudioPreviewOutput、AVCaptureFileOutput[BL4] 、AVCaptureStillImageOutput、AVCaptureVideoDataOutput:它們都是AVCaptureOutput的子類,用於接收各種數據.該對象也會被添加給AVCaptureSession管理.其中AVCaptureFileOutput依然代表輸出到文件的輸出端,
AVCaptureAudioFileOutput[BL5] 、AVCaptureMovieFileOutput[BL6] :它們都是AVCaptureFileOutput的子類,分別代表輸出到音頻文件、電影文件的輸出端。
AVCaptureVideoPreviewLayer:該對象是CALayer的子類,開發者只要創建它的實例,並為它設置AVCaptureSession,就可以非常方便地用它來實現拍攝預覽.
代 碼 片 段 |
![]() |
使用AVFoundation實現拍照和錄制視頻的大致步驟如下
1 |
使用AVCaptureDevice的靜態方法獲取設備,包括攝像頭和麥克風都可通過這種方式來獲取 |
2 |
利用AVCaptureDevice初始化AVCaptureDeviceInput對象,無論攝像頭還是麥克風都可通過這種方式轉換為AVCaptureInput對象 |
3 |
初始化輸出端.如果只是拍照,則初始化AVCaptureStillImageOutput輸出端即可;如果要捕捉視頻,則初始化AVCaptureMovieFileOutput輸出端. |
4 |
創建AVCaptureSession對象,使用該對象來添加輸入設備和輸出端.調用AVCaptureSession的startRunning方法開始捕捉畫面或聲音數據. |
5 |
將捕捉的數據(照片、視頻數據)輸出到指定文件。 |
框架 |
AVFoundation.framework框架,AssetsLibrary.framework,CoreMedia.framework框架 |
使用AVFoundation生成視頻縮略圖
AVFoundation可用來生成視頻縮略圖.
AVFoundation生成視頻縮略圖主要靠如下兩個類.
AVURLAsset |
該類是AVAsset的子類,AVAsset類專門用於獲取多媒體的相關信息,包括獲取多媒體的畫面、聲音等信息。而AVURLAsset子類的作用則是根據NSURL來初始化AVAsset對象。 |
AVAssetImageGenerator[BL7] |
該類專門用於截取視頻指定幀的畫面。 |
使用AVFoundation生成視頻縮略圖的步驟如下:
1 |
根據視頻的NSURL創建AVURLAsset對象 |
2 |
根據AVURLAsset對象創建AVAssetImageGenerator對象 |
3 |
調用AVAssetImageGenerator對象的copyCGImageAtTime:actualTime:error:方法來獲取該視頻指定時間點的視頻截圖.該方法的第一個CMTime參數用於指定獲取哪個時間點的視頻截圖,第2個CMTime參數用於獲取實際截圖 位於哪個時間點. 其中CMTime是專門用於標識電影時間的結構體,通常用如下兩個函數來創建CMTime. CMTimeMake(int64_t value, int_32 timescale): 第1個參數代表獲取第幾幀的截圖,第2個參數代表每秒的幀數.因此實際截取的時間點是value/timescale. CMTimeMakeWithSeconds(Float64 seconds, int32_t preferredTimeScale): 第1個參數代表獲取第幾秒的截圖,第2個參數則代表每秒的幀數. |
代碼片段 |
// 為增加UIImage增加一個類別,通過在該類別中為UIImage增加一個imageWithVideo:方法來獲取視頻的縮略圖 // UIImage + Video.m @implementation UIImage (Video) + (UIImage *)imageWithVideo:(NSURL *)vidoURL { // 根據視頻的URL創建AVURLAsset AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil]; // 根據AVURLAsset創建AVAssetImageGenerator對象 AVAssetImageGenerator* gen = [[AVAssetImageGenerator alloc] initWithAsset: asset]; gen.appliesPreferredTrackTransform = YES; // 定義獲取0幀處的視頻截圖 CMTime time = CMTimeMake(0, 10); NSError *error = nil; CMTime actualTime; // 獲取time處的視頻截圖 CGImageRef image = [gen copyCGImageAtTime: time actualTime: &actualTime error:&error]; // 將CGImageRef轉換為UIImage UIImage *thumb = [[UIImage alloc] initWithCGImage: image]; CGImageRelease(image); return thumb; } @end ViewController.m @interface ViewController: UIViewController @property (nonatomic, strong) UIImageView *iv; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 獲取URL NSURL *videoUrl = [[NSBundle mainBundle] URLForResource:@”movie” withExtension:@”mp4”]; // 生成視頻的縮略圖 UIImage *image = [UIImage imageWithVideo:videoUrl]; self.iv.image = image; } @end
|