Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repeat audio track if video duration in longer than audio duration

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.

like image 944
coder1010 Avatar asked Apr 26 '13 05:04

coder1010


1 Answers

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];
like image 132
Paresh Navadiya Avatar answered Nov 15 '22 15:11

Paresh Navadiya