iOS开发 AVFoundation 自定义视频录制

本文详细介绍如何使用AVFoundation在iOS上实现视频录制功能,包括界面绘制、相机硬件初始化、录制流程控制及权限处理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

导入几个头文件和遵守几个协议 #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、文章有什么问题请留言指出,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值