用AVFoudation進(jìn)行視頻錄制相對UIImagePickerController來說復(fù)雜,涉及到的相關(guān)類也更多,打個比喻,就是我想在要用積木搭房子,但是我現(xiàn)在只有一堆非常零碎的零件來進(jìn)行組裝。如下,要進(jìn)行視頻錄制并且保存我總結(jié)了一個相關(guān)步驟。
第一步:導(dǎo)入相關(guān)的頭文件
#import <AVFoundation/AVFoundation.h>第二步:創(chuàng)建
session會話對象,并且設(shè)置捕獲質(zhì)量第三步:創(chuàng)建對應(yīng)媒體類型的
device對象和deviceInput對象第四步:將對應(yīng)的
input對象添加進(jìn)入session中第五步:創(chuàng)建文件輸出對象
AVCaptureMovieFileOutput,并且將該對象添加進(jìn)session中的output中。
至此,設(shè)備初始化的工作完成。
第六步:根據(jù)
session創(chuàng)建AVCaptureVideoPreviewLayer層,并且設(shè)置好frame第七步:將創(chuàng)建好的
layer添加到相應(yīng)的view上去。此時session調(diào)用startRunning,就能將攝像頭捕捉到的影像在layer中顯示。第八步:定義好
fileurl用作存儲錄制視頻的路徑。fileURLWithPath:記住一定是用這個方法創(chuàng)建的url。否者會異常。第九步:
AVCaptureMovieFileOutput的實例調(diào)用startRecordingToOutputFileURL:recordingDelegate:方法開始講攝像頭捕捉的視頻保存進(jìn)之前設(shè)定好的fielurl
代碼:
- 首先定義session和output
@property (nonatomic,strong) AVCaptureSession *session;
@property (nonatomic,strong) AVCaptureMovieFileOutput *output;
- 然后實現(xiàn)對應(yīng)方法:
self.session = [[AVCaptureSession alloc]init];
//設(shè)置捕獲視頻的質(zhì)量
self.session.sessionPreset = AVCaptureSessionPresetHigh;
NSError *error;
//指定媒體類型為 視頻 。獲得捕獲設(shè)備AVCaptureDevice對象。
AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//實例化捕獲輸入AVCaptureDeviceInput(視頻)對象,通過對應(yīng)的device對象實例化。
AVCaptureDeviceInput *camera = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&error];
//指定媒體類型為 音頻 。獲得捕獲設(shè)備AVCaptureDevice對象。
AVCaptureDevice *micDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
//實例化捕獲輸入AVCaptureDeviceInput(音頻)對象,通過對應(yīng)的device對象實例化。
AVCaptureDeviceInput *mic = [AVCaptureDeviceInput deviceInputWithDevice:micDevice error:&error];
/*
當(dāng)前獲得了兩個輸入對象,一個是camera設(shè)備,一個是mic設(shè)備
*/
[self.session addInput:camera];
[self.session addInput:mic];
//創(chuàng)建文件輸出對象
self.output = [[AVCaptureMovieFileOutput alloc]init];
if ([self.session canAddOutput:self.output]) {
[self.session addOutput:self.output];
}
//創(chuàng)建layer層對象,參數(shù)是captureSession。并且設(shè)置layer的frame。然后天驕到相應(yīng)的view上
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
previewLayer.frame = CGRectMake(0, 0, 375.0, 375.0*16/9);
[self.view.layer insertSublayer:previewLayer atIndex:0];
[self.session startRunning];
到此為止,當(dāng)前界面的view上能輸出攝像頭捕捉到的數(shù)據(jù)。
- 接著定義好fileUrl:
-(NSURL *)fileUrl
{
NSString *outputPath = [NSString stringWithFormat:@"%@%@",NSTemporaryDirectory(),@"myvideo.mov"];
NSURL *urlPath = [NSURL fileURLWithPath:outputPath];//[NSURL URLWithString:outputPath];
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:outputPath]) {
NSError *error;
[manager removeItemAtPath:outputPath error:&error];
}
return urlPath;
}
然后調(diào)用下述方法開始講捕捉到的數(shù)據(jù)保存進(jìn)上述的fileurl中:
[self.output startRecordingToOutputFileURL:fileUrl recordingDelegate:self];設(shè)置此方法后,系統(tǒng)會持續(xù)的將捕捉到的視頻緩存起來,在通過調(diào)用:
[self.output stopRecording];
結(jié)束視頻的錄制,此時會調(diào)用下述代理方法
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error;在這個代理方法內(nèi)部實現(xiàn)保存的方法:
if (error == nil) {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(@"%@",assetURL.absoluteString);
if (error) {
NSLog(@"%@",error.localizedDescription);
}
}];
}