-
使用原生相机 UIImagePickerController 来录制
一、准备
1.添加依赖库AVFoundation.framework
2.导入头文件
3.添加成员变量:
{
//视频录制
UIImagePickerController *_picker;
//拍摄视频资源控制符
NSURL *_movieUrl;
//保存到本地资源控制符
NSURL *_locoaUrl;
//视频播放
AVPlayer *player;
}
4.设置权限
麦克风权限:Privacy - Microphone Usage Description 是否允许此App使用你的麦克风
相机权限: Privacy - Camera Usage Description 是否允许此App使用你的相机?
相册权限: Privacy - Photo Library Usage Description 是否允许此App访问你的媒体资料库?
通讯录权限:
Privacy - Contacts Usage Description 是否允许此App访问你的通讯录?
蓝牙权限:Privacy - Bluetooth Peripheral Usage Description 是否许允此App使用蓝牙?
语音转文字权限:Privacy - Speech Recognition Usage Description 是否允许此App使用语音识别?
日历权限:Privacy - Calendars Usage Description 是否允许此App使用日历?
定位权限:Privacy - Location When In Use Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据
后台定位权限: Privacy - Location Always Usage Description 我们需要通过您的地理位置信息获取您周边的相关数据定位的需要这么写,防止上架被拒。
二、代码:
/**
**
****点击按钮开始录制
** @param sender <#sender description#> */
- (IBAction)startPicker:(id)sender {
//初始化 UIImagePickerController
_picker = [[UIImagePickerController alloc]init];
_picker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//来源为摄像头
_picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// 重点 是设置媒体类型为视频 电影 类型为数组
_picker.mediaTypes = @[(NSString*)kUTTypeMovie];
//设置为录制模式
_picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
//下面为默认设置
//录制时间
_picker.videoMaximumDuration = 10;
//质量
_picker.videoQuality = UIImagePickerControllerQualityTypeIFrame960x540;
//显示摄像头控制面板 设置为NO 使用cameraOverlayView 自定义界面
_picker.showsCameraControls = YES;
// picker.cameraOverlayView 摄像头上覆盖的视图,可用通过这个视频来自定义拍照或录像界面
//摄像头 前置/后置
_picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
//闪光灯模式 自动
_picker.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
[self presentViewController:_picker animated:YES completion:nil];
}
#pragma mark UIImagePickerControllerDelegate 代理方法(在代理方法中处理视频)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[picker dismissViewControllerAnimated:YES completion:nil];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:@"public.image"]) {
//如果媒体类型为图片
//相机:裁剪后的图片//
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
//原始图片
UIImage *image2 = [info objectForKey:UIImagePickerControllerOriginalImage];
}else if (
[mediaType isEqualToString:@"public.movie"]){//如果媒体类型为视频
_movieUrl = [info objectForKey:UIImagePickerControllerMediaURL];
//获取视频资源定位
//将视频保存到本地
NSData *fileData = [NSData dataWithContentsOfURL:_movieUrl];
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
path = [path stringByAppendingPathComponent:@"save.mp4"];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isSuccess = [fileManager createFileAtPath:path contents:fileData attributes:nil];
if (isSuccess) {
NSLog(@"保存到本地成功");
//保存本地资源定位
_locoaUrl = [NSURL URLWithString:path];
} else {
NSLog(@"保存到本地失败");
} }
NSLog(@"拍照,相片完成”);
//将视频保存到相册
UISaveVideoAtPathToSavedPhotosAlbum([_movieUrl path], self, @selector(video:didFinishSavingWithError:contextInfo:), nil);}
/* 实现录制过程中点击取消退出 @param picker <#picker description#> */
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
}
/** 视频格式转换(带转换功能额)
** @param sender <#sender description#> */
- (IBAction)formatConverter:(id)sender{
//转换时文件不能已存在,否则出错
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:_movieUrl options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
//判断是否包含该质量的视频
if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality]) {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
//用时间给文件全名,以免重复,在测试的时候其实可以判断文件是否存在若存在,则删除,重新生成文件即可
NSDateFormatter *formater = [[NSDateFormatter alloc] init];
[formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
NSString *resultPath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/output-%@.mp4", [formater stringFromDate:[NSDate date]]];
exportSession.outputURL = [NSURL fileURLWithPath:resultPath];
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
switch (exportSession.status) {
case AVAssetExportSessionStatusUnknown:
NSLog(@"AVAssetExportSessionStatusUnknown");
break;
case AVAssetExportSessionStatusWaiting:
NSLog(@"AVAssetExportSessionStatusWaiting");
break;
case AVAssetExportSessionStatusExporting:
NSLog(@"AVAssetExportSessionStatusExporting");
break;
case AVAssetExportSessionStatusCompleted:
NSLog(@"AVAssetExportSessionStatusCompleted");
{
NSURL *fileUrl = [NSURL URLWithString:resultPath];
NSLog(@"转换结束");
[self fileSizeAtPath:fileUrl]; _endUrl = fileUrl;
}
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"AVAssetExportSessionStatusFailed");
break;
}
}];
}
}
三、其他:
/** **计算文件大小** @param filePathUrl <#filePathUrl description#> @return 返回单位为Byte */
- (unsigned long long)fileSizeAtPath:(NSURL *)filePathUrl{
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:[filePathUrl path]];
if (isExist){
unsigned long long fileSize = [[fileManager attributesOfItemAtPath:[filePathUrl path] error:nil] fileSize];
NSLog(@"%@大小: %f M",[filePathUrl path],fileSize/1024.0/1024.0);
return fileSize;
} else {
NSLog(@"file is not exist");
return 0;
}
}
/** **点击播放本地视频** @param sender <#sender description#> */
- (IBAction)playLocalMove:(id)sender {
NSURL *movieUrl = [NSURL fileURLWithPath:[_locoaUrl path]];
//直接调用_localUrl无法播放,不知道为什么
player = [AVPlayer playerWithURL:movieUrl];
//3、创建视频显示的图层
AVPlayerLayer *showVodioLayer = [AVPlayerLayer playerLayerWithPlayer:player];
showVodioLayer.frame = self.view.frame;
[self.view.layer addSublayer:showVodioLayer];
//4、播放视频
[player play];
}
/** **获取相册内视频的时长** @param URL <#URL description#> @return <#return value description#> */
-(CGFloat)getVideoLength:(NSURL*)URL{
NSDictionary*opts=[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVURLAsset *urlAs = [AVURLAsset URLAssetWithURL:URL options:opts];
CGFloat second= urlAs.duration.value/urlAs.duration.timescale;
return second;
}
//**视频保存后的回调**
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if (error) {
NSLog(@"保存视频过程中发生错误,错误信息:%@",error.localizedDescription);
}else{
NSLog(@"视频保存成功.");
}
}
视频质量与大小的关系(以10s为例)
// UIImagePickerControllerQualityTypeHigh = 0, 高,18M
// UIImagePickerControllerQualityTypeMedium = 1 , 中等,0.95M
// UIImagePickerControllerQualityTypeLow = 2, 低,0.19M
// UIImagePickerControllerQualityType640x480 , 3.745M
// UIImagePickerControllerQualityTypeIFrame1280x720, 50M
// UIImagePickerControllerQualityTypeIFrame960x540, 35M
四、UIImagePickerController常用属性、方法
1.+(BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;
// 检查指定源是否在设备上可用。
// 检查照片源是否可用
[UIImagePickerControlle isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]
2.allowsEditing
默认NO,是否允许编辑允许编辑.
[imagePicker setAllowsEditing:YES];
3. videoMaximumDuration
设置UIImagePicker的最大视频持续时间.默认10分钟
4. availableMediaTypesForSourceType:
//指定源可用的媒体种类
//获得相机模式下支持的媒体类型
NSArray* availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
5. sourceType
设置UIImagePicker照片源类型,默认有3种。
照片源类型 UIImagePickerControllerSourceTypeCamera
照相机 UIImagePickerControllerSourceTypePhotoLibrary
照片库(通过同步存放的,用户不能删除) UIImagePickerControllerSourceTypeSavedPhotosAlbum
保存的照片(通过拍照或者截屏保存的,用户可以删除)