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

 应项目需求,需要实现本地选取并上传图片、音频和视频文件。

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

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

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

 

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

此处会用到一个类就是`MPMediaPickerController`来访问iPod Library.注意需要导入并实现相应的代理另外在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];
选择界面:

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

选中和取消代理回调:

#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 *)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)

本人邮箱[email protected]欢迎小伙伴一起讨论,学习,进步。





你可能感兴趣的:(音视频选择,AVURLAsset,MPMediaItem)