AVAudioplayer播放中间可变暂停的声音列表

时间:2014-02-03 19:15:48

标签: ios objective-c audio avaudioplayer nstimer

我是一名Rails开发人员,致力于我的第一个iPhone应用程序。当按下一个按钮时,我想播放一系列音频命令(.m4a文件),每个命令之间有不同的空间。

我能够使用以下代码设置AVAudio播放器播放单个音频文件:

ViewController.h

- (void)viewDidLoad

{
[super viewDidLoad];
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"get_in_shower" ofType:@"m4a"]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[player setNumberOfLoops:0];
[player prepareToPlay];

}

-(IBAction)play:(id)sender {
[player play];
}

现在我想将它设置为循环遍历包含音频文件名的dicts数组,以及在播放下一个文件之前暂停的时间长度。像这样:

pseudocode

directions = [{"file":"first", "delay":30},  {"file":"second", delay:15}]
def play(directions) {
  for (direction in directions) {
play directions["file"]
NSTimer length["delay"]
}

我的问题是如何使用AVAudioPlayer完成此操作。我还阅读了NSTimer的文档,但在使用AVAudioPlayer时遇到了麻烦。

提前致谢!

1 个答案:

答案 0 :(得分:3)

我认为NSTimer并不适合您想要实现的目标。 您描述的是音频剪辑的编辑列表,您尝试使用数组和字典构建的内容已作为第一类API存在:

AVComposition and its mutable counterpart

因为这些类继承了AVAsset,所以您可以使用AVPlayer播放它们的实例。 即使AVPlayer没有内置循环,你也可以使用它的子类AVQueuePlayer来定期检查玩家的currentItem是否与其项目中的最后一个对象相同,然后在最后插入一个mutableCopy来实现循环。 (它必须是一个可变副本,因为对于不可变类,copy通常会返回实例本身,因此对身份的测试总是会评估为true。)

由于您不想在播放器未播放时重新排队最后一项,您可以使用播放器本身安排一个块。这使您无需跟踪调度/未安排定时器的播放器状态。

所以真正剩下的就是

  1. 创建AVMutableComposition
  2. 逐个插入声音片段,然后插入适当的空闲时间范围
  3. 创建一个AVQueuePlayer,当其当前项目结束时自动播放下一个项目
  4. 如果其currentItem是其最后一项,则使用该播放器安排一个定期块,在该播放器中您可以将您的合成的可变副本排入队列。
  5. 如有疑问consult the AVFoundation Programming Guide