我想从iPod-Library导出和压缩视频,但“exportAsynchronouslyWithCompletionHandler”可以正常用于某些视频,而不适用于某些视频。它不起作用,也没有抛出异常。 但奇怪的是,如果我注释掉“setVideoComposition:”方法,“exportAsynchronouslyWithCompletionHandler”可以正常工作。 这是我的代码:
AVAsset *_videoAsset = [AVAsset assetWithURL:[NSURL URLWithString:filmElementModel.alassetUrl]];
CMTime assetTime = [_videoAsset duration];
AVAssetTrack *avAssetTrack = [[_videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
Float64 duration = CMTimeGetSeconds(assetTime);
AVMutableComposition *avMutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *avMutableCompositionTrack = [avMutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error = nil;
[avMutableCompositionTrack insertTimeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(0.0f, 30), CMTimeMakeWithSeconds(duration>8.0f?8.0f:duration, 30))
ofTrack:avAssetTrack
atTime:kCMTimeZero
error:&error];
AVMutableVideoComposition *avMutableVideoComposition = [AVMutableVideoComposition videoComposition];
avMutableVideoComposition.frameDuration = CMTimeMake(1, 30);
AVMutableVideoCompositionLayerInstruction *layerInstruciton = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:avMutableComposition.tracks[0]];
[layerInstruciton setTransform:[[[_videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform] atTime:kCMTimeZero];
[layerInstruciton setOpacity:0.0f atTime:[_videoAsset duration]];
AVMutableVideoCompositionInstruction *avMutableVideoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
[avMutableVideoCompositionInstruction setTimeRange:CMTimeRangeMake(kCMTimeZero, [avMutableComposition duration])];
avMutableVideoCompositionInstruction.layerInstructions = [NSArray arrayWithObject:layerInstruciton];
if (avAssetTrack.preferredTransform.a) {
NSLog(@"横向");
avMutableVideoComposition.renderSize = CGSizeMake(avAssetTrack.naturalSize.width, avAssetTrack.naturalSize.height);
}else
{
avMutableVideoComposition.renderSize = CGSizeMake(avAssetTrack.naturalSize.height, avAssetTrack.naturalSize.width);
}
avMutableVideoComposition.instructions = [NSArray arrayWithObject:avMutableVideoCompositionInstruction];
// the url for save video
NSString *outUrlString = ITTPathForBabyShotResource([NSString stringWithFormat:@"%@/%@.mp4",DATA_ENV.userModel.userId,filmElementModel.filmElementId]);
NSFileManager *fm = [[NSFileManager alloc] init];
if ([fm fileExistsAtPath:outUrlString]) {
NSLog(@"video is have. then delete that");
if ([fm removeItemAtPath:outUrlString error:&error]) {
NSLog(@"delete is ok");
}else {
NSLog(@"delete is no error = %@",error.description);
}
}
CGSize renderSize = CGSizeMake(1280, 720);
if (MIN(avAssetTrack.naturalSize.width, avAssetTrack.naturalSize.height)<720) {
renderSize =avAssetTrack.naturalSize;
}
long long fileLimite =renderSize.width*renderSize.height*(duration>8.0f?8.0f:duration)/2;
_avAssetExportSession = [[AVAssetExportSession alloc] initWithAsset:avMutableComposition presetName:AVAssetExportPreset1280x720];
[_avAssetExportSession setVideoComposition:avMutableVideoComposition];
[_avAssetExportSession setOutputURL:[NSURL fileURLWithPath:outUrlString]];
[_avAssetExportSession setOutputFileType:AVFileTypeQuickTimeMovie];
[_avAssetExportSession setFileLengthLimit: fileLimite];
[_avAssetExportSession setShouldOptimizeForNetworkUse:YES];
[_avAssetExportSession exportAsynchronouslyWithCompletionHandler:^(void){
switch (_avAssetExportSession.status) {
case AVAssetExportSessionStatusFailed:
{
}
break;
case AVAssetExportSessionStatusCompleted:
{
}
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"export cancelled");
break;
case AVAssetExportSessionStatusExporting:
NSLog(@"AVAssetExportSessionStatusExporting");
break;
case AVAssetExportSessionStatusWaiting:
NSLog(@"AVAssetExportSessionStatusWaiting");
break;
}
}];
if (_avAssetExportSession.status != AVAssetExportSessionStatusCompleted){
NSLog(@"Retry export");
}
答案 0 :(得分:1)
我解决了这个问题!
[avMutableCompositionTrack insertTimeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(0.0f, 30), CMTimeMakeWithSeconds(duration>8.0f?8.0f:duration, 30))
ofTrack:avAssetTrack
atTime:kCMTimeZero
error:&error];
我用CMTimeRangeMake(CMTimeMakeWithSeconds(0.1f,30)替换CMTimeRangeMake(CMTimeMakeWithSeconds(0.0f,30)。
但我不知道为什么它可以正常工作。