Сбои при использовании AVAudioPlayer на iPhone - PullRequest
2 голосов
/ 16 июня 2010

Я пытаюсь использовать AVAudioPlayer для воспроизведения некоторых звуков в быстрой последовательности. Когда я реже запускаю функцию воспроизведения звука, чтобы звуки воспроизводились полностью до повторного вызова функции, приложение работает нормально. Но если я вызову функцию быстро в быстрой последовательности (чтобы звуки воспроизводились, пока предыдущие звуки все еще воспроизводятся), приложение, в конечном счете, вылетает после ~ 20 вызовов функции с сообщением «EXC_BAD_ACCESS». Вот код из функции:

NSString *nsWavPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:wavFileName];

AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:nsWavPath] error:NULL];
theAudio.delegate = self;

[theAudio play];

Как уже упоминалось в другом потоке, я реализовал следующую функцию делегата:

- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    if(!flag)
        NSLog(@"audio did NOT finish successfully\n");
    [player release];
}

Но приложение все еще падает после примерно 20 быстрых вызовов этой функции. Есть идеи, что я делаю не так?

Ответы [ 2 ]

1 голос
/ 21 августа 2012

Я нашел лучшее решение этой проблемы. Вам просто нужно активировать / деактивировать AVAudioSession.

Например: в вашем методе viewDidLoad поместите это:

NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive:YES error:&activationError];

Затем вы можете воспроизводить звук любым способом, подобным этому:

... some awesome code ...
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
[self.audioPlayer setDelegate:self];
[self.audioPlayer setVolume: 0.7f];
[self.audioPlayer setNumberOfLoops:0];
if ([self.audioPlayer prepareToPlay]) {
    [self.audioPlayer play];            
}
....

И, наконец, (не важно, закончился ли звук), когда вы закончите со звуками, просто сделайте это:

// I've made it on the view's callback
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.audioPlayer stop];
    [self setAudioPlayer:nil];
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive:NO
                                         error:&activationError];
    .... etc, etc...
}

И это все :) Ваше приложение никогда не будет аварийно завершено с EXC_BAD_ACCESS.

Надеюсь, что это поможет вам и избежать этого хакерского [самоудержания] / [самоотпуска]

Из руководства по программированию аудиосеансов Apple: https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/ConfiguringanAudioSession/ConfiguringanAudioSession.html

1 голос
/ 16 июня 2010

Прежде всего: убедитесь, что вы не пытаетесь воспроизвести звук во второй раз, который уже был выпущен с помощью [player release]; Если это так, вы сразу получите это сообщение об ошибке. После того, как вы отпустите проигрыватель, связанный с определенным звуком, вы не сможете воспроизвести файл снова, как показано здесь. Попробуйте закомментировать эту строку кода и посмотрите, происходит ли она по-прежнему.

Я также столкнулся с проблемой, когда AVAudioPlayer выделяет 32 КБ каждый раз, когда создается новый player, и если у вас достаточно звуков, вы можете исчерпать память и получить сбой. Я очень сомневаюсь, что это ваша проблема, поскольку, как правило, этот код ошибки не выдается.

EXC_BAD_ACCESS обычно пытается получить доступ к указателю, который больше не существует (например, ваш player объект) для большинства случаев, которые я видел на этом форуме

...