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

iOS获取相册视频文件封面图 选取手机中的音频、视频文件并导出数据。

2017-03-09 16:17 645 查看
 应项目需求,需要实现本地选取并上传图片、音频和视频文件。

 其中选取图片这块有很多开源框架,不再赘述。本文主要是采用iOS自带的类MPMediaPickerController 来实现UIImagePickerController音频、视频文件的选取。

 首先需要说明的是,如果需求是需要从语音备忘录里面读取原有录音,那么是较难实现的。我在http://stackoverflow.com/questions/5265215/iphone-access-voice-memos-programmatically上有找到相关回答说目前暂时还不能实现,只能现场马上录制并上传。



 

So,那么就考虑是从iPod的音乐库中导出音乐。

此处会用到一个类就是`MPMediaPickerController`来访问iPod Library.注意需要导入<MediaPlayer/MediaPlayer.h>并实现相应的代理另外在info.plist里面需要加入权限Privacy
- Media Library Usage Description

简单初始化代码如下:

MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
picker.prompt = @"请选择您需要上传的歌曲";
picker.showsCloudItems = YES;           //是否显示下载项
picker.allowsPickingMultipleItems = NO; //是否多选
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];
选择界面:



选中和取消代理回调:

#pragma mark MPMediaPickerControllerDelegate
- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {

[mediaPicker dismissViewControllerAnimated:YES completion:nil];

}

- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {

[mediaPicker dismissViewControllerAnimated:YES completion:nil];
MPMediaItem *item = mediaItemCollection.items.firstObject;

[self convertToM4A:item];

NSLog(@"%@---%@-----", item.title, item.assetURL);
}


选中回调集合里面放的是`MPMediaItem`对象。每一个此对象都表示了一首歌曲的信息,可以通过MPMediaEntity来访问其属性,具体可以查看.h文件。

值得一提的是其中有一个assetURL属性,格式类似于这样:ipod-library://item/item.wav?id=3524634042900602222

此属性可以直接用于AVPlayer播放该音频,但是如果要通过该URL访问音频数据,则是不能实现的。

要想获取到本地的音频文件,需要用到AVAssetExportSession将其导出。具体操作代码如下

- (void)convertToM4A: (MPMediaItem *)song
{
NSURL *url = [song valueForProperty:MPMediaItemPropertyAssetURL];

AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil];

NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSLog(@"%@", documentsDirectoryPath);
NSLog (@"compatible presets for songAsset: %@",[AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]);

NSArray *ar = [AVAssetExportSession exportPresetsCompatibleWithAsset: songAsset];
NSLog(@"%@", ar);

AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
initWithAsset: songAsset
presetName: AVAssetExportPresetAppleM4A];

NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);

exporter.outputFileType = @"com.apple.m4a-audio";

NSString *exportFile = [documentsDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.m4a",[song valueForProperty:MPMediaItemPropertyTitle]]];

NSError *error1;

if([fileManager fileExistsAtPath:exportFile])
{
[fileManager removeItemAtPath:exportFile error:&error1];
}

NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager]enumeratorAtPath:documentsDirectoryPath];
for (NSString *fileName in enumerator)
{
NSLog(@"------%@", fileName);
}

NSURL* exportURL = [NSURL fileURLWithPath:exportFile];

exporter.outputURL = exportURL;

// do the export
[exporter exportAsynchronouslyWithCompletionHandler:^
{
NSData *data1 = [NSData dataWithContentsOfFile:exportFile];
double size = (long)data1.length / 1024. / 1024.;
NSString *title = song.title;
if ([[title stringByReplacingOccurrencesOfString:@" " withString:@""] isEqualToString:@""]) {

title = @"无名称音频";
}
title = [title stringByAppendingString:[NSString stringWithFormat:@"       %.2fM", size]];
dispatch_async(dispatch_get_main_queue(), ^{

self.audiolb.text = title;
});
//         NSLog(@"==================data1:%@",data1);

int exportStatus = exporter.status;

switch (exportStatus) {

case AVAssetExportSessionStatusFailed: {

// log error to text view
NSError *exportError = exporter.error;

NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);

break;
}

case AVAssetExportSessionStatusCompleted: {

NSLog (@"AVAssetExportSessionStatusCompleted");

break;
}

case AVAssetExportSessionStatusUnknown: {
NSLog (@"AVAssetExportSessionStatusUnknown");
break;
}
case AVAssetExportSessionStatusExporting: {
NSLog (@"AVAssetExportSessionStatusExporting");
break;
}

case AVAssetExportSessionStatusCancelled: {
NSLog (@"AVAssetExportSessionStatusCancelled");
break;
}

case AVAssetExportSessionStatusWaiting: {
NSLog (@"AVAssetExportSessionStatusWaiting");
break;
}

default:
{ NSLog (@"didn't get export status");
break;
}
}

}];
}
需注意在其他线程中操作UI时,应将UI操作用GCD放到主线程中。

视频选择其实用到的就是经常用的图片选择器,iOS中照片和摄像文件同样储存在相册中的,所有跟图片处理器的使用大同小异。

选择好UIImagePickerController的mediaTypes就好

UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = @[(NSString *)kUTTypeMovie];

picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];


有一点非常好的是,选中视频文件之后,系统会自动为我们导出并压缩一份文件,返回的URL也可以直接访问到本地文件。另外可以用MPMoviePlayerController对象来获取视频文件里的某一张图作为封面图。

#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

[picker dismissViewControllerAnimated:YES completion:nil];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {

[picker dismissViewControllerAnimated:YES completion:nil];

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if([mediaType isEqualToString:@"public.movie"])
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(@"found a video");

NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:videoURL options:NSDataReadingUncached error:&error];
if (!error) {

double size = (long)data.length / 1024. / 1024.;

self.vediolb.text = [NSString stringWithFormat:@"%.2fMB", size];
if (size > 30.0) {

//文件过大
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"视频文件不得大于30M" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancle = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancle];
[self presentViewController:alert animated:YES completion:nil];
} else {

//保存数据
//获取视频的thumbnail
MPMoviePlayerController *player = [[MPMoviePlayerController alloc]initWithContentURL:videoURL] ;
UIImage  *thumbnail = [player thumbnailImageAtTime:0.01 timeOption:MPMovieTimeOptionNearestKeyFrame];
player = nil;
self.vedioimage.image = thumbnail;
}
}

}
}


(欢迎随手给一颗星星哦~)本篇博客Demo地址https://github.com/xmy0010/DemoForCSDN               (TyunMediaPickerDemo)

本人邮箱18144200589@163.com欢迎小伙伴一起讨论,学习,进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息