Problems with AvMutableComposition having a black border at the end

I am recording a video using AVCaptureConnection in my iOS application. After that, I add some images to the video as CALayers. Everything works fine, but I get a black frame at the very end of the resulting video after adding the images. This is not the scope of the actual audio / video. For audio, I extract it and change its pitch, and then add it using AVMutableComposition. Here is the code I'm using. Please help me with what I am doing wrong, or I need to add something else.

cmp = [AVMutableComposition composition]; AVMutableCompositionTrack *videoComposition = [cmp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; AVMutableCompositionTrack *audioComposition = [cmp addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVAssetTrack *sourceAudioTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; [videoComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil] ; [audioComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceAudioTrack atTime:kCMTimeZero error:nil]; animComp = [AVMutableVideoComposition videoComposition]; animComp.renderSize = CGSizeMake(320, 320); animComp.frameDuration = CMTimeMake(1,30); animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; // to gather the audio part of the video NSArray *tracksToDuck = [cmp tracksWithMediaType:AVMediaTypeAudio]; NSMutableArray *trackMixArray = [NSMutableArray array]; for (NSInteger i = 0; i < [tracksToDuck count]; i++) { AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:[tracksToDuck objectAtIndex:i]]; [trackMix setVolume:5 atTime:kCMTimeZero]; [trackMixArray addObject:trackMix]; } audioMix = [AVMutableAudioMix audioMix]; audioMix.inputParameters = trackMixArray; AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]); AVMutableVideoCompositionLayerInstruction *layerVideoInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoComposition]; [layerVideoInstruction setOpacity:1.0 atTime:kCMTimeZero]; instruction.layerInstructions = [NSArray arrayWithObject:layerVideoInstruction] ; animComp.instructions = [NSArray arrayWithObject:instruction]; [self exportMovie:self]; 

This is my method for exporting video

 -(IBAction) exportMovie:(id)sender{ //successCheck = NO; NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *tempPath = [docPaths objectAtIndex:0]; //NSLog(@"Temp Path: %@",tempPath); NSString *fileName = [NSString stringWithFormat:@"%@/Final.MP4",tempPath]; NSFileManager *fileManager = [NSFileManager defaultManager] ; if([fileManager fileExistsAtPath:fileName ]){ NSError *ferror = nil ; [fileManager removeItemAtPath:fileName error:&ferror]; } NSURL *exportURL = [NSURL fileURLWithPath:fileName]; AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:cmp presetName:AVAssetExportPresetMediumQuality] ; exporter.outputURL = exportURL; exporter.videoComposition = animComp; //exporter.audioMix = audioMix; exporter.outputFileType = AVFileTypeQuickTimeMovie; [exporter exportAsynchronouslyWithCompletionHandler:^(void){ switch (exporter.status) { case AVAssetExportSessionStatusFailed:{ NSLog(@"Fail"); break; } case AVAssetExportSessionStatusCompleted:{ NSLog(@"Success video"); }); break; } default: break; } }]; NSLog(@"outside"); } 
+5
source share
3 answers

there is an export property to provide a time range, try giving the time range a little less than the actual time (a little less than nano seconds)

+4
source

Thanks for khushboo. I have the same problem. Like my test. This problem occurs only in version 10.7 sys. 10.8 do not have. over a given range of time an export session solves this problem.

+2
source

Just wanted to write this for people with my particular problem.

I have an AVMutableComposition video and tried to speed up / slow it down using AVMutableComposition and scaling the time range of audio and video components using scaleTimeRange

Scaling the time range to 2x or 3x speed sometimes led to the fact that the last few frames of the video turned black. Fortunately, @Khushboo's answer also solved my problem.

However, instead of decreasing the timeRange exporter by a few milliseconds, I just made it the same as the duration of the composition, which ended up working fine.

 exporter?.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: composition.duration) 

Hope this helps!

0
source

All Articles