Недавно я обнаружил, что обработчики событий удаленного управления MediaPlayer (MPRemoteCommand) не вызываются в iOS-приложении со встроенным проигрывателем Unity. Я использую Xcode 6.3.1 и Unity 5.0.1f1, однако похоже, что его можно воспроизвести с любой комбинацией доступных в настоящее время версий.
Это официальная документация Apple по обработке событий удаленного управления в iOS: https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Remote-ControlEvents/Remote-ControlEvents.html.
Проблему очень легко воспроизвести — это всего лишь 24 строки кода, добавленные в пустой проект.
Создайте новое приложение Single View в Xcode (чтобы сделать рабочий пример без проигрывателя Unity) или создайте пустой проект в Unity и сразу же соберите его для платформы iOS (Файл -> Настройки сборки..., iOS, Сборка) со всеми настройками, оставленными с их значения по умолчанию, чтобы получить проект Xcode, сгенерированный Unity (чтобы сделать сломанный пример со встроенным проигрывателем Unity).
Импортируйте заголовочный файл платформы MediaPlayer в AppDelegate.h (например, без Unity) или UnityAppController.h (например, с Unity):
#import <MediaPlayer/MediaPlayer.h>
Объявите свойство для объекта MPMoviePlayerController в интерфейсе класса, расположенном в AppDelegate.h/UnityAppController.h:
@property (strong, nonatomic) MPMoviePlayerController *player;
Вставьте этот код, который создает проигрыватель с URL-адресом (это прямая радиостанция, вы можете использовать любой другой источник живого звука HTTP, который вы хотите), регистрирует обработчики событий удаленного управления play, pause и togglePlayPause и запускает воспроизведение звука ( таким образом, делая приложение приложением «Сейчас исполняется») в начале метода application:didFinishLaunchingWithOptions:, расположенного в AppDelegate.m/UnityAppController.mm (вы также можете добавить его непосредственно перед оператором возврата этого метода — это не имеет значения):
self.player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"http://81.9.96.34/eldoradio-64k"]]; [[MPRemoteCommandCenter sharedCommandCenter].playCommand addTarget:self action:@selector(playCommand)]; [[MPRemoteCommandCenter sharedCommandCenter].pauseCommand addTarget:self action:@selector(pauseCommand)]; [[MPRemoteCommandCenter sharedCommandCenter].togglePlayPauseCommand addTarget:self action:@selector(togglePlayPauseCommand)]; [self.player play];
Добавьте реализацию обработчиков в AppDelegate.m/UnityAppController.mm:
- (void)playCommand { [self.player play]; } - (void)pauseCommand { [self.player pause]; } - (void)togglePlayPauseCommand { if (self.player.playbackState == MPMoviePlaybackStatePlaying) { [self.player pause]; } else { [self.player play]; } }
Соберите и запустите приложение. Вы должны услышать музыку, играющую после ее запуска.
Инициировать некоторые события удаленного управления. Самый простой способ — подключить стандартный Apple EarPods и нажмите кнопку воспроизведения-паузы на них, что должно сгенерировать событие togglePlayPause, но открытие Центра управления iOS (пользовательский интерфейс, который вы получаете, проводя пальцем по экрану снизу) и нажатие кнопки воспроизведения/паузы также допустимо. (они должны генерировать отдельные события воспроизведения и паузы соответственно).
В приложении без Unity звук останавливается и начинает воспроизводиться в соответствии с отправленными событиями удаленного управления. В приложении с Unity обработчики никогда не вызываются (в них можно поставить точки останова и увидеть это под отладчиком) и вообще ничего не происходит. Вы также можете заметить, что внешний вид Центра управления iOS совершенно другой: в приложении со встроенным проигрывателем Unity у него есть кнопки воспроизведения и две кнопки перемотки независимо от состояния звука, а в приложении без Unity отображается только кнопка паузы при воспроизведении звука или просто кнопку воспроизведения, когда он не играет.
Также можно заменить MPMoviePlayerController на AVPlayer из фреймворка AVFoundation — результат будет точно таким же.
Кто-нибудь знает причину такого поведения и/или обходной путь? Это очень плохо влияет на наше приложение.
PS: я уже задавал подобный вопрос раньше, но не получил любые ответы. Пример в этом максимально прост.