Skip to content

Instantly share code, notes, and snippets.

@maximveksler
Created February 25, 2014 23:36
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save maximveksler/9220316 to your computer and use it in GitHub Desktop.
Save maximveksler/9220316 to your computer and use it in GitHub Desktop.
Fucking AV Foundation code with audio and video mixing
- (void)buildTransitionCompositionAUDIO:(AVMutableComposition *)composition andVideoComposition:(AVMutableVideoComposition *)videoComposition andAudioMix:(AVMutableAudioMix *)audioMix
{
CMTime nextClipStartTime = kCMTimeZero;
// Add two video tracks and two audio tracks.
AVMutableCompositionTrack *compositionVideoTracks[2];
AVMutableCompositionTrack *compositionAudioTracks[2];
compositionVideoTracks[0] = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
compositionVideoTracks[1] = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
compositionAudioTracks[0] = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
compositionAudioTracks[1] = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// CMTimeRange *passThroughTimeRanges = alloca(sizeof(CMTimeRange) * clipsCount);
// CMTimeRange *transitionTimeRanges = alloca(sizeof(CMTimeRange) * clipsCount);
AVURLAsset *asset;
NSInteger alternatingIndex;
CMTimeRange timeRangeInAsset;
AVAssetTrack *clipVideoTrack;
AVAssetTrack *clipAudioTrack;
const CMTime duration = CMTimeMakeWithSeconds(18, 60000);
NSError *error;
alternatingIndex = 0;
asset = [self.clips objectAtIndex:0];
timeRangeInAsset = CMTimeRangeMake(kCMTimeZero, duration);
clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTracks[alternatingIndex] insertTimeRange:timeRangeInAsset ofTrack:clipVideoTrack atTime:nextClipStartTime error:&error];
clipAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTracks[alternatingIndex] insertTimeRange:timeRangeInAsset ofTrack:clipAudioTrack atTime:nextClipStartTime error:&error];
alternatingIndex = 1;
asset = [self.clips objectAtIndex:1];
timeRangeInAsset = CMTimeRangeMake(kCMTimeZero, duration);
clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTracks[alternatingIndex] insertTimeRange:timeRangeInAsset ofTrack:clipVideoTrack atTime:nextClipStartTime error:&error];
clipAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTracks[alternatingIndex] insertTimeRange:timeRangeInAsset ofTrack:clipAudioTrack atTime:nextClipStartTime error:&error];
// Set up the video composition if we are to perform crossfade transitions between clips.
alternatingIndex = 0;
NSMutableArray *instructions = [NSMutableArray array];
AVMutableVideoCompositionInstruction *transitionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
transitionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, duration);
AVMutableVideoCompositionLayerInstruction *fromLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTracks[alternatingIndex]];
AVMutableVideoCompositionLayerInstruction *toLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTracks[1-alternatingIndex]];
// Fade in the toLayer by setting a ramp from 0.0 to 1.0.
[fromLayer setOpacityRampFromStartOpacity:1.0 toEndOpacity:0.0 timeRange:CMTimeRangeMake(kCMTimeZero, duration)];
[toLayer setOpacityRampFromStartOpacity:0.0 toEndOpacity:1.0 timeRange:CMTimeRangeMake(kCMTimeZero, duration)];
transitionInstruction.layerInstructions = [NSArray arrayWithObjects:toLayer, fromLayer, nil];
[instructions addObject:transitionInstruction];
// Add X audio mix
NSMutableArray *trackMixArray = [NSMutableArray array];
AVMutableAudioMixInputParameters *audioMixInputParameters[2];
audioMixInputParameters[0] = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTracks[0]];
audioMixInputParameters[1] = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTracks[1]];
AVMutableAudioMixInputParameters *trackMix1 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTracks[0]];
[trackMix1 setVolumeRampFromStartVolume:0.0 toEndVolume:1.0 timeRange:CMTimeRangeMake(kCMTimeZero, duration)];
[trackMixArray addObject:trackMix1];
AVMutableAudioMixInputParameters *trackMix2 = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:compositionAudioTracks[1]];
[trackMix2 setVolumeRampFromStartVolume:5.0 toEndVolume:5.0 timeRange:CMTimeRangeMake(kCMTimeZero, duration)];
[trackMixArray addObject:trackMix2];
audioMix.inputParameters = trackMixArray;
videoComposition.instructions = instructions;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment