iOS从相册选择视频和保存视频到相册

时间:2024-03-11 14:50:56

最近,在做有关视频操作的功能。需要从相册选择视频,处理之后再保存到相册。

选择视频:

方式一:用系统的UIImagePickerController

贴代码:

 

  1.  
    - (void)selectAction{
  2.  
     
  3.  
    NSLog(@"从相册选择");
  4.  
    UIImagePickerController *picker=[[UIImagePickerController alloc] init];
  5.  
     
  6.  
    picker.delegate=self;
  7.  
    picker.allowsEditing=NO;
  8.  
    picker.videoMaximumDuration = 1.0;//视频最长长度
  9.  
    picker.videoQuality = UIImagePickerControllerQualityTypeMedium;//视频质量
  10.  
     
  11.  
    //媒体类型:@"public.movie" 为视频 @"public.image" 为图片
  12.  
    //这里只选择展示视频
  13.  
    picker.mediaTypes = [NSArray arrayWithObjects:@"public.movie", nil];
  14.  
     
  15.  
    picker.sourceType= UIImagePickerControllerSourceTypeSavedPhotosAlbum;
  16.  
     
  17.  
    [kCurNavController presentViewController:picker animated:YES completion:^{
  18.  
     
  19.  
    }];
  20.  
     
  21.  
    }
  22.  
    #pragma mark UIImagePickerControllerDelegate
  23.  
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
  24.  
     
  25.  
    NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaType];
  26.  
     
  27.  
    if ([mediaType isEqualToString:@"public.movie"]){
  28.  
    //如果是视频
  29.  
    NSURL *url = info[UIImagePickerControllerMediaURL];//获得视频的URL
  30.  
    NSLog(@"url %@",url);
  31.  
    self.videoUrl = url;
  32.  
    }
  33.  
     
  34.  
    [self dismissViewControllerAnimated:YES completion:nil];
  35.  
    }

选择视频:

方式二:利用三方库TZImagePickerController 

贴代码:

 

  1.  
    - (void)selectThreeKuAction{
  2.  
     
  3.  
    TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 columnNumber:4 delegate:nil pushPhotoPickerVc:YES];
  4.  
     
  5.  
    //展示相册中的视频
  6.  
    imagePickerVc.allowPickingVideo = YES;
  7.  
    //不展示图片
  8.  
    imagePickerVc.allowPickingImage = NO;
  9.  
    //不显示原图选项
  10.  
    imagePickerVc.allowPickingOriginalPhoto = NO;
  11.  
    //按时间排序
  12.  
    imagePickerVc.sortAscendingByModificationDate = YES;
  13.  
     
  14.  
    //选择完视频之后的回调
  15.  
    [imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage,id asset){
  16.  
     
  17.  
    //iOS8以后返回PHAsset
  18.  
    PHAsset *phAsset = asset;
  19.  
     
  20.  
    if (phAsset.mediaType == PHAssetMediaTypeVideo) {
  21.  
    //从PHAsset获取相册中视频的url
  22.  
    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
  23.  
    options.version = PHImageRequestOptionsVersionCurrent;
  24.  
    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
  25.  
    PHImageManager *manager = [PHImageManager defaultManager];
  26.  
    [manager requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
  27.  
    AVURLAsset *urlAsset = (AVURLAsset *)asset;
  28.  
     
  29.  
    NSURL *url = urlAsset.URL;
  30.  
    self.videoUrl = url;
  31.  
    NSLog(@"%@",url);
  32.  
    }];
  33.  
    }
  34.  
    }];
  35.  
    [kCurNavController presentViewController:imagePickerVc animated:YES completion:nil];
  36.  
    }

以上都得到了视频的URL,之后再操作就方便了。

 

