I have got two audio tracks on me that I combine with one another like this:
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
AVMutableC
In swift with repeat whiel
Loop.
fix video length isuue
let audioLength = CMTime(value: 100, timescale: 1)
let videoLength = CMTime(value: 220, timescale: 1)
func getAudioRepeatInfo(audioLength:CMTime, videoLength:CMTime) -> [(at:CMTime, duration:CMTime)] {
var at = [(at:CMTime, duration:CMTime)](), start = CMTime.zero
repeat {
let info = (at:start, duration: min(CMTimeSubtract(videoLength, start), audioLength) )
at.append(info)
start = CMTimeAdd(start, info.duration)
} while start < videoLength
return at
}
var ranges = getAudioRepeatInfo(audioLength: audioLength, videoLength: videoLength)
Playground Output:
[(at: __C.CMTime(value: 0, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0), duration: __C.CMTime(value: 100, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0)),
(at: __C.CMTime(value: 100, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0), duration: __C.CMTime(value: 100, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0)),
(at: __C.CMTime(value: 200, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0), duration: __C.CMTime(value: 20, timescale: 1, flags: __C.CMTimeFlags(rawValue: 1), epoch: 0))]
Use:
for info in repeatInfo {
try compositionAudioTrack1?.insertTimeRange(.init(start: .zero, duration: info.duration), of: assetTrack, at: info.at)
}
I think it should work:
CMTime videoDuration = avAsset.duration;
if(CMTimeCompare(videoDuration, audioAsset.duration) == -1){
[compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack1 atTime:kCMTimeZero error:nil];
}else if(CMTimeCompare(videoDuration, audioAsset.duration) == 1){
CMTime currentTime = kCMTimeZero;
while(YES){
CMTime audioDuration = audioAsset.duration;
CMTime totalDuration = CMTimeAdd(currentTime,audioDuration);
if(CMTimeCompare(totalDuration, videoDuration)==1){
audioDuration = CMTimeSubtract(totalDuration,videoDuration);
}
[compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioDuration) ofTrack:clipAudioTrack1 atTime:currentTime error:nil];
currentTime = CMTimeAdd(currentTime, audioDuration);
if(CMTimeCompare(currentTime, videoDuration) == 1 || CMTimeCompare(currentTime, videoDuration) == 0){
break;
}
}
}
On the Gaurav response you should change this line:
audioDuration = CMTimeSubtract(totalDuration,videoDuration);
to:
audioDuration = CMTimeSubtract(videoDuration,currentTime);
Otherwise the audiotrack will be longer than the video ( that will be just black )