ios 相机 录视频和拍照的封装 保存到相册
来源:互联网 发布:阿里云主机备案 编辑:程序博客网 时间:2024/05/29 19:04
使用:
@interface ViewController ()@property (nonatomic, strong) CameraTool *videoTool;@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相机拍摄预览图层@end@implementation ViewController- (CameraTool *)videoTool { if(!_videoTool) { _videoTool = [[CameraTool alloc]init]; } return _videoTool;}-(void)viewDidLoad { [super viewDidLoad]; self.captureVideoPreviewLayer = [self.videoTool previewLayer]; CALayer *layer=self.view.layer; layer.masksToBounds=YES; self.captureVideoPreviewLayer.frame = layer.bounds; [layer addSublayer:self.captureVideoPreviewLayer]; [self.videoTool startRecordFunction];}
主要代码:
CameraTool.h
#import <Foundation/Foundation.h>#import <AVFoundation/AVFoundation.h>typedef void(^Block)(NSData *data);//回调照片流@interface CameraTool : NSObject@property (strong, nonatomic) NSString *videoPath;//视频路径//捕获到的视频呈现的layer- (AVCaptureVideoPreviewLayer *)previewLayer;//启动录制功能- (void)startRecordFunction;//关闭录制功能- (void)stopRecordFunction;//开始录制- (void) startCapture;//停止录制- (void) stopCapture;//拍照- (void)shutterCamera:(Block)block;//开启闪光灯- (void)openFlashLight;//关闭闪光灯- (void)closeFlashLight;//切换前后置摄像头- (void)changeCameraInputDeviceisFront:(BOOL)isFront;-(void)saveAllVideoToPoto;//保存视频到相册-(void)deleteAllVideo;//删除所有视频@end
CameraTool.m
#import "CameraTool.h"#import <AssetsLibrary/AssetsLibrary.h>#import <Photos/Photos.h>@interface CameraTool() <AVCaptureFileOutputRecordingDelegate>@property (strong, nonatomic) AVCaptureSession *captureSession; //负责输入和输出设备之间的连接会话,数据流的管理控制@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;//捕获到的视频呈现的layer@property (strong, nonatomic) AVCaptureDeviceInput *backCameraInput;//后置摄像头输入@property (strong, nonatomic) AVCaptureDeviceInput *frontCameraInput;//前置摄像头输入@property (strong, nonatomic) AVCaptureDeviceInput *audioMicInput;//麦克风输入@property (strong, nonatomic) AVCaptureConnection *videoConnection;//视频录制连接@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;//视频输出流@property (nonatomic, strong)AVCaptureStillImageOutput *stillImageOutput;//照片输出流对象@end@implementation CameraTool#pragma mark -API//启动录制功能- (void)startRecordFunction{ [self.captureSession startRunning];}//关闭录制功能- (void)stopRecordFunction{ if(self.captureSession) [self.captureSession stopRunning];}//开始录制- (void)startCapture{ if(self.captureMovieFileOutput.isRecording) return; NSString *defultPath = [self getVideoPathCache]; NSString *outputFielPath=[defultPath stringByAppendingPathComponent:[self getVideoNameWithType:@"mp4"]]; NSLog(@"save path is :%@",outputFielPath); NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath]; //设置录制视频流输出的路径 [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self]; }//停止录制- (void) stopCapture{ if ([self.captureMovieFileOutput isRecording]) { [self.captureMovieFileOutput stopRecording];//停止录制 }}// 这是拍照按钮的方法- (void)shutterCamera:(Block)block{ AVCaptureConnection *videoConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; if (!videoConnection) { NSLog(@"空"); return; } [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { if (imageDataSampleBuffer == NULL) { return; } NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; block(imageData); UIImage *image = [UIImage imageWithData:imageData]; [self SavedPhoto:image]; NSLog(@"image size = %@", NSStringFromCGSize(image.size)); }];}//保存图片到相册- (void)SavedPhoto:(UIImage *)image{ UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), (__bridge void *)self);}- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ NSLog(@"image = %@, error = %@, contextInfo = %@", image, error, contextInfo);}//开启闪光灯- (void)openFlashLight{ //改变会话的配置前一定要先开启配置,配置完成后提交配置改变 //[self stopRecordFunction]; [self.captureSession beginConfiguration]; AVCaptureDevice *backCamera = [self backCamera]; if (backCamera.torchMode == AVCaptureTorchModeOff) { [backCamera lockForConfiguration:nil]; backCamera.torchMode = AVCaptureTorchModeOn; backCamera.flashMode = AVCaptureFlashModeOn; [backCamera unlockForConfiguration]; } //提交会话配置 [self.captureSession commitConfiguration]; [self startRecordFunction];}//关闭闪光灯- (void)closeFlashLight{ //改变会话的配置前一定要先开启配置,配置完成后提交配置改变 // [self stopRecordFunction]; [self.captureSession beginConfiguration]; AVCaptureDevice *backCamera = [self backCamera]; if (backCamera.torchMode == AVCaptureTorchModeOn) { [backCamera lockForConfiguration:nil]; backCamera.torchMode = AVCaptureTorchModeOff; backCamera.flashMode = AVCaptureTorchModeOff; [backCamera unlockForConfiguration]; } //提交会话配置 [self.captureSession commitConfiguration]; [self startRecordFunction];}//切换前后置摄像头- (void)changeCameraInputDeviceisFront:(BOOL)isFront { //改变会话的配置前一定要先开启配置,配置完成后提交配置改变 [self stopRecordFunction]; [self.captureSession beginConfiguration]; if (isFront) { [self.captureSession removeInput:self.backCameraInput]; if ([self.captureSession canAddInput:self.frontCameraInput]) { //[self changeCameraAnimation]; [self.captureSession addInput:self.frontCameraInput]; } }else { [self.captureSession removeInput:self.frontCameraInput]; if ([self.captureSession canAddInput:self.backCameraInput]) { //[self changeCameraAnimation]; [self.captureSession addInput:self.backCameraInput]; } } //提交会话配置 [self.captureSession commitConfiguration]; [self startRecordFunction];}#pragma mark - 视频输出代理-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{ NSLog(@"开始录制...");}-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{ NSLog(@"视频录制完成."); [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]; [self startCapture]; //视频录入完成之后在后台将视频存储到相// [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{// [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];// } completionHandler:^(BOOL success, NSError * _Nullable error) {// if (error) {// NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription);// }else {// NSLog(@"成功保存视频到相簿.");// }// }]; }-(void)saveAllVideoToPoto { NSArray *arr = [self getAllFile]; for (NSString *str in arr) { NSURL *fileUrl=[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@",[self getVideoPathCache],str]]; [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:fileUrl]; } completionHandler:^(BOOL success, NSError * _Nullable error) { if (error) { NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription); }else { NSLog(@"成功保存视频到相簿."); } }]; }}-(void)deleteAllVideo { NSArray *arr = [self getAllFile]; for (NSString *str in arr) { NSString *file = [NSString stringWithFormat:@"%@/%@",[self getVideoPathCache],str]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL is = [fileManager removeItemAtPath:file error:nil]; if (!is) { NSLog(@"删除文件错误"); } } }#pragma mark - 视频地址- (NSString *)getVideoPathCache{ NSString *videoCache = [NSTemporaryDirectory() stringByAppendingPathComponent:@"videos"] ; BOOL isDir = NO; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL existed = [fileManager fileExistsAtPath:videoCache isDirectory:&isDir]; if ( !(isDir == YES && existed == YES) ) { [fileManager createDirectoryAtPath:videoCache withIntermediateDirectories:YES attributes:nil error:nil]; }; return videoCache;}- (NSString *)getVideoNameWithType:(NSString *)fileType { NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"HHmmss"]; NSDate * NowDate = [NSDate dateWithTimeIntervalSince1970:now]; ; NSString * timeStr = [formatter stringFromDate:NowDate]; NSString *fileName = [NSString stringWithFormat:@"video_%@.%@",timeStr,fileType]; return fileName;}-(NSArray *)getAllFile { NSArray *files = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[self getVideoPathCache] error:nil]; return files;}#pragma mark - Device init Method//捕获到的视频呈现的layer- (AVCaptureVideoPreviewLayer *)previewLayer { if (_previewLayer == nil) { //通过AVCaptureSession初始化 AVCaptureVideoPreviewLayer *preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; //设置比例为铺满全屏 preview.videoGravity = AVLayerVideoGravityResizeAspectFill; _previewLayer = preview; } return _previewLayer;}//捕获视频的会话- (AVCaptureSession *)captureSession{ if(_captureSession == nil) { _captureSession = [[AVCaptureSession alloc] init]; //设置分辨率 if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) { _captureSession.sessionPreset=AVCaptureSessionPreset1280x720; } //添加后置摄像头的输入 if ([_captureSession canAddInput:self.backCameraInput]) { [_captureSession addInput:self.backCameraInput]; } //添加后置麦克风的输入 if ([_captureSession canAddInput:self.audioMicInput]) { [_captureSession addInput:self.audioMicInput]; } //将设备输出添加到会话中 if ([_captureSession canAddOutput:self.captureMovieFileOutput]) { [_captureSession addOutput:self.captureMovieFileOutput]; } //照片输出流 if ([_captureSession canAddOutput:self.stillImageOutput]) { [_captureSession addOutput:self.stillImageOutput]; } //设置视频录制的方向 self.videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait; } return _captureSession;}//后置摄像头输入- (AVCaptureDeviceInput *)backCameraInput { if (_backCameraInput == nil) { NSError *error; _backCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backCamera] error:&error]; if (error) { NSLog(@"获取后置摄像头失败~%d",[self isAvailableWithCamera]); } } return _backCameraInput;}//前置摄像头输入- (AVCaptureDeviceInput *)frontCameraInput { if (_frontCameraInput == nil) { NSError *error; _frontCameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontCamera] error:&error]; if (error) { NSLog(@"获取前置摄像头失败~"); } } return _frontCameraInput;}//麦克风输入- (AVCaptureDeviceInput *)audioMicInput { if (_audioMicInput == nil) { AVCaptureDevice *mic = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; NSError *error; _audioMicInput = [AVCaptureDeviceInput deviceInputWithDevice:mic error:&error]; if (error) { NSLog(@"获取麦克风失败~%d",[self isAvailableWithMic]); } } return _audioMicInput;}//照片输出流-(AVCaptureStillImageOutput *)stillImageOutput { if (!_stillImageOutput) { _stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; // 这是输出流的设置参数AVVideoCodecJPEG参数表示以JPEG的图片格式输出图片 NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil]; [_stillImageOutput setOutputSettings:outputSettings]; } return _stillImageOutput;}//初始化设备输出对象,用于获得输出数据- (AVCaptureMovieFileOutput *)captureMovieFileOutput{ if(_captureMovieFileOutput == nil) { _captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc]init]; } return _captureMovieFileOutput;}//视频连接- (AVCaptureConnection *)videoConnection { _videoConnection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; if ([_videoConnection isVideoStabilizationSupported ]) { _videoConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto; } return _videoConnection;}//返回前置摄像头- (AVCaptureDevice *)frontCamera { return [self cameraWithPosition:AVCaptureDevicePositionFront];}//返回后置摄像头- (AVCaptureDevice *)backCamera { return [self cameraWithPosition:AVCaptureDevicePositionBack];}//用来返回是前置摄像头还是后置摄像头- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position { //返回和视频录制相关的所有默认设备 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; //遍历这些设备返回跟position相关的设备 for (AVCaptureDevice *device in devices) { if ([device position] == position) { return device; } } return nil;}@end@implementation CameraTool(Authorization)- (BOOL)isAvailableWithCamera{ return [self isAvailableWithDeviveMediaType:AVMediaTypeVideo];}- (BOOL)isAvailableWithMic{ return [self isAvailableWithDeviveMediaType:AVMediaTypeAudio];}- (BOOL)isAvailableWithDeviveMediaType:(NSString *)mediaType{ AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if(status == ALAuthorizationStatusDenied||status == ALAuthorizationStatusRestricted) return NO; else return YES;}@end
阅读全文
0 0
- ios 相机 录视频和拍照的封装 保存到相册
- iOS之打开照相机拍照或者录像/打开手机的相册或者视频/视频压缩/自定义相机界面/照片或视频保存到相册
- IOS 永久保存相册或相机拍照的图片
- iOS从相册选择视频和保存视频到相册
- 调用系统相机拍照,并且保存到系统相册的一般套路
- 调用系统相机拍照,并且保存到系统相册一般的方法
- iOS 打开相册,保存图片到相册,打开相机
- IOS拍照---》保存到相册----》并且获取照片的ALasset传到相册
- iOS访问相册以及拍照保存至相册的实现
- 拍照并保存到本地相册中 ios
- iOS调用相机和相册 并编辑保存到本地(个人中心设置头像)
- Unity 截屏 录屏 并且保存到 iOS相册
- 保存照片和视频到相册显示
- 开启相机拍照并获取与到照片已经保存到相册中
- 保存图片到【相机胶卷】和【自定义相册】
- iOS 拍照和相册获取照片封装UIImagePickerController
- 【Ios】 Unity for iOS 打开相册、相机及保存图片到相册
- 调用系统相机拍照片保存到指定的路径
- git stash和git stash pop
- QT模块的介绍
- centOS7安装MySQL
- SpringMVC前台验证码刷新方式
- C的二维数组理解指针以及存储的方式
- ios 相机 录视频和拍照的封装 保存到相册
- solr 拼音检索
- artTemplate的使用总结
- 点击率预测算法:FTRL
- Vue.js和MVVM小细节
- 有兴趣的进来
- 将微信公众号的文章保存到本地pdf
- 阿里云创建E-MapReduce 1 快速开始
- Android espresso-web等待网页元素方法