为什么我从相册导出的视频总是提示压缩失败?

最近公司项目加了一个从相册导入视频的功能,想把相册视频压缩并转码成MP4格式上传,但是总是提示上传失败
获取相册选取的视频的代码如下

 - (IBAction)getVideos:(id)sender {
    ZZPhotoController* photoController = [[ZZPhotoController alloc] init];
    photoController.isVideo = YES;
    photoController.selectPhotoOfMax = 1;
    //设置相册中完成按钮旁边小圆点颜色。
    photoController.roundColor = [UIColor greenColor];

    WS(weakSelf)
    [photoController showIn:self result:^(id responseObject)
     {
         NSArray* array = (NSArray *)responseObject;
         PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
         options.version = PHVideoRequestOptionsVersionOriginal;
         options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
         PHAsset *phasset =  [array firstObject];

         if (phasset.mediaType != PHAssetResourceTypeVideo) {
             [SVProgressHUD showInfoWithStatus:@"请上传一个视频"];
         }else if(phasset.duration > 20){
             [SVProgressHUD showInfoWithStatus:@"视频时间不能超过20s"];
         }else if (phasset.duration < 3) {
             [SVProgressHUD showInfoWithStatus:@"视频时间不能小于3s"];
         }else {
             [[PHImageManager defaultManager] requestAVAssetForVideo:phasset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {

                 AVURLAsset * urlAsset = (AVURLAsset *)asset;

                 NSURL *string = urlAsset.URL;
                 NSData *data = [NSData dataWithContentsOfURL:string];

                 if(data.length > 10*1024*1024){
                     dispatch_sync(dispatch_get_main_queue(), ^{
                         [SVProgressHUD showInfoWithStatus:@"视频大小不能超过10M"];
                     });

                 }else{

                     [self.videoRecorder compressVideoUrl:urlAsset.URL];
                 }
             }];
         }
     } failure:nil];
}

之前项目中有录制视频的功能,录制视频之后进行压缩转码的代码如下

 #pragma mark - compress 压缩

- (void)compressVideoUrl:(NSURL *)url{

    AVAsset *asset = [AVAsset assetWithURL:url];

    if (asset.duration.value / asset.duration.timescale < MIN_TIME){
        if ([_delegate respondsToSelector:@selector(recordDidTimeShort)]) {
            [_delegate recordDidTimeShort];
        }

        //删除文件
        NSFileManager *fileManager = [NSFileManager defaultManager];
        [fileManager removeItemAtURL:url error:nil];

        return;
    }
    //显示菊花
    [ZZPhotoHud setTitle:@"视频处理中..."];
    [ZZPhotoHud showActiveHud];

    AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];

    CGFloat minValue = MIN(assetTrack.naturalSize.width, assetTrack.naturalSize.height);

    CGSize renderSize = CGSizeMake(minValue,minValue * 3 / 4  );


    AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

        NSError *audioError;
        NSError *videoError;
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                        ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] firstObject]
                         atTime:kCMTimeZero
                          error:&audioError];
    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                        ofTrack:assetTrack
                         atTime:kCMTimeZero
                          error:&videoError];


    AVMutableVideoCompositionLayerInstruction *layerInst = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

    CGFloat rate = 1.0;

    CGAffineTransform layerTransform = CGAffineTransformMake(assetTrack.preferredTransform.a, assetTrack.preferredTransform.b, assetTrack.preferredTransform.c, assetTrack.preferredTransform.d, assetTrack.preferredTransform.tx * rate, assetTrack.preferredTransform.ty );
    layerTransform = CGAffineTransformConcat(layerTransform, CGAffineTransformMake(1, 0, 0, 1, 0, -(assetTrack.naturalSize.width - assetTrack.naturalSize.height) / 2.0));//向上移动取中部影响
    layerTransform = CGAffineTransformScale(layerTransform, rate, rate);//放缩,解决前后摄像结果大小不对称



    [layerInst setTransform:layerTransform atTime:kCMTimeZero];
    [layerInst setOpacity:0.0 atTime:asset.duration];


    AVMutableVideoCompositionInstruction *mainInst = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    mainInst.layerInstructions = @[layerInst];
    mainInst.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);

    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.instructions = @[mainInst];
    videoComposition.renderSize = renderSize;
    videoComposition.frameDuration = CMTimeMake(1, 30);


    //系统的
//    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
//    exportSession.videoComposition = videoComposition;
//    exportSession.outputFileType = AVFileTypeMPEG4;
//    NSURL *outFileUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",[url.relativePath stringByReplacingOccurrencesOfString:@"mov" withString:@"mp4"]]];
//    exportSession.outputURL = outFileUrl;
//    [exportSession exportAsynchronouslyWithCompletionHandler:^{
//       
//        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
//            NSLog(@"压缩成功啦~~");
//            NSFileManager *fileManager = [NSFileManager defaultManager];
//            [fileManager removeItemAtURL:url error:nil];
//            
//            if ([_delegate respondsToSelector:@selector(recordDidFinishOutFileAtUrl:)]) {
//                [_delegate recordDidFinishOutFileAtUrl:exportSession.outputURL];
//            }
//
//        }
//        else{
//            NSLog(@"压缩失败 %@",exportSession.error);
//        }
//        
//    }];
    //第三方的
    SDAVAssetExportSession *session = [SDAVAssetExportSession exportSessionWithAsset:mixComposition];
    session.videoComposition = videoComposition;
    session.outputFileType = AVFileTypeMPEG4;
    session.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",[url.relativePath stringByReplacingOccurrencesOfString:@"mov" withString:@"mp4"]]];;
    //    session.delegate = self;
    session.videoSettings = @{
                              AVVideoCodecKey:AVVideoCodecH264,
                              AVVideoWidthKey:@1000,//[NSNumber numberWithInteger:CGRectGetWidth(_bgView.frame)],
                              AVVideoHeightKey:@750,//[NSNumber numberWithInteger:CGRectGetHeight(_bgView.frame)],
                              AVVideoCompressionPropertiesKey:@{
                                      AVVideoAverageBitRateKey:@1000000,
                                      AVVideoProfileLevelKey:AVVideoProfileLevelH264High41
                                      }
                              };

    session.audioSettings = @{
                              AVFormatIDKey:@(kAudioFormatMPEG4AAC),
                              AVNumberOfChannelsKey:@2,
                              AVSampleRateKey:@16000,
                              AVEncoderBitRateKey:@64000,
                              };

    [session exportAsynchronouslyWithCompletionHandler:^{

        if (AVAssetExportSessionStatusCompleted == session.status) {
            NSLog(@"压缩成功啦~~");
            dispatch_async(dispatch_get_main_queue(), ^{

                if ([_delegate respondsToSelector:@selector(recordDidFinishOutFileAtUrl:)]) {
                    [_delegate recordDidFinishOutFileAtUrl:session.outputURL];
                }
                //删除文件
                NSFileManager *fileManager = [NSFileManager defaultManager];
                [fileManager removeItemAtURL:url error:nil];

            });

        }
        else{
            NSLog(@"压缩失败 %@",session.error);
        }
    }];
}

我也是调用的这个方法,传入的是从相册获取的视频的URL,但是回调方法总是显示压缩失败,求大神解救

阅读 13.2k
1 个回答

您倒是把session.error的输出也贴出来吧?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题