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