循环AVMutableCompositionTrack

Ser*_*yov 1 cocoa-touch core-audio ios avmutablecomposition avasset

我有两个音轨,我就像这样相互结合:

AVMutableComposition *composition = [[AVMutableComposition alloc] init];

AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack setPreferredVolume:1.0];
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:originalContentURL options:nil];
AVAssetTrack *clipAudioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];

AVMutableCompositionTrack *compositionAudioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack1 setPreferredVolume:0.01];
NSString *soundOne1  =[[NSBundle mainBundle]pathForResource:@"jingle1" ofType:@"m4a"];
NSURL *url1 = [NSURL fileURLWithPath:soundOne1];
AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:url1 options:nil];
AVAssetTrack *clipAudioTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack1 atTime:kCMTimeZero error:nil];
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,第一个AVAsset是第二个轨道的基本长度,这意味着如果我有一个很长的第二个轨道,它将被切割,这正是我想要的方式.

但是,我需要能够循环第二个轨道,这样如果一个轨道太长,第二个轨道就会继续运行.我后来不得不将生成的曲目保存在光盘上,这也是一个重要因素.

经过一项研究,我发现在iOS中实际循环轨道没有方便的方法.其中一种方法是AVMutableComposition反复插入第二首曲目,但这对我来说听起来很奇怪.基于该主题的任何想法都将非常有用.

Gau*_*ngh 7

我认为它应该工作:

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;
           }
     }
}
Run Code Online (Sandbox Code Playgroud)


Min*_*rip 6

在Gaurav响应中你应该改变这一行:
audioDuration = CMTimeSubtract(totalDuration,videoDuration);
to:
audioDuration = CMTimeSubtract(videoDuration,currentTime);

否则,录音带将比视频长(只是黑色)