博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发 AVFoundation 自定义视频录制
阅读量:6447 次
发布时间:2019-06-23

本文共 5181 字,大约阅读时间需要 17 分钟。

最近一顿疯狂加班啊,年前一顿加,写了好几个版本的更新。然而到现在都没有上线,真蛋疼。

回归正题啊,通过学习本章的内容,你将学会本章内容。

##一 、第一步当然还是绘制一个界面,很简单一个view 一个录制按钮

导入几个头文件和遵守几个协议 #import <AVFoundation/AVFoundation.h> #import "RAFileManager.h" //这是个操作文件的工具类 不多做介绍 #import <AssetsLibrary/AssetsLibrary.h> //这货iOS8过期了。。。 PHPhoto看起来比这个好用多了

遵守一个协议

//这玩意必须遵守不然拿不到视频哦复制代码

##二、初始化相机硬件等 这个步骤跟拍照的步骤大部分是一样的,两处区别 : ####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;

什么?这些属性都是干啥的?猛戳这里--->

之后初始化相机,连接硬件和软件。

- (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、硬件之间关系介绍戳这里 ######2、文章演示demo戳这里 ######文章演示demo戳这里 ######文章演示demo戳这里 重要的事情还是要说三遍,虽然写的不怎么样,如果你们要用还是希望能仔细看一看,别上来就私聊 留言要demo。

######3、要转载的看官们也不要问了,注明出处就行了。随便转。 ######4、文章有什么问题请留言指出,欢迎交流。

你可能感兴趣的文章
mssqll2008下只显示相关的登陆操作
查看>>
网站物理路径查找思路
查看>>
App引流增长技术:Deeplink(深度链接)技术
查看>>
赠云风大侠
查看>>
thinkphp留言板开发笔记 1 - 新的
查看>>
DEDECMS中,引入文件
查看>>
运维mysql基础
查看>>
初入前端9
查看>>
animation动画
查看>>
Ubuntu下系统自带截图设置
查看>>
solr6.6初探之查询篇
查看>>
Qt程序打包成exe可执行文件
查看>>
MongoDB基础之 安装
查看>>
Django model进阶
查看>>
mysql基本语法
查看>>
计算机组成原理学习笔记:1.计算机系统概论
查看>>
在linux下,查看一个运行中的程序, 占用了多少内存
查看>>
Git-实验报告
查看>>
Qt基本应用
查看>>
Hello World!
查看>>