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

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

2016-03-01 14:04 1256 查看
[iOS]从相册获取以及用相机拍摄视频并缓存到沙盒

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
 
示意图:









内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: