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

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

如题,本文只是为了获取视频数据源,以便后面能方便完成视频上传等操作。
需要导入AVFoundation.framework(获取数据源), MediaPlayer.framework(播放视频)

后面又写了一个:https://gamin.blog.csdn.net/article/details/104052672

#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
 

示意图:

 

 

 

 

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值