Ios 如何使轨道的某一部分循环?

Ios 如何使轨道的某一部分循环?,ios,objective-c,audio,avaudioplayer,Ios,Objective C,Audio,Avaudioplayer,我有一个包含介绍(0:00-0:10)和循环部分(0:10-0:30)的音乐文件。有许多库和简单的解决方案可以从结束->开始循环一个轨迹,但是我很难找到从结束->开始循环一个轨迹的方法。实现这一目标的最佳方式是什么 下面是我根据下面的评论正在使用的代码。循环时仍会产生一个小间隙: _player = [AVPlayer playerWithURL:url]; Float64 durationSeconds = CMTimeGetSeconds([asset duration]); CMTime

我有一个包含介绍(0:00-0:10)和循环部分(0:10-0:30)的音乐文件。有许多库和简单的解决方案可以从结束->开始循环一个轨迹,但是我很难找到从结束->开始循环一个轨迹的方法。实现这一目标的最佳方式是什么

下面是我根据下面的评论正在使用的代码。循环时仍会产生一个小间隙:

_player = [AVPlayer playerWithURL:url];
Float64 durationSeconds = CMTimeGetSeconds([asset duration]);
CMTime loopStart = CMTimeMakeWithSeconds(19.2, 1);
CMTime loopEnd = CMTimeMakeWithSeconds(durationSeconds, 1);
NSArray *times = @[[NSValue valueWithCMTime:loopEnd]];

__weak typeof(AVPlayer *)weakPlayer = _player;
self.playerObserver = [_player addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
    [weakPlayer seekToTime:loopStart];
}];

[_player play];

如果可以从AVAudioPlayer切换到AVPlayer,则可以使用
addBoundaryObserverForTimes:

从:

请求在遍历指定时间时调用块 在正常播放期间


< AV基础编程指南对如何使用该方法的代码示例进行了解释:

最后,ObjectAL演示了一个演示项目,它使用两个单独的音频文件来播放和插入,然后在回放中没有回音的情况下循环一首歌曲的主体。我已将其修改为使用单个音频文件:

+(ALBuffer *)bufferFromFile:(NSString *)filePath startTime:(float)startTime endTime:(float)endTime
{
    NSURL *url = [OALTools urlForPath:filePath];
    OALAudioFile *file = [[OALAudioFile alloc] initWithUrl:url reduceToMono:NO];

    // Convert the start and end times into frames
    NSInteger startFrame = startTime*file.streamDescription->mSampleRate;
    NSInteger endFrame = (endTime-startTime)*file.streamDescription->mSampleRate;///file.totalFrames-(endTime*file.streamDescription->mSampleRate);

    ALBuffer* buffer = [file bufferNamed:[url description]
                              startFrame:startFrame
                               numFrames:endFrame];
    //as_release(file); // I've commented this out, but I suspect there may be some kind of leak here. Can anyone comment on how to properly release this memory?
    return buffer;
}

-(void)playBackgroundMusic:(NSString *)file withIntroThatLoopsAt:(CGFloat)seconds
{
    // Uses OpenAL for both the intro and the main loop.
    // Uses a callback to start the main loop playing.
    // Note: This only works on iOS 5+.

    _source = [ALSource source];
    _introBuffer= [JAudioEngine bufferFromFile:file startTime:0 endTime:seconds];
    _mainBuffer = [JAudioEngine bufferFromFile:file startTime:seconds endTime:-1];

    [self stop];

    __block typeof(self) blockSelf = self;
    [_source registerNotification:AL_BUFFERS_PROCESSED
                             callback:^(__unused ALSource *source, __unused ALuint notificationID, __unused ALvoid *userData)
                             {
                                 [blockSelf.source play:blockSelf.mainBuffer loop:YES];
                                 [blockSelf.source unregisterAllNotifications];
                             }
                             userData:nil];

    [_source play:_introBuffer];
}

-(void)stop
{
    [_source unregisterAllNotifications];
    [_source stop];
}

你用的是什么音频播放器?您使用的播放机是否有可能收到播放结束的通知?如果是,那么当您的播放机到达终点时,只需通过编程将播放头放在所需的音频位置,然后播放它。这不难实现。我建议您使用
AVPlayer
执行此任务。祝你好运这是个好主意,但我还有差距。我使用的是m4a,所以它应该是硬件加速的。我需要做一些缓冲吗?在街区里寻找肯定是错误的,但我不知道还有什么其他选择。我已经用一些代码编辑了原始帖子。你在寻找什么?seekToTime:有几个重载,允许您指定精度。例如–seekToTime:tolerance before:tolerance after:completionHandler:我尝试过使用每个seekToTime方法,但没有发现任何差异。差距仍然存在。也许你注意到的差距是你花在寻找上的时间。也许你可以使用第二个AVPlayer,在你播放循环部分时进行搜索。在边界完成处理程序中,你可以切换到已经倒回正确位置的玩家。