I am mixing an audio and video file using AVMutableComposition. Below is my code for that:
enter code here
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSString *bundleDirectory = [[NSBundle mainBundle] bundlePath];
NSString *audio_inputFilePath = [bundleDirectory stringByAppendingPathComponent:@"xyz.mp3"];//audio of 35 seconds
NSURL *audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath];
NSURL *video_inputFileUrl = [NSURL fileURLWithPath:videoOutputPath];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:@"video.mp4"];//video of 60 seconds
NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
CMTime nextClipStartTime = kCMTimeZero;
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:video_inputFileUrl options:nil];
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,videoAsset.duration);
AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil];
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
enter code here
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
enter code here
AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:nextClipStartTime error:nil];
enter code here
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPreset640x480];
Issue i am facing is my audio file duration is shorter than the video duration. So what i want to do is loop the audio file till the video ends. Like my video is is 60 seconds and audio is 35 seconds, so the audio should repeat for 25 seconds.
Can anyone help me how this can be done.
Solution 1: Create a new CMTimeRange
and insertTimeRange
in AVMutableCompositionTrack
if (videoAsset.duration>audioAsset.duration)
{
//new time range
CMTime duration = CMTimeMakeWithSeconds(CMTimeGetSeconds(videoAsset.duration)-CMTimeGetSeconds(audioAsset.duration), audioAsset.duration.timescale);
if (CMTIME_IS_VALID(duration))
{
CMTimeRange video_timeRange2 = CMTimeRangeMake(audioAsset.duration,duration);
//start from where left
CMTime nextClipStartTime2 = audioAsset.duration;
//add in AVMutableCompositionTrack
[b_compositionVideoTrack insertTimeRange:video_timeRange2 ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime2 error:nil];
}
else
NSLog(@"time is invalid");
}
NOTE: not tested but it should work.
EDIT:
Solution 2: Try this. Don't use my code and replace this line below with yours
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeInvalid error:nil];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With