iOS从相册获取以及用相机拍摄视频并缓存到沙盒

来源:互联网 发布:浴缸尺寸 知乎 编辑:程序博客网 时间:2024/05/22 17:37

iOS从相册获取以及用相机拍摄视频并缓存到沙盒


Demo:http://download.csdn.net/detail/u012881779/9449227

从标题很容易发现,本文只是为了获取视频数据源,以便后面能方便完成视频上传等操作

需要导入AVFoundation.framework(获取数据源), MediaPlayer.framework(播放视频)

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #import "DMSelectVideoViewController.h"  
  2. #import "ZYQAssetPickerController.h"  
  3. #import <AVFoundation/AVFoundation.h>  
  4. #import <MediaPlayer/MediaPlayer.h>  
  5. // 视频URL路径  
  6. #define KVideoUrlPath   \  
  7. [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"VideoURL"]  
  8.   
  9.   
  10. @interface DMSelectVideoViewController ()<UIActionSheetDelegate , ZYQAssetPickerControllerDelegate , UINavigationControllerDelegate ,UITextFieldDelegate , UIImagePickerControllerDelegate>  
  11. @property (strongnonatomic) NSMutableArray     *uploadDataArr;     
  12. @property (weak, nonatomic) IBOutlet UITextView  *desTextView;  
  13. @property (weak, nonatomic) IBOutlet UIImageView *imgView;  
  14. @property (weak, nonatomic) IBOutlet UILabel     *titleLab;  
  15. @property (weak, nonatomic) IBOutlet UILabel     *typeLab;  
  16. @property (weak, nonatomic) IBOutlet UILabel     *timeLab;  
  17. @property (strongnonatomicMPMoviePlayerViewController *moviePlayerView;  
  18.   
  19. @end  
  20.   
  21. @implementation DMSelectVideoViewController  
  22. @synthesize uploadDataArr = _uploadDataArr;  
  23. @synthesize moviePlayerView = _moviePlayerView;  
  24.   
  25. //播放视频  
  26. - (IBAction)playVideoAction:(id)sender {  
  27.     if(_uploadDataArr){  
  28.         NSDictionary *lastObj = [_uploadDataArr lastObject];  
  29.         NSString *viPath = [lastObj objectForKey:@"path"];  
  30.         if(![viPath isEqualToString:@""]){  
  31.             NSURL *movieURL = [NSURL fileURLWithPath:viPath];  
  32.             [_moviePlayerView.view removeFromSuperview];  
  33.             _moviePlayerView = nil;  
  34.             _moviePlayerView =[[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];  
  35.             [_moviePlayerView.moviePlayer prepareToPlay];  
  36.             [self.view addSubview:_moviePlayerView.view];  
  37.   
  38.             _moviePlayerView.moviePlayer.shouldAutoplay=YES;  
  39.             [_moviePlayerView.moviePlayer setControlStyle:MPMovieControlStyleDefault];  
  40.             [_moviePlayerView.moviePlayer setFullscreen:YES];  
  41.             [_moviePlayerView.view setFrame:self.view.bounds];  
  42.               
  43.             //播放完后的通知  
  44.             [[NSNotificationCenter defaultCenter] addObserver:self  
  45.                                                      selector:@selector(movieFinishedCallback:)  
  46.                                                          name:MPMoviePlayerPlaybackDidFinishNotification                                                      object:nil];  
  47.             //离开全屏时通知,因为默认点击Done是退出全屏,要离开播放器就要覆盖掉这个事件  
  48.             [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitFullScreen:) name: MPMoviePlayerDidExitFullscreenNotification object:nil];  
  49.         }  
  50.     }  
  51. }  
  52.   
  53. //播放结束后离开播放器,点击上一曲、下一曲也是播放结束  
  54. -(void)movieFinishedCallback:(NSNotification*)notify {  
  55.     MPMoviePlayerController* theMovie = [notify object];  
  56.     [[NSNotificationCenter defaultCenter] removeObserver:self  
  57.                                                    name:MPMoviePlayerPlaybackDidFinishNotification  
  58.                                                  object:theMovie];  
  59.     [theMovie.view removeFromSuperview];  
  60. }  
  61.   
  62. -(void)exitFullScreen:(NSNotification *)notification{  
  63.     [_moviePlayerView.view removeFromSuperview];  
  64. }  
  65.   
  66.   
  67.   
  68. //选择视频  
  69. - (IBAction)ChioceVideoAction:(id)sender {  
  70.     [self.view endEditing:YES];  
  71.   
  72.     UIActionSheet *actionSheet=[[UIActionSheet alloc] initWithTitle:nil  
  73.                                                            delegate:self  
  74.                                                   cancelButtonTitle:@"取消"  
  75.                                              destructiveButtonTitle:nil  
  76.                                                   otherButtonTitles:@"从相册选择",@"相机拍摄", nil nil];  
  77.     actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;  
  78.     [actionSheet showInView:self.view];  
  79. }  
  80.   
  81. //投稿  
  82. - (IBAction)IWantToContributeAction:(id)sender {  
  83.     [self.view endEditing:YES];  
  84. }  
  85.   
  86. -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{  
  87.       
  88.     switch (buttonIndex) {  
  89.         case 0:  
  90.             //从相册选择  
  91.             [self selectFromAlbumAction];  
  92.             break;  
  93.               
  94.         case 1:  
  95.             //相机拍摄  
  96.             [self shootingWithCameraAction];  
  97.             break;  
  98.               
  99.         default:  
  100.             break;  
  101.     }  
  102. }  
  103.   
  104. #pragma mark 从相册选择  
  105. //从相册选择  
  106. -(void)selectFromAlbumAction{  
  107.     ZYQAssetPickerController *picker = [[ZYQAssetPickerController alloc] init];  
  108.     picker.maximumNumberOfSelection = 1;  
  109.   
  110.     picker.assetsFilter = [ALAssetsFilter allVideos];  
  111.     picker.showEmptyGroups=NO;  
  112.     picker.delegate=self;  
  113.       
  114.     picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {  
  115.         if ([[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) {  
  116.             NSTimeInterval duration = [[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyDuration] doubleValue];  
  117.             return duration <= 60;  
  118.               
  119.         } else {  
  120.             return YES;  
  121.         }  
  122.     }];  
  123.       
  124.     [self presentViewController:picker animated:YES completion:NULL];  
  125. }  
  126.   
  127. #pragma mark - ZYQAssetPickerController Delegate  
  128. -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{  
  129.       
  130.     if(!_uploadDataArr){  
  131.         _uploadDataArr = [[NSMutableArray alloc] init];  
  132.     }  
  133.     [_uploadDataArr removeAllObjects];  
  134.     //清空缓存中数据  
  135.     [self cleanCachesVideo];  
  136.     //清空UI上数据  
  137.     [self cleanOnUIData];  
  138.       
  139.     for (int i=0; i<assets.count; i++) {  
  140.         ALAsset *asset=assets[i];  
  141.         ALAssetRepresentation * representation = asset.defaultRepresentation;  
  142.           
  143.         UIImage *tempImg = [UIImage imageWithCGImage:asset.thumbnail];  
  144.         NSData *data = UIImageJPEGRepresentation(tempImg, 1);  
  145.         NSString *reName = [self renameWithTimeSp:representation.filename];  
  146.         [self videoWithUrl:representation.url withFileName:reName];  
  147.               
  148.         int seconds  =[[asset valueForProperty:ALAssetPropertyDuration] intValue];  
  149.   
  150.         NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];  
  151.         if(data){  
  152.             [objDict setObject:data forKey:@"header"];  
  153.         }  
  154.         [objDict setObject:[NSString stringWithFormat:@"%@/%@",KVideoUrlPath,reName]  forKey:@"path"];  
  155.         [objDict setObject:[NSString stringWithFormat:@"%.2fM",(representation.size/1024.0)/1024.0] forKey:@"type"];  
  156.         [objDict setObject:reName  forKey:@"name"];  
  157.           
  158.         [objDict setObject:[NSString stringWithFormat:@"%d",seconds]  forKey:@"time"];  
  159.   
  160.         [_uploadDataArr addObject:objDict];  
  161.     }  
  162. }  
  163.   
  164. // 将原始视频的URL转化为NSData数据,写入沙盒  
  165. - (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName{  
  166.    
  167.     NSFileManager * fileManager = [NSFileManager defaultManager];  
  168.     if (![fileManager fileExistsAtPath:KVideoUrlPath]) {  
  169.         [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil];  
  170.     }  
  171.     ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];  
  172.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  173.         if (url) {  
  174.             [assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {  
  175.                 ALAssetRepresentation *rep = [asset defaultRepresentation];  
  176.                 NSString * videoPath = [KVideoUrlPath stringByAppendingPathComponent:fileName];  
  177.                 const charchar *cvideoPath = [videoPath UTF8String];  
  178.                 FILEFILE *file = fopen(cvideoPath, "a+");  
  179.                 if (file) {  
  180.                     const int bufferSize = 111024 * 1024;  
  181.                     // 初始化一个1M的buffer  
  182.                     Byte *buffer = (Byte*)malloc(bufferSize);  
  183.                     NSUInteger read = 0, offset = 0, written = 0;  
  184.                     NSError* err = nil;  
  185.                     if (rep.size != 0)  
  186.                     {  
  187.                         do {  
  188.                             read = [rep getBytes:buffer fromOffset:offset length:bufferSize error:&err];  
  189.                             written = fwrite(buffer, sizeof(char), read, file);  
  190.                             offset += read;  
  191.                         } while (read != 0 && !err);  
  192.                     }  
  193.                     // 释放缓冲区,关闭文件  
  194.                     free(buffer);  
  195.                     buffer = NULL;  
  196.                     fclose(file);  
  197.                     file = NULL;  
  198.                       
  199.                     // UI的更新放在主线程  
  200.                     dispatch_async(dispatch_get_main_queue(), ^{  
  201.                         NSDictionary *firstDict = [_uploadDataArr firstObject];  
  202.                         if(firstDict){  
  203.                             _imgView.image = [UIImage imageWithData:[firstDict objectForKey:@"header"]];  
  204.                             _titleLab.text = [firstDict objectForKey:@"name"];  
  205.                             _typeLab.text = [firstDict objectForKey:@"type"];  
  206.                             NSString *timeStr = [firstDict objectForKey:@"time"];  
  207.                             if([timeStr intValue] > 0){  
  208.                                 _timeLab.text = [NSString stringWithFormat:@"%@S",timeStr];  
  209.                             }  
  210.                         }  
  211.                     });  
  212.                 }  
  213.             } failureBlock:nil];  
  214.         }  
  215.     });  
  216. }  
  217.   
  218. //清空缓存中数据  
  219. -(void)cleanCachesVideo{  
  220.     NSFileManager * fileManager = [NSFileManager defaultManager];  
  221.     if (![fileManager fileExistsAtPath:KVideoUrlPath]) {  
  222.         [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil];  
  223.     }  
  224.   
  225.     NSArray *contents = [fileManager contentsOfDirectoryAtPath:KVideoUrlPath error:NULL];  
  226.     NSEnumerator *e = [contents objectEnumerator];  
  227.     NSString *filename;  
  228.     while ((filename = [e nextObject])) {  
  229.           [fileManager removeItemAtPath:[KVideoUrlPath stringByAppendingPathComponent:filename] error:NULL];  
  230.     }  
  231. }  
  232.   
  233. //用时间戳对文件命名 到毫秒  
  234. -(NSString *)renameWithTimeSp:(NSString *)fileName{  
  235.     NSArray *spArr = [fileName componentsSeparatedByString:@"."];  
  236.     int hs = arc4random() % 100;  
  237.     NSDate *newDate = [NSDate date];  
  238.     long int timeSp = (long)[newDate timeIntervalSince1970];  
  239.     fileName = [NSString stringWithFormat:@"%ld%d.%@",timeSp,hs,[spArr lastObject]];  
  240.     return fileName;  
  241. }  
  242.   
  243. //清空UI上数据  
  244. -(void)cleanOnUIData{  
  245.     _imgView.image = nil;  
  246.     _titleLab.text = @"";  
  247.     _typeLab.text = @"";  
  248.     _timeLab.text = @"";  
  249. }  
  250.   
  251. #pragma mark 相机拍摄  
  252. //相机拍摄  
  253. -(void)shootingWithCameraAction{  
  254.     UIImagePickerController *ipc = [[UIImagePickerController alloc] init];  
  255.     ipc.sourceType = UIImagePickerControllerSourceTypeCamera;//sourcetype有三种分别是camera,photoLibrary和photoAlbum  
  256.     NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支持的Media格式都有哪些,共有两个分别是@"public.image",@"public.movie"  
  257.     ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//设置媒体类型为public.movie  
  258.     [self presentViewController:ipc animated:YES completion:nil];  
  259.     ipc.videoMaximumDuration = 60.0f;//60秒  
  260.     ipc.delegate = self;//设置委托  
  261.   
  262. }  
  263.   
  264. //选择完成后响应  
  265. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{  
  266.     NSString*sourceURL = [info objectForKey:UIImagePickerControllerMediaURL];  
  267.     NSLog(@"%@",sourceURL);  
  268.     NSFileManager * fileManager = [NSFileManager defaultManager];  
  269.     if (![fileManager fileExistsAtPath:KVideoUrlPath]) {  
  270.         [fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil];  
  271.     }  
  272.     //视频长度  
  273.     float videoLengthTime = [self getVideoLength:(NSURL *)sourceURL];  
  274.     //视频缩略图  
  275.     UIImage *videoImgtemp = [self getImage:(NSURL *)sourceURL];  
  276.       
  277.     NSData *createData = [NSData dataWithContentsOfFile:sourceURL];  
  278.     if(createData){  
  279.         //清空缓存中数据  
  280.         [self cleanCachesVideo];  
  281.         //清空UI上数据  
  282.         [self cleanOnUIData];  
  283.           
  284.         NSString *lastName = @"capturedvideo.MOV";  
  285.         NSString *kvideoPath = [NSString stringWithFormat:@"%@/%@",KVideoUrlPath,[self renameWithTimeSp:lastName]];  
  286.         BOOL result = [fileManager createFileAtPath:kvideoPath contents:createData attributes:nil];  
  287.         if(result){  
  288.             NSString *paiPath = [NSString stringWithFormat:@"%@/tmp", NSHomeDirectory()] ;  
  289.   
  290.             NSArray *contents = [fileManager contentsOfDirectoryAtPath:paiPath error:NULL];  
  291.             NSEnumerator *e = [contents objectEnumerator];  
  292.             NSString *filename;  
  293.             while ((filename = [e nextObject])) {  
  294.                 [fileManager removeItemAtPath:[paiPath stringByAppendingPathComponent:filename] error:NULL];  
  295.             }  
  296.         }  
  297.         if (![kvideoPath isEqualToString:@""]) {  
  298.             if(!_uploadDataArr){  
  299.                 _uploadDataArr = [[NSMutableArray alloc] init];  
  300.             }  
  301.             [_uploadDataArr removeAllObjects];  
  302.               
  303.             AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:kvideoPath] options:nil];  
  304.             NSString *addname = [[kvideoPath componentsSeparatedByString:@"/"] lastObject];  
  305.             NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];  
  306.             NSData *data = UIImageJPEGRepresentation(videoImgtemp, 1);  
  307.             if(data){  
  308.                 [objDict setObject:data forKey:@"header"];  
  309.             }  
  310.             [objDict setObject:kvideoPath  forKey:@"path"];  
  311.             [objDict setObject:[NSString stringWithFormat:@"%.2fM",[self getFileSize:kvideoPath]] forKey:@"type"];  
  312.             [objDict setObject:addname forKey:@"name"];  
  313.             [objDict setObject:[NSString stringWithFormat:@"%.f",videoLengthTime]  forKey:@"time"];  
  314.   
  315.             [_uploadDataArr addObject:objDict];  
  316.               
  317.             // UI的更新放在主线程  
  318.             dispatch_async(dispatch_get_main_queue(), ^{  
  319.                 NSDictionary *firstDict = [_uploadDataArr firstObject];  
  320.                 if(firstDict){  
  321.                     _imgView.image = [UIImage imageWithData:[firstDict objectForKey:@"header"]];  
  322.                     _titleLab.text = [firstDict objectForKey:@"name"];  
  323.                     _typeLab.text = [firstDict objectForKey:@"type"];  
  324.                     NSString *timeStr = [firstDict objectForKey:@"time"];  
  325.                     if([timeStr intValue] > 0){  
  326.                         _timeLab.text = [NSString stringWithFormat:@"%@S",timeStr];  
  327.                     }  
  328.                 }  
  329.             });  
  330.         }  
  331.     }  
  332.       
  333.     [self dismissViewControllerAnimated:YES completion:nil];  
  334. }  
  335.   
  336. //获取视频文件的大小,返回的是单位是M。  
  337. - (CGFloat)getFileSize:(NSString *)path{  
  338.     NSFileManager *fileManager = [[NSFileManager alloc] init];  
  339.     float filesize = -1.0;  
  340.     if ([fileManager fileExistsAtPath:path]) {  
  341.         NSDictionary *fileDic = [fileManager attributesOfItemAtPath:path error:nil];//获取文件的属性  
  342.         unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue];  
  343.         filesize = (1.0*size/1024)/1024.0;  
  344.           
  345.     }  
  346.     return filesize;  
  347. }  
  348.   
  349. //获取视频文件的时长。  
  350. - (CGFloat)getVideoLength:(NSURL *)URL{  
  351.     NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]  
  352.                                                      forKey:AVURLAssetPreferPreciseDurationAndTimingKey];  
  353.     AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:URL options:opts];  
  354.     float second = 0;  
  355.     second = urlAsset.duration.value/urlAsset.duration.timescale;  
  356.     return second;  
  357.       
  358. }  
  359.   
  360. //获取本地视频缩略图,网上说需要添加AVFoundation.framework  
  361. - (UIImage *)getImage:(NSURL *)URL{  
  362.       
  363.     AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:URL options:nil];  
  364.     AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];  
  365.     gen.appliesPreferredTrackTransform = YES;  
  366.     CMTime time = CMTimeMakeWithSeconds(0.0600);  
  367.     NSError *error = nil;  
  368.     CMTime actualTime;  
  369.     CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];  
  370.     UIImage *thumb = [[UIImage alloc] initWithCGImage:image];  
  371.     CGImageRelease(image);  
  372.       
  373.     return thumb;  
  374. }  
  375.   
  376. @end  
0 0
原创粉丝点击