I am combining several videos and several compositions, and I get the bot what is wrong in the code, because the same code worked absolutely fine yesterday, but today I get the following answer AVAssetExportSessionStatus = 4,error = Error Domain=AVFoundationErrorDomain Code=-11841 "The operation couldn't be completed. (AVFoundationErrorDomain error -11841.)" I did some research and found that the export was failing due to invalid video composition. Please find out what is wrong with the video composition.
- (void)mergeAllselectedVideos { NSArray *pathArray = [DocumentDirectory getUrlFromDocumentDirectoryOfList:self.selectedClipsArray]; AVMutableComposition *mixComposition = [[AVMutableComposition alloc]init]; NSMutableArray *layerinstructions = [[NSMutableArray alloc]init]; CMTime time = kCMTimeZero; CMTime previousSongDuration = kCMTimeZero; for (int i = 0 ; i < pathArray.count; i++) { //VIDEO TRACK// time = CMTimeAdd(time, previousSongDuration); NSURL *url = [NSURL URLWithString:[pathArray objectAtIndex:i]]; AVAsset *avAsset = [AVAsset assetWithURL:url]; AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; [track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:[[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time error:nil]; previousSongDuration = avAsset.duration; } CMTime audioTime = kCMTimeZero; for (int i = 0; i < self.selectedSongsArray.count; i++) { MPMediaItem * songItem = [self.selectedSongsArray objectAtIndex:i]; NSURL *songURL = [songItem valueForProperty: MPMediaItemPropertyAssetURL]; AVAsset *audioAsset = [AVAsset assetWithURL:songURL]; AVMutableCompositionTrack *AudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; CMTimeRange timeRange = CMTimeRangeMake(audioTime, audioAsset.duration); if(CMTimeGetSeconds(CMTimeAdd(audioTime, audioAsset.duration)) > CMTimeGetSeconds(time)) { timeRange = CMTimeRangeMake(audioTime, CMTimeSubtract(time,audioTime)); } [AudioTrack insertTimeRange:timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil]; audioTime = CMTimeAdd(audioTime, audioAsset.duration); } AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, time); MainInstruction.layerInstructions = layerinstructions; AVMutableVideoComposition *MainCompositionInst = [AVMutableVideoComposition videoComposition]; MainCompositionInst.instructions = [NSArray arrayWithObject:MainInstruction]; MainCompositionInst.frameDuration = CMTimeMake(1, 30); MainCompositionInst.renderSize = CGSizeMake(320.0, 480.0); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; movieName = [CoreDataFunctions getNameForMovieForDate:[CalendarFunctions getCurrentDateString]]; self.moviePlayButton.titleLabel.text = movieName; NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:movieName]; NSURL *url = [NSURL fileURLWithPath:myPathDocs]; AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality]; exporter.outputURL=url; exporter.outputFileType = AVFileTypeQuickTimeMovie; exporter.videoComposition = MainCompositionInst; exporter.shouldOptimizeForNetworkUse = YES; [exporter exportAsynchronouslyWithCompletionHandler:^{dispatch_async(dispatch_get_main_queue(), ^{[self exportDidFinish:exporter];});}]; } - (void)exportDidFinish:(AVAssetExportSession*)session { //Printing error NSLog(@"AVAssetExportSessionStatus = %i,error = %@",session.status,session.error); }
Shubham sharma
source share