Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 5: Error merging 3 videos with AVAssetExportSession

I'm trying to merge (append) 3 videos using AVAssetExportSession, but I keep getting this error. Weirdly for 1 or 2 videos it worked.

Error Domain=AVFoundationErrorDomain Code=-11820 "Cannot Complete Export" UserInfo=0x458120 {NSLocalizedRecoverySuggestion=Try exporting again., NSLocalizedDescription=Cannot Complete Export}

I even tried to redo the function in case of error but what I got is only infinite error message. This is the snippet of my code.

AVMutableComposition *mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSError * error = nil;
NSMutableArray * timeRanges = [NSMutableArray arrayWithCapacity:arrayMovieUrl.count];
NSMutableArray * tracks = [NSMutableArray arrayWithCapacity:arrayMovieUrl.count];

for (int i=0; i<[arrayMovieUrl count]; i++) {
    AVURLAsset *assetClip = [arrayMovieUrl objectAtIndex:i];
    AVAssetTrack *clipVideoTrackB = [[assetClip tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    [timeRanges addObject:[NSValue valueWithCMTimeRange:CMTimeRangeMake(kCMTimeZero, assetClip.duration)]];
    [tracks addObject:clipVideoTrackB];
}
[compositionTrack insertTimeRanges:timeRanges ofTracks:tracks atTime:kCMTimeZero error:&error];

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPreset1280x720];
NSParameterAssert(exporter != nil);
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.outputURL = outputUrl;
[exporter exportAsynchronouslyWithCompletionHandler:^{
    switch ([exporter status]) {
        case AVAssetExportSessionStatusFailed:
            NSLog(@"Export failed: %@", [exporter error]);
            break;
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"Export canceled");
            break;
        case AVAssetExportSessionStatusCompleted:
            NSLog(@"Export successfully");
            break;
        default:
            break;
    }
    if (exporter.status != AVAssetExportSessionStatusCompleted){
        NSLog(@"Retry export");
        [self renderMovie];
    }
}];

Is there something wrong with my code or iOS 5 has some bug?

like image 922
vangoz Avatar asked Mar 30 '12 11:03

vangoz


1 Answers

I've found the problem. So the problem was actually because I use AVPlayerLayer to display each video in preview mode simultaneously. Referring to this question AVPlayerItem fails with AVStatusFailed and error code "Cannot Decode" , there's undocumented limit of maximum 4 simultaneous AVPlayer to work. And this limit somehow hinders AVAssetExportSession from working when there's 4 AVPlayer instance at that moment.

The solution is to release the AVPlayer before exporting, or not using AVPlayer altogether.

like image 170
vangoz Avatar answered Sep 29 '22 08:09

vangoz