Как мне управлять воспроизведением другого звука в iOS с учетом многозадачности?

В Руководстве по аудиосессии есть раздел "Проверка, воспроизводится ли другой звук во время запуска приложения".

Я использую MonoTouch (но не стесняйтесь давать ответ Objective-C, API тот же), поэтому код из этого документа выглядит примерно так:

bool otherAudioPlaying = AudioSession.OtherAudioIsPlaying;
if(otherAudioPlaying)
    AudioSession.Category = AudioSessionCategory.AmbientSound;
else
    AudioSession.Category = AudioSessionCategory.SoloAmbientSound;

В результате, если мое приложение запускается с воспроизведением музыки с iPod, эта музыка с iPod будет продолжать воспроизводиться и не позволит мне использовать аппаратный аудиодекодер (который мне в любом случае не нужен). Если при запуске моего приложения музыка с iPod не воспроизводится, я могу использовать аппаратный декодер.

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

Теперь это прекрасно работает в старых операционных системах, которые не поддерживают многозадачность. Но с многозадачностью пользователь может покинуть мое приложение (запустить его в фоновом режиме), начать воспроизведение музыки на iPod и повторно войти в мое приложение. Тогда их музыка на iPod будет отключена, и моя музыка снова начнет играть.

Я бы хотел, чтобы музыка iPod продолжала воспроизводиться, когда мое приложение возвращается на передний план - даже если моя собственная музыка воспроизводилась (и с использованием аппаратного декодера), когда мое приложение находилось в фоновом режиме.

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

Как я могу это сделать? (И желательно без резкого отключения звука, сохраняя приятное затухание, которое обычно случается.)

РЕДАКТИРОВАТЬ: я также должен указать, что я делаю всю свою работу со звуком в основном потоке.


person Andrew Russell    schedule 22.10.2010    source источник
comment
Что не так с настройкой AudioSession.category = AVAudioSessionCategoryAmbient, независимо от того, воспроизводится ли другой звук или нет?   -  person William Jockusch    schedule 28.10.2010
comment
@William Если я выберу категорию Ambient, то я не смогу сам использовать декодирующее оборудование для моей собственной музыки (а выполнение этого на CPU требует слишком много процессорного времени).   -  person Andrew Russell    schedule 29.10.2010


Ответы (2)


Почему бы просто не позаботиться о том, чтобы реализовать это в вашем приложении, делегируйте многозадачные сообщения? В фоновом режиме приостановите воспроизведение звука (при необходимости сохраните текущую позицию воспроизведения) и снова включите его, когда приложение возобновит фокус.

Просто чтобы уточнить немного больше: ответьте на applicationDidEnterBackground: в своем делегате, сбросив состояние аудиоплеера, и ответьте на applicationWillEnterForeground: установив его резервную копию, как вы это делаете сейчас. У вас также может быть объект, который настраивает воспроизведение звука, отвечая на UIApplicationWillEnterBackgroundNotification / UIApplicationWillEnterForegroundNotification через NSNotificationCenter, что, вероятно, было бы немного проще за счет абстрагирования от того, что ваше приложение делает именно в фоновом режиме, из класса делегата вашего приложения.

person refulgentis    schedule 25.10.2010
comment
Я знаю о applicationDidEnterBackground и полагаю, что решение потребует ответа на него. Я пытаюсь понять, что влечет за собой приостановка звука и сброс бит состояния аудиоплеера. - person Andrew Russell; 25.10.2010
comment
Хм ... Кажется, я не понимаю. Если это вопрос об AudioSession, вы знаете, как его запустить, я предполагаю, что аналогичные методы остановят его? Если вы действительно не знаете, я посмотрю в документации и отвечу еще раз. На более банальном уровне: я не могу сказать вам, как сбросить состояние вашего аудиоплеера, потому что я не знаю, как вы его настраивали. iOS будет считать его сбросом, если вы его остановите. - person refulgentis; 25.10.2010
comment
Мой аудиоплеер - это простой аппаратный AudioQueue, по сути то, что описано в Руководстве по программированию служб звуковой очереди (за исключением того, что он обрабатывается в другом потоке, чем основной, где я получаю уведомления). Дело в том, что взаимодействие с API AudioQueue / AudioSession во время applicationDidEnterBackground приводит к странному поведению или сбою. К сожалению, документация (насколько я могу судить) не описывает способ взаимодействия этих двух частей API. - person Andrew Russell; 29.10.2010

Что касается вашего последнего комментария к ответу refulgentis, вы можете приостановить воспроизведение музыки в applicationWillResignActive и оставить операции сохранения состояния и очистку для applicationDidEnterBackground. Это может быть лучше для предотвращения любого странного поведения во время фонового переходного состояния.

person Nick Toumpelis    schedule 31.10.2010