AVAssetExportSession exportAsynchronouslyWithCompletionHandler有时不起作用

时间:2015-01-19 08:48:59

标签: ios objective-c

我想从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");
    }

1 个答案:

答案 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)。

但我不知道为什么它可以正常工作。