As far as I know, AVMutableVideoCompositionLayerInstruction cannot just be added or added as your code.
From your code, I think you want to save information about video instructions when merging video assets, but instructions cannot be directly copied.
If you want to do this, see the docs for AVVideoCompositionLayerInstruction , for example.
getTransformRampForTime:startTransform:endTransform:timeRange: setTransformRampFromStartTransform:toEndTransform:timeRange: setTransform:atTime: getOpacityRampForTime:startOpacity:endOpacity:timeRange: setOpacityRampFromStartOpacity:toEndOpacity:timeRange: setOpacity:atTime: getCropRectangleRampForTime:startCropRectangle:endCropRectangle:timeRange: setCropRectangleRampFromStartCropRectangle:toEndCropRectangle:timeRange: setCropRectangle:atTime:
You should use the getFoo... methods on the source track, and then output insertTime or timeRange for the final track, then setFoo... , and then add the final video composition to layerInstructions.
YES, a little complicated ... Also, most importantly, you cannot get all the video effects that apply to the original resource.
So what is your goal? And what is your source resource with support?
If you just want to merge some mp4 / mov files, just loop the tracks and add them to AVMutableCompositionTrack , no videoComposition . And I checked your code, it works.
If you want to combine AVAssets, which with video instructions, see above explanation and docs . And my best practice is, before merging, save these AVAssets to a file using AVAssetExportSession , and then just merge the video files.
ps Maybe there are some problems with your test files or source resources.
The code for my project like Vine is:
- (BOOL)generateComposition { [self cleanComposition]; NSUInteger segmentsCount = self.segmentsCount; if (0 == segmentsCount) { return NO; } AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableVideoComposition *videoComposition = nil; AVMutableVideoCompositionInstruction *videoCompositionInstruction = nil; AVMutableVideoCompositionLayerInstruction *videoCompositionLayerInstruction = nil; AVMutableAudioMix *audioMix = nil; AVMutableCompositionTrack *videoTrack = nil; AVMutableCompositionTrack *audioTrack = nil; AVMutableCompositionTrack *musicTrack = nil; CMTime currentTime = kCMTimeZero; for (MVRecorderSegment *segment in self.segments) { AVURLAsset *asset = segment.asset; NSArray *videoAssetTracks = [asset tracksWithMediaType:AVMediaTypeVideo]; NSArray *audioAssetTracks = [asset tracksWithMediaType:AVMediaTypeAudio]; CMTime maxBounds = kCMTimeInvalid; CMTime videoTime = currentTime; for (AVAssetTrack *videoAssetTrack in videoAssetTracks) { if (!videoTrack) { videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; videoTrack.preferredTransform = CGAffineTransformIdentity; videoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; videoCompositionLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; } CGAffineTransform transform = videoAssetTrack.preferredTransform; if (AVCaptureDevicePositionFront == segment.cameraPosition) { transform = CGAffineTransformMakeTranslation(self.config.videoSize, 0); transform = CGAffineTransformScale(transform, -1.0, 1.0); } else if (AVCaptureDevicePositionBack == segment.cameraPosition) { } [videoCompositionLayerInstruction setTransform:transform atTime:videoTime]; videoTime = [MVHelper appendAssetTrack:videoAssetTrack toCompositionTrack:videoTrack atTime:videoTime withBounds:maxBounds]; maxBounds = videoTime; } if (self.sessionConfiguration.originalVoiceOn) { CMTime audioTime = currentTime; for (AVAssetTrack *audioAssetTrack in audioAssetTracks) { if (!audioTrack) { audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; } audioTime = [MVHelper appendAssetTrack:audioAssetTrack toCompositionTrack:audioTrack atTime:audioTime withBounds:maxBounds]; } } currentTime = composition.duration; } if (videoCompositionInstruction && videoCompositionLayerInstruction) { videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration); videoCompositionInstruction.layerInstructions = @[videoCompositionLayerInstruction]; videoComposition = [AVMutableVideoComposition videoComposition]; videoComposition.renderSize = CGSizeMake(self.config.videoSize, self.config.videoSize); videoComposition.frameDuration = CMTimeMake(1, self.config.videoFrameRate); videoComposition.instructions = @[videoCompositionInstruction]; }