您的位置:首页 > 移动开发 > IOS开发

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

2016-11-14 15:50 561 查看
iOS从相册获取以及用相机拍摄视频并缓存到沙盒

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

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

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

[objc] view
plain copy

print?





#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 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 charchar *cvideoPath = [videoPath UTF8String];

FILEFILE *file = fopen(cvideoPath, "a+");

if (file) {

const int bufferSize = 111024 * 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: