接上回。
Record and Save Video(手动录制视频并保存)
做好了视频的播放,现在要做的是使用手机录制视频并保存到media library中.
打开storyboard这样做:
1.在Record Video View Controller上添加一个按钮,命名为”Record Video”
2.同样的,为”Record Video”按钮添加名为 recordAndPlay:的消息响应.
用以下代码替代RecordVideoViewController.h内容:
#import <MediaPlayer/MediaPlayer.h>
#import <MobileCoreServices/UTCoreTypes.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface RecordVideoViewController: UIViewController
-(IBAction)recordAndPlay:(id)sender;
-(BOOL)startCameraControllerFromViewController:(UIViewController*)controller
usingDelegate:(id )delegate;
-(void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo;
@end
你可能已经注意到了—》这些代码中有些和PlayVideoViewController中写过的代码一样。至于那些不同的部分:
AssetsLibrary.h 头文件提供了获取图片和视频的路径,想要将video保存到本地图库,就需要引入AssetsLibrary框架。
这个库包括了本地相册,从iTunes下载的,还有直接下载到手机上的媒体文件。可以用这个库提供的方法将图片和视频存储到本地相册。
另外一个不同之处就是video:didFinishSavingWithError:contextInfo:方法,这个方法会在视频保存完成之后被执行。方法名称说明了它的作用。
好啦,现在打开RecordVideoViewController.m,将以下语句添加到recordAndPlay:方法中:
[self startCameraControllerFromViewController:self usingDelegate:self];
接下要添加如下一个方法到文件末尾(但是在结尾的@end之前):
-(BOOL)startCameraControllerFromViewController:(UIViewController*)controller
usingDelegate:(id )delegate {
// 1 - Validattions
if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil)) {
return NO;
}
// 2 - Get image picker
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose movie capture
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
// 3 - Display image picker
// 改动1
[controller presentViewController:cameraUI animated:NO completion:nil];
return YES;
}
当按下“Record Video”时候该方法会被调用。方法声明我们刚刚已经写在了.h文件中。
注意:代码最后我改动了一下,就是标注了改动1的那句,代替了废弃方法,原先代码可以看原文。
在上面的代码中,你查找的类型是“UIImagePickerControllerSourceTypeCamera”而不是 “UIImagePickerControllerSourceTypeSavedPhotosAlbum”,因为你要使用的是相机。
编译并运行代码看看目前的进度。
在app首页点击“Record Video”按钮,这一次打开的不是相册,而是相机界面。点击红色录制按钮开始录制视频,当录制完成时候再次点击按钮结束。
只是看看这个视频截图,你根本无法想象刚刚发生了什么!一个辣妹从我的镜头前走过~
开个玩笑。。。但是用你自己的手机调试运行这样一段代码确实是一件非常让人兴奋的事情
当你跳到下一个界面后,你可以选择使用这个录好的视频或者重新录制。如果你选择了”Use”,你将会注意到没有什么事情发生–这是因为,因为我们没有实现回调方法。你需要一个完成保存功能的回调方法。
去实现这样一个回调方法,添加如下代码到RecordVideoViewController.m:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
// 改动2
[self dismissViewControllerAnimated:NO completion:nil];
// Handle a movie capture
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
// 改动3
NSString *moviePath = (NSString*)[[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self,
@selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}
}
-(void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {
if (error) {
// 改动4 因为alertView和actionSheet在ios8中被废弃掉了,所以我使用了被推荐的alertController和alertAction来代替
NSString *title = NSLocalizedString(@"错误", nil);
NSString *message = NSLocalizedString(@"保存失败", nil);
NSString *otherButtonTitle = NSLocalizedString(@"确定", nil);
UIAlertController *alert=[UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:nil];
[alert addAction:otherAction];
[self presentViewController:alert animated:NO completion:nil];
} else {
NSString *title = NSLocalizedString(@"保存成功", nil);
NSString *message = NSLocalizedString(@"保存到本地相册", nil);
NSString *otherButtonTitle = NSLocalizedString(@"确定", nil);
// 创建alertController
UIAlertController *alert=[UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
// 创建按钮
UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:nil];
// 添加按钮
[alert addAction:otherAction];
// 显示alert
[self presentViewController:alert animated:NO completion:nil];
}
}
在上面两个方法中,我都有比较大的改动,主要是因为alertView和actionSheet在ios8中都已经被废弃了,所以使用alertController + alertAction组合代替。
在上面的代码中
imagePickerController:didFinishPickingMediaWithInfo:
方法是根据info参数提供的视频临时存储的url地址,然后将该视频保存到本地相册。
而UISaveVideoAtPathToSavedPhotosAlbum方法是SDK中提供的保存视频到本地相册的默认方法,我们传入的参数是要保存视频的目标路径和一个可以通知我们保存状态的回调函数。
编译运行代码,录制一个视频并选择”Use”,如果”保存成功”的提示出现,那么视频就已经被成功的保存到了本地相册中了!如果真机测试的话,可以打开自己的手机相册看一下,多了一个视频~
好了,视频录制并保存也已经完成了,接下来一篇就是对于AVFoundation的一个简单的介绍,然后下下篇是如何合并视频。
欢迎继续关注!