裁剪视频:

 

  1.  
    //视频裁剪
  2.  
    - (void)cropWithVideoUrlStr:(NSURL *)videoUrl start:(CGFloat)startTime end:(CGFloat)endTime completion:(void (^)(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess))completionHandle
  3.  
    {
  4.  
    AVURLAsset *asset =[[AVURLAsset alloc] initWithURL:videoUrl options:nil];
  5.  
     
  6.  
    //获取视频总时长
  7.  
    Float64 duration = CMTimeGetSeconds(asset.duration);
  8.  
     
  9.  
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dafei.mp4"];
  10.  
    NSURL *outputURL = [NSURL fileURLWithPath:outputPath];
  11.  
     
  12.  
    //如果文件已经存在,先移除,否则会报无法存储的错误
  13.  
    NSFileManager *manager = [NSFileManager defaultManager];
  14.  
    [manager removeItemAtPath:outputPath error:nil];
  15.  
     
  16.  
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];
  17.  
    if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality])
  18.  
    {
  19.  
     
  20.  
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
  21.  
    initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
  22.  
     
  23.  
    exportSession.outputURL = outputURL;
  24.  
    //视频文件的类型
  25.  
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
  26.  
    //输出文件是否网络优化
  27.  
    exportSession.shouldOptimizeForNetworkUse = YES;
  28.  
     
  29.  
    //要截取的开始时间
  30.  
    CMTime start = CMTimeMakeWithSeconds(startTime, asset.duration.timescale);
  31.  
    //要截取的总时长
  32.  
    CMTime duration = CMTimeMakeWithSeconds(endTime - startTime,asset.duration.timescale);
  33.  
    CMTimeRange range = CMTimeRangeMake(start, duration);
  34.  
    exportSession.timeRange = range;
  35.  
     
  36.  
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
  37.  
    switch ([exportSession status]) {
  38.  
    case AVAssetExportSessionStatusFailed:
  39.  
    {
  40.  
    NSLog(@"合成失败:%@", [[exportSession error] description]);
  41.  
    completionHandle(outputURL, endTime, NO);
  42.  
    }
  43.  
    break;
  44.  
    case AVAssetExportSessionStatusCancelled:
  45.  
    {
  46.  
    completionHandle(outputURL, endTime, NO);
  47.  
    }
  48.  
    break;
  49.  
    case AVAssetExportSessionStatusCompleted:
  50.  
    {
  51.  
    //成功
  52.  
    completionHandle(outputURL, endTime, YES);
  53.  
     
  54.  
    }
  55.  
    break;
  56.  
    default:
  57.  
    {
  58.  
    completionHandle(outputURL, endTime, NO);
  59.  
    } break;
  60.  
    }
  61.  
    }];
  62.  
    }
  63.  
    }

处理完视频之后,把视频保存到相册:

方式一:

 

  1.  
    //保存视频到相册
  2.  
    - (void)writeVideoToPhotoLibrary:(NSURL *)url
  3.  
    {
  4.  
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
  5.  
     
  6.  
    [library writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error){
  7.  
    if (error == nil) {
  8.  
     
  9.  
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存成功" preferredStyle:UIAlertControllerStyleAlert];
  10.  
     
  11.  
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  12.  
     
  13.  
    }]];
  14.  
    [self presentViewController:alert animated:true completion:nil];
  15.  
     
  16.  
    }else{
  17.  
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存失败" preferredStyle:UIAlertControllerStyleAlert];
  18.  
     
  19.  
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  20.  
     
  21.  
    }]];
  22.  
    [self presentViewController:alert animated:true completion:nil];
  23.  
    }
  24.  
    }];
  25.  
    }
保存视频到相册,方式二:用下面这个方法

 

UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);

  1.  
    // 视频保存回调
  2.  
    - (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo: (void *)contextInfo {
  3.  
     
  4.  
    if (error == nil) {
  5.  
     
  6.  
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存成功" preferredStyle:UIAlertControllerStyleAlert];
  7.  
     
  8.  
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  9.  
     
  10.  
    }]];
  11.  
    [self presentViewController:alert animated:true completion:nil];
  12.  
     
  13.  
    }else{
  14.  
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存失败" preferredStyle:UIAlertControllerStyleAlert];
  15.  
     
  16.  
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  17.  
     
  18.  
    }]];
  19.  
    [self presentViewController:alert animated:true completion:nil];
  20.  
    }
  21.