两种主要技术:UIImagePickerController、AVFoundation框架。
使用UIImagePickerController
#import "ViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
- (IBAction)videoRecod:(id)sender;
-(void)video:(NSString *)videoPath
didFinishSavingWithError:(NSError *)error
contextInfo:(NSString *)contextInfo;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)videoRecod:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
//录制质量设定
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
//只允许最多录制30秒时间
imagePickerController.videoMaximumDuration = 30.0f;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
else
{
NSLog(@"摄像头不可用。");
}
}
-(void)video:(NSString *)videoPath
didFinishSavingWithError:(NSError *)error
contextInfo:(NSString *)contextInfo
{
NSString *title;
NSString *message;
if (!error)
{
title = @"视频保存";
message = @"视频已经保存到设备的相机胶卷中";
}
else
{
title = @"保存失败";
message = [error description];
}
UIAlertController *alertC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertC addAction:alertA];
[self presentViewController:alertC animated:YES completion:nil];
}
#pragma mark - UIImagePickerController代理方法
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info
{
NSString *tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath))
{
UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), (__bridge void *)(tempFilePath));
}
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark -UINavigationControllerDelegate方法
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"选择器将要显示");
}
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"选择器显示结束");
}
@end
使用AVFoundation框架
更加细粒度的控制,可以获得来自设备的输入流,实时采集、捕获和播放视频技术。
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface ViewController ()
<AVCaptureFileOutputRecordingDelegate>
{
BOOL isRecording;
}
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureMovieFileOutput *output;
- (IBAction)recordPressed:(id)sender;
-(NSURL *)p_fileURL;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_session = [[AVCaptureSession alloc] init];
_session.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *camera = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&error];
AVCaptureDevice *micDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput *mic = [AVCaptureDeviceInput deviceInputWithDevice:micDevice error:&error];
if (error || !camera || !mic)
{
NSLog(@"Input Error");
}
else
{
[_session addInput:camera];
[_session addInput:mic];
}
_output = [[AVCaptureMovieFileOutput alloc] init];
if ([_session canAddOutput:_output])
{
[_session addOutput:_output];
}
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
previewLayer.frame = CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height - 70);
[self.view.layer insertSublayer:previewLayer atIndex:0];
[_session startRunning];
isRecording = NO;
_label.text = @"";
}
- (IBAction)recordPressed:(id)sender
{
if (!isRecording)
{
[_button setTitle:@"停止" forState:UIControlStateNormal];
_label.text = @"录制中……";
isRecording = YES;
NSURL *fileURL = [self p_fileURL];
[_output startRecordingToOutputFileURL:fileURL recordingDelegate:self];
}
else
{
[_button setTitle:@"录制" forState:UIControlStateNormal];
_label.text = @"停止";
[_output stopRecording];
isRecording = NO;
}
}
-(NSURL *)p_fileURL
{
NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"movie.mov"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *manager = [[NSFileManager alloc] init];
if ([manager fileExistsAtPath:outputPath])
{
[manager removeItemAtPath:outputPath error:nil];
}
return outputURL;
}
#pragma mark - AVCaptureFileOutputRecordingDelegate协议方法
-(void)captureOutput:(AVCaptureFileOutput *)output
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray<AVCaptureConnection *> *)connections
error:(NSError *)error
{
if (error == nil)
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error)
{
if (error)
{
NSLog(@"写入错误。");
}
}];
}
}
@end