实习准备 – 拍照和录制视频

主要方式:
1.使用UIImagePickerController拍照和录制视频
2.使用AVFoundation拍照和录制视频 (高度定制)

1.使用UIImagePickerController拍照和录制视频

UIImagePickerController是苹果提供的系统API,继承于UINavigationController,可以直接调用系统相机,但是界面不可定制。

UIImagePickerController大可实现下面几个功能:
* 控制摄像机拍照
* 控制摄像机录像
* 从相册选取照片或者视频

  • 通过设置sourceType属性来实现上面的功能,值为UIImagePickerControllerSourceTypeCamera为拍照和录制视频(下面再设置其他属性将两个功能划分),值为UIImagePickerControllerSourceTypePhotoLibrary为选取系统相册中的照片或者视频
  • cameraCaptureMode属性可以设置到底是拍照还是录像,值为UIImagePickerControllerCameraCaptureModePhoto为拍照,值为UIImagePickerControllerCameraCaptureModeVideo为录像
  • 设置cameraDevice属性为选取前后摄像头,UIImagePickerControllerCameraDeviceFront为前置,UIImagePickerControllerCameraDeviceRear为后置
  • 如果是启用录像功能的话还要设置mediaTypes属性,该属性值为NSArray,用于控制只支持哪种多媒体数据,如果要录制视频必须包含kUTTypeMovie值。
  • 上面提到UIImagePickerController继承于UINavigationController,同时为了实现监听摄像头拍到的内容,我们必须要实现UIImagePickerControllerDelegate和UINavigationControllerDelegate两个协议。
  • 另外几个常用的属性,如allowsEditing (拍摄到的照片是否允许编辑),videoQuality(录制的视频质量),cameraFlashMode(闪光灯模式),除此之外还可以调用方法来控制拍照和录制视频,不如 – takePicture方法可以拍照 ,- startVideoCapture 开始录像,- stopVideoCapture 结束录像。

这里我根据资料写了一个简单的demo,体会一下上述的几个功能,同时把一些坑填上。

#import "ViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <AssetsLibrary/AssetsLibrary.h>

@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>

@property(nonatomic,strong)UIImagePickerController *picker;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.picker = [[UIImagePickerController alloc] init];
    self.picker.delegate = self;
    
}

头部引用了两个框架,MobileCoreServices/MobileCoreServices是用在了设置录制视频的mediaTypes属性那里,(比如如果不引用的话kUTTypeMovie就会提示找不到),AssetsLibrary/AssetsLibrary则是用在保存录制的视频那里,(iOS9.0 之后使用 PHPhotoLibrary 代替,后面再重写此处);

 

- (IBAction)takePhoto:(id)sender {
    //如果拍摄的摄像头可用
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        //设置拍照或者录制
        self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        self.picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
        self.picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
        self.picker.allowsEditing = YES;
    }else{
        NSLog(@"模拟器无法打开摄像头");
    }
    
    [self presentViewController:_picker animated:YES completion:nil];
}

本方法实现了拍照功能,先判断摄像头是否可用,可用的话设置sourceType属性,然后再甚至cameraCaptureMode属性明确为拍照功能,同时设置摄像头的其他属性(这里为设置摄像头,后置摄像头为默认,设置允许编辑状态)。最后将视图使用 – presentViewController弹出。

- (IBAction)takeVideo:(id)sender {
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        _picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        _picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
        _picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
        _picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
    }else{
        NSLog(@"模拟器无法打开摄像头");
    }
    [self presentViewController:_picker animated:YES completion:nil];
}

录像功能与拍照功能相同思路,不在赘述。

- (IBAction)loadPhoto:(id)sender {
    _picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    _picker.allowsEditing = NO;
    [self presentViewController:_picker animated:YES completion:nil];
}

这里是选取照片功能,只需要将sourceType修改为UIImagePickerControllerSourceTypePhotoLibrary即可。

最后我们实现UIImagePickerControllerDelegate中的方法,来调用获取到的视频或图片。

//当得到照片时调用该方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSLog(@"成功%@",info);
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    //判断是否是图片
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage] && _picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
        UIImage *theImage = nil;
        //判断是否允许编辑
        if ([_picker allowsEditing]) {
            //获取编辑后的照片
            theImage = [info objectForKey:UIImagePickerControllerEditedImage];
        }else{
            theImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        }
        
        //保存照片到相册中
        UIImageWriteToSavedPhotosAlbum(theImage, self, nil, nil);
    }
    
    //判断是否是视频
    else if([mediaType isEqualToString:(NSString *)kUTTypeMovie]){
        NSURL *mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
        
        //创建ALAssetsLLibrary对象并将视频保存到媒体库
        ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
        [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:mediaURL completionBlock:^(NSURL *assetURL, NSError *error) {
            //如果没有错误则成功
            if (!error) {
                NSLog(@"视频保存成功");
            }else{
                NSLog(@"保存视频出错,%@",error);
            }
        }];
    }
    
    [_picker dismissViewControllerAnimated:YES completion:nil];
}

2.使用AVFoundation拍照和录制视频 (高度定制)