Внедрение и устранение неисправностей Фоновый звук в iOS
Есть много вопросов, связанных с воспроизведением фоновой музыки в iOS на StackOverflow. Никто не может полностью изучить все краевые дела, цель этот вопрос должен быть последним словом в фоновом звуковом вопросе о Иос
Определения и допущения
Весь код, вопросы и примеры относятся к ios5.
"background" . Состояние, в которое приложение вводится, когда пользователь нажимает кнопку "домой" или кнопку питания (поэтому устройства отображают экран блокировки). Приложение можно также использовать в фоновом режиме, используя многозадачный коммутатор или жесты многозадачности на iPad.
"audio" - Аудио воспроизводится с использованием AudioQueue (включая AVAudioPlayer)
Необходимые условия
Как я понимаю, есть 2 требования к приложению для воспроизведения аудио в фоновом режиме.
- Установите
UIBackgroundModes
в audio
в Info.plist
-
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
Требования
В моем случае используется относительно длинный звук в фоновом режиме (музыка). Есть потенциально сотни треков, и приложение будет воспроизводить их последовательно. Можно считать, что звук будет проигрываться бесконечно.
Приложение будет обрабатывать прерывания, приостанавливая воспроизведение.
Вопросы
У меня был смешанный успех:
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:...];
Разрешение воспроизведения звука в фоновом режиме. Но я смущен, если это необходимо и как оно отличается:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
Пограничные случаи
-
Перерывы. Если вы зарегистрируетесь, чтобы получать уведомления о прерываниях звука (телефонные звонки и т.д.), Став делегатом AVAudioPlayer
. Например, если вы приостанавливаете или останавливаете свой звук, когда прерывание начинается и возобновляется, когда оно заканчивается, ваше приложение приостановлено, если прерывание превышает 10 минут (максимальное время, разрешенное для выполнения фоновых задач)?
-
Симулятор остановит звук при вызове Lock или Home при использовании:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
Однако это работает на устройстве. Это известная проблема?
Ответы
Ответ 1
У меня есть опыт работы с фоновым режимом GPS и фоновым звуком. Это не совсем то же самое, что и ваша ситуация (вы хотите воспроизвести длинный звуковой файл, и я играю короткие сообщения), но вот что я могу вам сказать:
-
beginBackgroundTaskWithExpirationHandler
Этот селектор имеет одну цель при вызове в фоновом режиме: избегайте приложению возвращаться в приостановленное состояние, в котором больше не может быть вызван код (вы "заморожены" ). Поэтому до тех пор, пока вы вызывали beginBackgroundTaskWithExpirationHandler
и до того, как вы завершили свою долговременную задачу с помощью beginBackgroundTaskWithExpirationHandler
, вы используете процессор и потребляете аккумулятор.
Я действительно сомневаюсь, что игра в фоновом режиме должна использовать батарею iPhone, как если бы она запускала приложение, поэтому я сомневаюсь, что beginBackgroundTaskWithExpirationHandler
действительно участвует в вашем потоке.
-
Симулятор: не полагайтесь на симулятор: он не полностью реализует фоновые режимы. Фактически, когда вы нажимаете кнопку "домой", ваше приложение уходит в фоновом режиме, но на этом этапе вы все равно сможете выполнить код в своем приложении. Через некоторое время ваше приложение будет приостановлено (= заморожено), и ваше исполнение кода будет приостановлено, чтобы сохранить батарею.
Это приостановленное состояние никогда не будет происходить на симуляторе.
-
Перерывы. Это не зависит от вас, чтобы приостановить/возобновить воспроизведение при поступлении телефонного звонка. Платформа отвечает за это, и вы можете просто отреагировать на это с помощью AVAudioSessionDelegate. Тем не менее, вы можете повлиять на то, как ваш сеанс будет взаимодействовать с другими звуковыми звуками, установив свойство на ваш сеанс аудио (см. kAudioSessionProperty_OverrideCategoryMixWithOthers, например).
Таким образом, поток больше: вы описываете, как ваш аудио-сеанс должен взаимодействовать с остальной системой, система будет смешивать звуки в соответствии с этим, и если ваш сеанс будет прерван, вы будете уведомлены с помощью AVAudioSessionDelegate.
Надеюсь, что это поможет.
Ответ 2
Я использовал ниже код для управления устройством -
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
Используется для регистрации регистра для прослушивания пульта дистанционного управления.
После этого удалите его -
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
сделать приложение canBecomeFirstResponder -
- (BOOL)canBecomeFirstResponder {
return YES;
}
Используется метод делегата для управления iPhone, например, воспроизведение и пауза, а doble нажмите на домашнюю кнопку
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
//if it is a remote control event handle it correctly
if (event.type == UIEventTypeRemoteControl) {
if (event.subtype == UIEventSubtypeRemoteControlPlay) {
[audioPlayer play];
NSLog(@"play");
} else if (event.subtype == UIEventSubtypeRemoteControlPause) {
[audioPlayer stop];
NSLog(@"pause");
} else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
NSLog(@"toggle");
}
}
}