最近公司项目加了一个从相册导入视频的功能,想把相册视频压缩并转码成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,但是回调方法总是显示压缩失败,求大神解救
您倒是把session.error的输出也贴出来吧?