начните воспроизведение звука из фоновой задачи через AVAudioPlayer в XCode

я пытаюсь начать воспроизведение звука из фоновой задачи через AVAudioPlayer, который затем создается, поэтому вот что у меня есть.

для удобства чтения я вырезаю все выбранные пользователем значения.

- (void)restartHandler {
    bg = 0;
    bg = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:bg];
    }];
    tim = [NSTimer timerWithTimeInterval:.1 target:self selector:@selector(upd) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:tim forMode:NSRunLoopCommonModes];
}

- (void)upd {
    if ([[NSDate date] timeIntervalSinceDate:startDate] >= difference) {
        [self playSoundFile];
        [tim invalidate];
        [[UIApplication sharedApplication] endBackgroundTask:bg];
    }
}

- (void)playSoundFile {

    NSError *sessionError = nil;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];


    // new player object
    _player = [[AVQueuePlayer alloc] init];
    [_player insertItem:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"Manamana" withExtension:@"m4a"]] afterItem:nil];

    [_player setVolume:.7];
    [_player play];

    NSLog(@"Testing");
}

объяснение: bg, tim, startDate, difference и _player глобально объявленные переменные. Я зову - (void)restartHandler из пользовательского метода и внутри него запустите 10hz повторяющийся таймер для - (void)upd. При достижении заданной разницы,- (void)playSoundFile получает вызывается и инициирует и запускает плеер. Вызывается тестовый NSLog в конце метода.

теперь странно, если я позвоню - (void)playSoundFile когда приложение активно, все работает просто отлично, но если я начну его с фоновой задачи, он просто не будет воспроизводить звук.

любая помощь, подсказка, решение или хедз-ап очень ценится.

редактировать

поэтому я попытался использовать разные потоки во время выполнения и, как кажется, если проигрыватель не создан в основном потоке, эта же проблема появится. Я также попытался использовать AVPlayer и AVAudioPlayer здесь AVAudioPlayer ' s .playing свойство вернулось да и по-прежнему не звучало.

4 ответов


из того, что я узнал после написания приложения плеера, кажется, что вы не можете начать воспроизведение звука, когда ваше приложение уже находится в фоновом режиме дольше, чем X секунд, даже если вы настроили все правильно.

чтобы исправить это, вы должны использовать мудро фоновой задачи. Самое главное, что вы должны не вызов endBackgroundTask сразу после playSoundFile. задержка около 5-10 секунд.

вот как мне удалось сделать это для iOS6 и iOS7.

1, добавьте аудио UIBackgroundModes в plist.

2, установить категорию аудио сессии:

3, Создайте AVQueuePlayer в основной поток и enqueue аудио актив перед приложением введите фон.

*для продолжает играть в фоновом режиме (например, воспроизведение списка воспроизведения)*

4, Убедитесь, что аудио очередь в AVQueuePlayer никогда не опустеет, иначе ваше приложение будет приостановлено после завершения воспроизведения последнего актива.

5, Если 5 секунд не достаточно для вас, чтобы получить следующий актив, который вы можете использовать фоновую задачу для задержки приостановки. когда актив готов, вы должны позвонить endBackgroundTask через 10 секунд.


включить свой playSoundFile вызов ниже, это всегда должно запускать его в основном потоке

dispatch_async(dispatch_get_main_queue(), ^{

});

добавьте это, если к вашему - (void) playSoundFile чтобы проверить, если игрок создан, если нет, то создайте его

if(!_player) {
    _player = [[AVQueuePlayer alloc] init];
}

Мне кажется,что у вас нет соответствующего фонового режима? Xcode screenshot

кроме того, похоже, что другой пользователь имел ту же проблему и исправил ее с помощью публикации Apple Docs. ссылка на сообщение

возможно, нужно просто сделать шаг, чтобы установить аудио сеанс активным:

[audioSession setActive:YES error:&activationError];

надеюсь, что это помогает!


Если вам нужно начать воспроизводить звук в фоновом режиме (без трюка, такого как сохранение воспроизведения на нулевой громкости, пока вам не понадобится звук):

  • установить фоновый режим аудио в вашем p.список;
  • установите категорию AudioSession в AVAudioSessionCategoryPlayback
  • установить AudioSession в active
  • когда ваше фоновое приложение запускается, запустите фоновую задачу перед воспроизведением звука (по-видимому, когда оставшееся фоновое время менее 10 секунд, звук не воспроизводится)

теперь это работает для меня.