[iOS]从相册获取以及用相机拍摄视频并缓存到沙盒
2016-03-01 14:04
1256 查看
[iOS]从相册获取以及用相机拍摄视频并缓存到沙盒
Demo:http://download.csdn.net/detail/u012881779/9449227
从标题很容易发现,本文只是为了获取视频数据源,以便后面能方便完成视频上传等操作
需要导入AVFoundation.framework(获取数据源), MediaPlayer.framework(播放视频)
Demo:http://download.csdn.net/detail/u012881779/9449227
从标题很容易发现,本文只是为了获取视频数据源,以便后面能方便完成视频上传等操作
需要导入AVFoundation.framework(获取数据源), MediaPlayer.framework(播放视频)
#import "DMSelectVideoViewController.h" #import "ZYQAssetPickerController.h" #import <AVFoundation/AVFoundation.h> #import <MediaPlayer/MediaPlayer.h> // 视频URL路径 #define KVideoUrlPath \ [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"VideoURL"] @interface DMSelectVideoViewController ()<UIActionSheetDelegate , ZYQAssetPickerControllerDelegate , UINavigationControllerDelegate ,UITextFieldDelegate , UIImagePickerControllerDelegate> @property (strong, nonatomic) NSMutableArray *uploadDataArr; @property (weak, nonatomic) IBOutlet UITextView *desTextView; @property (weak, nonatomic) IBOutlet UIImageView *imgView; @property (weak, nonatomic) IBOutlet UILabel *titleLab; @property (weak, nonatomic) IBOutlet UILabel *typeLab; @property (weak, nonatomic) IBOutlet UILabel *timeLab; @property (strong, nonatomic) MPMoviePlayerViewController *moviePlayerView; @end @implementation DMSelectVideoViewController @synthesize uploadDataArr = _uploadDataArr; @synthesize moviePlayerView = _moviePlayerView; //播放视频 - (IBAction)playVideoAction:(id)sender { if(_uploadDataArr){ NSDictionary *lastObj = [_uploadDataArr lastObject]; NSString *viPath = [lastObj objectForKey:@"path"]; if(![viPath isEqualToString:@""]){ NSURL *movieURL = [NSURL fileURLWithPath:viPath]; [_moviePlayerView.view removeFromSuperview]; _moviePlayerView = nil; _moviePlayerView =[[MPMoviePlayerViewController alloc] initWithContentURL:movieURL]; [_moviePlayerView.moviePlayer prepareToPlay]; [self.view addSubview:_moviePlayerView.view]; _moviePlayerView.moviePlayer.shouldAutoplay=YES; [_moviePlayerView.moviePlayer setControlStyle:MPMovieControlStyleDefault]; [_moviePlayerView.moviePlayer setFullscreen:YES]; [_moviePlayerView.view setFrame:self.view.bounds]; //播放完后的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; //离开全屏时通知,因为默认点击Done是退出全屏,要离开播放器就要覆盖掉这个事件 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitFullScreen:) name: MPMoviePlayerDidExitFullscreenNotification object:nil]; } } } //播放结束后离开播放器,点击上一曲、下一曲也是播放结束 -(void)movieFinishedCallback:(NSNotification*)notify { MPMoviePlayerController* theMovie = [notify object]; [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie]; [theMovie.view removeFromSuperview]; } -(void)exitFullScreen:(NSNotification *)notification{ [_moviePlayerView.view removeFromSuperview]; } //选择视频 - (IBAction)ChioceVideoAction:(id)sender { [self.view endEditing:YES]; UIActionSheet *actionSheet=[[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"从相册选择",@"相机拍摄", nil]; actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque; [actionSheet showInView:self.view]; } //投稿 - (IBAction)IWantToContributeAction:(id)sender { [self.view endEditing:YES]; } -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ switch (buttonIndex) { case 0: //从相册选择 [self selectFromAlbumAction]; break; case 1: //相机拍摄 [self shootingWithCameraAction]; break; default: break; } } #pragma mark 从相册选择 //从相册选择 -(void)selectFromAlbumAction{ ZYQAssetPickerController *picker = [[ZYQAssetPickerController alloc] init]; picker.maximumNumberOfSelection = 1; picker.assetsFilter = [ALAssetsFilter allVideos]; picker.showEmptyGroups=NO; picker.delegate=self; picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { if ([[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) { NSTimeInterval duration = [[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyDuration] doubleValue]; return duration <= 60; } else { return YES; } }]; [self presentViewController:picker animated:YES completion:NULL]; } #pragma mark - ZYQAssetPickerController Delegate -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{ if(!_uploadDataArr){ _uploadDataArr = [[NSMutableArray alloc] init]; } [_uploadDataArr removeAllObjects]; //清空缓存中数据 [self cleanCachesVideo]; //清空UI上数据 [self cleanOnUIData]; for (int i=0; i<assets.count; i++) { ALAsset *asset=assets[i]; ALAssetRepresentation * representation = asset.defaultRepresentation; UIImage *tempImg = [UIImage imageWithCGImage:asset.thumbnail]; NSData *data = UIImageJPEGRepresentation(tempImg, 1); NSString *reName = [self renameWithTimeSp:representation.filename]; [self videoWithUrl:representation.url withFileName:reName]; int seconds =[[asset valueForProperty:ALAssetPropertyDuration] intValue]; NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init]; if(data){ [objDict setObject:data forKey:@"header"]; } [objDict setObject:[NSString stringWithFormat:@"%@/%@",KVideoUrlPath,reName] forKey:@"path"]; [objDict setObject:[NSString stringWithFormat:@"%.2fM",(representation.size/1024.0)/1024.0] forKey:@"type"]; [objDict setObject:reName forKey:@"name"]; [objDict setObject:[NSString stringWithFormat:@"%d",seconds] forKey:@"time"]; [_uploadDataArr addObject:objDict]; } } // 将原始视频的URL转化为NSData数据,写入沙盒 - (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName{ NSFileManager * fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:KVideoUrlPath]) { [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil]; } ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (url) { [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) { ALAssetRepresentation *rep = [asset defaultRepresentation]; NSString * videoPath = [KVideoUrlPath stringByAppendingPathComponent:fileName]; const char *cvideoPath = [videoPath UTF8String]; FILE *file = fopen(cvideoPath, "a+"); if (file) { const int bufferSize = 11024 * 1024; // 初始化一个1M的buffer Byte *buffer = (Byte*)malloc(bufferSize); NSUInteger read = 0, offset = 0, written = 0; NSError* err = nil; if (rep.size != 0) { do { read = [rep getBytes:buffer fromOffset:offset length:bufferSize error:&err]; written = fwrite(buffer, sizeof(char), read, file); offset += read; } while (read != 0 && !err); } // 释放缓冲区,关闭文件 free(buffer); buffer = NULL; fclose(file); file = NULL; // UI的更新放在主线程 dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary *firstDict = [_uploadDataArr firstObject]; if(firstDict){ _imgView.image = [UIImage imageWithData:[firstDict objectForKey:@"header"]]; _titleLab.text = [firstDict objectForKey:@"name"]; _typeLab.text = [firstDict objectForKey:@"type"]; NSString *timeStr = [firstDict objectForKey:@"time"]; if([timeStr intValue] > 0){ _timeLab.text = [NSString stringWithFormat:@"%@S",timeStr]; } } }); } } failureBlock:nil]; } }); } //清空缓存中数据 -(void)cleanCachesVideo{ NSFileManager * fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:KVideoUrlPath]) { [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil]; } NSArray *contents = [fileManager contentsOfDirectoryAtPath:KVideoUrlPath error:NULL]; NSEnumerator *e = [contents objectEnumerator]; NSString *filename; while ((filename = [e nextObject])) { [fileManager removeItemAtPath:[KVideoUrlPath stringByAppendingPathComponent:filename] error:NULL]; } } //用时间戳对文件命名 到毫秒 -(NSString *)renameWithTimeSp:(NSString *)fileName{ NSArray *spArr = [fileName componentsSeparatedByString:@"."]; int hs = arc4random() % 100; NSDate *newDate = [NSDate date]; long int timeSp = (long)[newDate timeIntervalSince1970]; fileName = [NSString stringWithFormat:@"%ld%d.%@",timeSp,hs,[spArr lastObject]]; return fileName; } //清空UI上数据 -(void)cleanOnUIData{ _imgView.image = nil; _titleLab.text = @""; _typeLab.text = @""; _timeLab.text = @""; } #pragma mark 相机拍摄 //相机拍摄 -(void)shootingWithCameraAction{ UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; ipc.sourceType = UIImagePickerControllerSourceTypeCamera;//sourcetype有三种分别是camera,photoLibrary和photoAlbum NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支持的Media格式都有哪些,共有两个分别是@"public.image",@"public.movie" ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//设置媒体类型为public.movie [self presentViewController:ipc animated:YES completion:nil]; ipc.videoMaximumDuration = 60.0f;//60秒 ipc.delegate = self;//设置委托 } //选择完成后响应 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ NSString*sourceURL = [info objectForKey:UIImagePickerControllerMediaURL]; NSLog(@"%@",sourceURL); NSFileManager * fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:KVideoUrlPath]) { [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil]; } //视频长度 float videoLengthTime = [self getVideoLength:(NSURL *)sourceURL]; //视频缩略图 UIImage *videoImgtemp = [self getImage:(NSURL *)sourceURL]; NSData *createData = [NSData dataWithContentsOfFile:sourceURL]; if(createData){ //清空缓存中数据 [self cleanCachesVideo]; //清空UI上数据 [self cleanOnUIData]; NSString *lastName = @"capturedvideo.MOV"; NSString *kvideoPath = [NSString stringWithFormat:@"%@/%@",KVideoUrlPath,[self renameWithTimeSp:lastName]]; BOOL result = [fileManager createFileAtPath:kvideoPath contents:createData attributes:nil]; if(result){ NSString *paiPath = [NSString stringWithFormat:@"%@/tmp", NSHomeDirectory()] ; NSArray *contents = [fileManager contentsOfDirectoryAtPath:paiPath error:NULL]; NSEnumerator *e = [contents objectEnumerator]; NSString *filename; while ((filename = [e nextObject])) { [fileManager removeItemAtPath:[paiPath stringByAppendingPathComponent:filename] error:NULL]; } } if (![kvideoPath isEqualToString:@""]) { if(!_uploadDataArr){ _uploadDataArr = [[NSMutableArray alloc] init]; } [_uploadDataArr removeAllObjects]; AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:kvideoPath] options:nil]; NSString *addname = [[kvideoPath componentsSeparatedByString:@"/"] lastObject]; NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init]; NSData *data = UIImageJPEGRepresentation(videoImgtemp, 1); if(data){ [objDict setObject:data forKey:@"header"]; } [objDict setObject:kvideoPath forKey:@"path"]; [objDict setObject:[NSString stringWithFormat:@"%.2fM",[self getFileSize:kvideoPath]] forKey:@"type"]; [objDict setObject:addname forKey:@"name"]; [objDict setObject:[NSString stringWithFormat:@"%.f",videoLengthTime] forKey:@"time"]; [_uploadDataArr addObject:objDict]; // UI的更新放在主线程 dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary *firstDict = [_uploadDataArr firstObject]; if(firstDict){ _imgView.image = [UIImage imageWithData:[firstDict objectForKey:@"header"]]; _titleLab.text = [firstDict objectForKey:@"name"]; _typeLab.text = [firstDict objectForKey:@"type"]; NSString *timeStr = [firstDict objectForKey:@"time"]; if([timeStr intValue] > 0){ _timeLab.text = [NSString stringWithFormat:@"%@S",timeStr]; } } }); } } [self dismissViewControllerAnimated:YES completion:nil]; } //获取视频文件的大小,返回的是单位是M。 - (CGFloat)getFileSize:(NSString *)path{ NSFileManager *fileManager = [[NSFileManager alloc] init]; float filesize = -1.0; if ([fileManager fileExistsAtPath:path]) { NSDictionary *fileDic = [fileManager attributesOfItemAtPath:path error:nil];//获取文件的属性 unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue]; filesize = (1.0*size/1024)/1024.0; } return filesize; } //获取视频文件的时长。 - (CGFloat)getVideoLength:(NSURL *)URL{ NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:URL options:opts]; float second = 0; second = urlAsset.duration.value/urlAsset.duration.timescale; return second; } //获取本地视频缩略图,网上说需要添加AVFoundation.framework - (UIImage *)getImage:(NSURL *)URL{ AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:URL options:nil]; AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; gen.appliesPreferredTrackTransform = YES; CMTime time = CMTimeMakeWithSeconds(0.0, 600); NSError *error = nil; CMTime actualTime; CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error]; UIImage *thumb = [[UIImage alloc] initWithCGImage:image]; CGImageRelease(image); return thumb; } @end示意图:
相关文章推荐
- iOS开发打电话的功能
- Masonry框架
- iOS内存管理之自动释放池延迟销毁对象
- iOS-数组,字典常用的字面量写法
- iOS 之可穿戴设备开发之蓝牙4.0
- iOS下的Masonry适配
- iOS应用崩溃日志分析
- iOS-更新CocoaPods出现错误 提示重复文件
- iOS 证书失效,更换WWDR试一下,吼吼
- iOS文件目录
- iOS开发中如何合理地制造BUG
- iOS 图片点击放大封装
- iOS-常用宏定义
- ios签名机制的理解
- iOS-.pch如何使用
- ios进行打包
- Missing iOS Distribution signing identity问题解决
- iOS 高效添加圆角效果实战讲解
- iOS开发之Runloop
- iOS 第三方库冲突的处理