How to repeat audio track if video duration in longer than audio duration
Asked Answered
S

1

8

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.

Surgeon answered 26/4, 2013 at 5:42 Comment(1)
D
4

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];
Derringdo answered 26/4, 2013 at 6:13 Comment(2)
not working. your logic seems correct but still audio stops after 35 secondsSurgeon
i already tried with the b_composition. i used your logic. not the same lines. is it possible to add two audio tracks in the mixcomposition??Surgeon

© 2022 - 2024 — McMap. All rights reserved.