AVAudio проигрыватель воспроизводит список звуков с переменной паузой между

Я разработчик 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.

Заранее спасибо!

Я думаю, что NSTimer не очень подходит для того, чего вы хотите достичь. То, что вы описываете, – это список редактирования аудиоклипов, и то, что вы пытаетесь построить с использованием массивов и словарей, уже существует как API первого класса:

AVComposition и его изменчивый аналог .

Поскольку эти классы наследуют AVAsset, вы можете воспроизводить их с помощью AVPlayer. И хотя AVPlayer не имеет встроенной петли, вы можете использовать свой подкласс AVQueuePlayer для достижения цикла, периодически проверяя, совпадает ли текущий идентификатор игрока с последним объектом в его элементах, а затем просто вставляет в конец mutableCopy. (Это должна быть измененная копия, потому что для неизменяемых классов копия обычно возвращает сам экземпляр, поэтому тест на идентификацию всегда будет иметь значение true.)

Поскольку вы не хотите повторно отмечать последний элемент, пока игрок не играет, вы можете запланировать блок с самим игроком. Это освобождает вас от отслеживания состояния проигрывателя для таймера планирования / незапланировки.

Так что все, что действительно осталось, это

  1. Создать AVMutableComposition
  2. Один за другим, вставьте ваши звуковые клипы, а затем соответствующий пустой временной диапазон для паузы
  3. Создайте AVQueuePlayer, который автоматически воспроизводит следующий элемент, когда его текущий конец элемента
  4. Запланируйте периодический блок с тем игроком, в который вы вставляете измененную копию своей композиции, если ее currentItem является последним.

В случае сомнений ознакомьтесь с руководством по программированию AVFoundation