AVAudioPlayer audioPlayerDidFinishPlaying: успешно: не вызывается - PullRequest
3 голосов
/ 08 февраля 2012

Я столкнулся со странной проблемой с классом AVAudioPlayer, когда обратный вызов audioPlayerDidFinishPlaying:successfully: не вызывается , иногда . Сокращенная версия кода, запускающего воспроизведение, выглядит следующим образом:

self.player = [[[AVAudioPlayer alloc] initWithContentsOfURL:localFileAudioURL error:&error] autorelease];
self.player.delegate = self;
[player prepareToPlay];
[NSTimer scheduledTimerWithTimeInterval:0.016f target:self selector:@selector(updatePlaybackProgress) userInfo:nil repeats:YES];
[player play];

Существует таймер, который запускается каждые 16 мс, чтобы показать ход воспроизведения. Когда воспроизведение аудио завершается и вызывается обратный вызов audioPlayerDidFinishPlaying:successfully:, таймер отключается. Код обратного вызова:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [self.progressTimer invalidate];
    self.progressTimer = nil;
}

Однако иногда (один раз в 20-30 воспроизведений) этот обратный вызов не вызывается. Я добавил точки останова и журнал вызовов, чтобы убедиться, что этот метод обратного вызова не был вызван.

NumberOfLoops для воспроизведения установлено на 0, поэтому оно не повторяется.

Вот некоторая дополнительная информация, если это поможет. Создающийся повторяющийся таймер обновляет пользовательский интерфейс с текущим прогрессом воспроизведения. Его код выглядит так:

- (void)updatePlaybackProgress {
    SoundCell *soundCell = [self soundCellForCurrentlyPlayingSound];

    NSTimeInterval progress = player.currentTime / player.duration;
    if (progress >= 0) {
        soundCell.progress = progress;
    }
}

Обратный вызов завершения не называется , иногда , поэтому таймер не аннулируется и вызывается через каждые 16 мс. Я записал значения player.currentTime и progress в методе updatePlaybackProgress, и кажется, что воспроизведение повторяется снова и снова. Значение currentTime продолжает увеличиваться с 0.0 до 1.0, затем возвращается к 0.0 и начинается снова. Аудио, однако, воспроизводится только в первый раз, а не непрерывно, как предполагает значение currentTime.

Эта проблема возникает для звуков длительностью от 1 до 30 секунд.

На данный момент у меня нет идей, и Google и форумы разработчиков Apple не имеют ничего общего.

1 Ответ

1 голос
/ 08 февраля 2012
  1. ваш таймер не гарантированно сработает в указанное вами время.Если вы пытаетесь построить индикатор прогресса игрока, я предлагаю использовать CADisplayLink, чтобы дать вам более схожую функциональность без накладных расходов (его срабатывает на основе обновления экрана).

  2. я бы реализовал ВСЕ методы протокола AVAudioPlayerDelegate, связанные с воспроизведением.

Ответ на завершение воспроизведения звука - audioPlayerDidFinishPlaying: успешно: Ответ наОшибка декодирования звука - audioPlayerDecodeErrorDidOccur: ошибка: Обработка прерываний звука - audioPlayerBeginInterruption: - audioPlayerEndInterruption: - audioPlayerEndInterruption: withFlags:

Скорее всего, один из них вызывается, когда воспроизведение останавливается.Вы также можете зарегистрироваться на NSNotifications для воспроизведения аудио, и в реализуемом вами методе вам просто нужно сравнить аудиоплеер с локальным проигрывателем, чтобы понять, что это то, что вас заинтересует.

...