![圖片來自網路](https://i.iter01.com/images/afcf423f70a3e5e041ddfa398a58eb12344de9b324d6c9a88e902b19868cd9de.png)
最近一頓瘋狂加班啊,年前一頓加,寫了好幾個版本的更新。然而到現在都沒有上線,真蛋疼。
迴歸正題啊,通過學習本章的內容,你將學會本章內容。
##一 、第一步當然還是繪製一個介面,很簡單一個view 一個錄製按鈕
![18禁](https://i.iter01.com/images/992a444e7a3863b1c6236e9552201a6603c151a9399e8d5bc90edaad5f9ebe7c.png)
匯入幾個標頭檔案和遵守幾個協議 #import <AVFoundation/AVFoundation.h> #import "RAFileManager.h" //這是個操作檔案的工具類 不多做介紹 #import <AssetsLibrary/AssetsLibrary.h> //這貨iOS8過期了。。。 PHPhoto看起來比這個好用多了
遵守一個協議
<AVCaptureFileOutputRecordingDelegate> //這玩意必須遵守不然拿不到視訊哦
複製程式碼
##二、初始化相機硬體等 這個步驟跟拍照的步驟大部分是一樣的,兩處區別 : ####1、輸出不一樣:拍照部分用的是AVCaptureStillImageOutput,視訊錄製需要的是AVCaptureMovieFileOutput ####2、輸入硬體不一樣:拍照只需要攝像頭捕捉影像的輸入,視訊錄製的話還需要一個音訊的輸入(畢竟我們們這AV是有聲的哈)。
建立如下屬性
@property (nonatomic) dispatch_queue_t sessionQueue;
/**
複製程式碼
* AVCaptureSession物件來執行輸入裝置和輸出裝置之間的資料傳遞 / @property (nonatomic, strong) AVCaptureSession session; /** * 視訊輸入裝置 / @property (nonatomic, strong) AVCaptureDeviceInput videoInput; /** * 聲音輸入 / @property (nonatomic, strong) AVCaptureDeviceInput audioInput; /** * 視訊輸出流 / @property(nonatomic,strong)AVCaptureMovieFileOutput movieFileOutput; / * 預覽圖層 / @property (nonatomic, strong) AVCaptureVideoPreviewLayer previewLayer; /** * 記錄錄製時間 / @property (nonatomic, strong) NSTimer timer;
什麼?這些屬性都是幹啥的?猛戳這裡--->AVFoundation自定義相機
之後初始化相機,連線硬體和軟體。
- (void)initAVCaptureSession{
複製程式碼
self.session = [[AVCaptureSession alloc] init]; //這裡根據需要設定 可以設定4K self.session.sessionPreset = AVCaptureSessionPreset1280x720; NSError *error; AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //更改這個設定的時候必須先鎖定裝置,修改完後再解鎖,否則崩潰 [device lockForConfiguration:nil]; //設定閃光燈為自動 [device setFlashMode:AVCaptureFlashModeAuto]; [device unlockForConfiguration]; self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error]; self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio] error:nil]; if (error) { NSLog(@"%@",error); }
self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
if ([self.session canAddInput:self.videoInput]) {
[self.session addInput:self.videoInput];
}
if ([self.session canAddInput:self.audioInput]) {
[self.session addInput:self.audioInput];
}
if ([self.session canAddOutput:self.movieFileOutput]) {
[self.session addOutput:self.movieFileOutput];
}
//初始化預覽圖層
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
self.previewLayer.frame = CGRectMake(0, 0,KMainScreenW, KMainScreenH);
self.backView.layer.masksToBounds = YES;
[self.backView.layer insertSublayer:self.previewLayer atIndex:0];
}
記得在viewDidLoad裡面呼叫一下。viewWillAppear裡面開啟session ,viewWillDisappear裡面關閉session
相機開啟了一定要關閉,相機開啟了一定要關閉,相機開啟了一定要關閉,重要的事情說三遍
##三、開啟錄製方法和結束錄製方法 - (void)startVideoRecorder{ AVCaptureConnection *movieConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo]; AVCaptureVideoOrientation avcaptureOrientation = AVCaptureVideoOrientationPortrait; [movieConnection setVideoOrientation:avcaptureOrientation]; [movieConnection setVideoScaleAndCropFactor:1.0]; NSURL *url = [[RAFileManager defaultManager] filePathUrlWithUrl:[self getVideoSaveFilePathString]];
if (![self.movieFileOutput isRecording]) { [self.movieFileOutput startRecordingToOutputFileURL:url recordingDelegate:self];
}
}
- (void)stopVideoRecorder{
複製程式碼
if ([self.movieFileOutput isRecording]) {
複製程式碼
[self.movieFileOutput stopRecording];
}
}
##四、最後寫個按鈕點選開始錄製呼叫上面方法就好並且實現delegate。注意判斷是否有使用相機,麥克風的許可權。如果沒有許可權,你還剛好沒判斷。。。那麼恭喜你。。崩潰了。
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
//判斷最小時間的哈
複製程式碼
if (CMTimeGetSeconds(captureOutput.recordedDuration) < VIDEO_RECORDER_MIN_TIME) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"視訊時間過短" message:nil delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil]; [alert show]; return; } NSLog(@"%s-- url = %@ ,recode = %f , int %lld kb", func, outputFileURL, CMTimeGetSeconds(captureOutput.recordedDuration), captureOutput.recordedFileSize / 1024); ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init]; [lib writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) { }]; }
向相簿寫入視訊的時候也要注意許可權。
######DLC:
獲取視訊截圖的方法
- (UIImage *)videoSnap:(NSString *)videoPath{
複製程式碼
NSURL *url = [NSURL fileURLWithPath:videoPath]; AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; CMTime snaptime = CMTimeMake(10, 10); CMTime time2; CGImageRef cgImageRef = [generator copyCGImageAtTime:snaptime actualTime:&time2 error:nil]; UIImage *tempImage = [UIImage imageWithCGImage:cgImageRef]; //這裡取完圖片記得搞下圖片的方向,在這裡我就不寫了。 return tempImage; }
這個方法第一個時間是指的圖片建立的時間, 第二個actualTime 是指向圖片正式生成時間的指標,實際生成時間這個引數可以傳NULL,如果你不關心它是什麼時候誕生的。 但是第一個時間不能傳入空,必須告訴它你要在哪一個時間點生成一張截圖 - (nullable CGImageRef)copyCGImageAtTime:(CMTime)requestedTime actualTime:(nullable CMTime *)actualTime error:(NSError * __nullable * __nullable)outError CF_RETURNS_RETAINED;
獲取到截圖之後記得處理下方向。
最後: ######1、硬體之間關係介紹戳這裡AVFoundation自定義相機 ######2、文章演示demo戳這裡 AVFoundation自定義視訊錄製demo ######文章演示demo戳這裡 AVFoundation自定義視訊錄製demo ######文章演示demo戳這裡 AVFoundation自定義視訊錄製demo 重要的事情還是要說三遍,雖然寫的不怎麼樣,如果你們要用還是希望能仔細看一看,別上來就私聊 留言要demo。
######3、要轉載的看官們也不要問了,註明出處就行了。隨便轉。 ######4、文章有什麼問題請留言指出,歡迎交流。