Есть ли способ получить доступ к текущей воспроизводимой дорожке, когда iPhone подключен к аксессуару?
Я пытаюсь получить информацию о текущем воспроизводимом треке в приложении для iOS. Это работает довольно хорошо, пока iPhone не подключен к аксессуару. Если я подключу его к своей машине (Opel Astra, разъем для iPhone), следующий код перестанет работать, как описано в документации:
Если вы создаете музыкальный проигрыватель iPod, а пользователь воспроизводит элемент из другой библиотеки с помощью функции "Домашний обмен", значение этого свойства
nil
,
Код:
// nil while connected to an accessory
MPMediaItem *nowPlayingMediaItem =
[[MPMusicPlayerController iPodMusicPlayer] nowPlayingItem];
// Works while not connected to an accessory
NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];
Я даже пробовал "хакерские" вещи, такие как доступ к "частным" свойствам ( оригинальный код):
MPMediaQuery *query=nil;
MPMediaItemCollection *collection=nil;
id internalPlayer=nil;
Ivar internalPlayeriVar = object_getInstanceVariable(iPod, "_internal", NULL);
internalPlayer = object_getIvar(iPod, internalPlayeriVar);
NSLog(@"internalPlayer: %@", internalPlayer);
Ivar queryIvar = object_getInstanceVariable(internalPlayer, "_query", NULL);
query = object_getIvar(internalPlayer, queryIvar); // nil everytime
Ivar collectionIvar = object_getInstanceVariable(internalPlayer,
"_itemCollection", NULL);
collection = object_getIvar(internalPlayer, collectionIvar); // nil everytime
или вызвать частные методы:
// Same behaviour like [iPod nowPlayingItem], works
// only while no accessory is connected
MPMediaItem *nowPlayingMediaItem =
[iPod nowPlayingItemAtIndex:[iPod indexOfNowPlayingItem]];
// Works while not connected to an accessory
NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];
Также нет решения для доступа к новому MPNowPlayingInfoCenter
, его nil
все время.
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo
Моя машина воспроизводит мою музыку напрямую, без использования приложения для iPhone, и кажется, что мой iPhone знает, что машина в данный момент играет, потому что отображает заголовок, исполнителя и значок обложки на экране блокировки (и только там). Также увеличивается внутренний счетчик игр.
Если я проверю состояние воспроизведения, он также возвращает YES
если машина играет музыку:
[[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStatePlaying
Итак, есть ли какой-нибудь способ (может быть, через вызов частных методов), чтобы получить доступ к песне, которую играет машина в настоящее время?
4 ответа
Apple просто "исправила это" в iOS 6.1 после того, как сообщила об этом как об ошибке. Следующий код теперь работает, когда мой iPhone подключен к моей машине:
MPMediaItem *nowPlayingMediaItem = [iPod nowPlayingItem];
NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];
NSLog(@"Playing title: %@", title);
И, что мне действительно нравится: также можно изменить дорожку воспроизведения с помощью приложения iPod - приложение отображается так, как вы ожидаете, вместо большого белого экрана, "подключенного к аксессуару". Так что это также может работать программно.
Вы используете темы? Если это так, запустите код в главном потоке. Если нет, зарегистрируйтесь для получения уведомлений MPMusicPlayerController об изменении элемента. Таким образом, когда песня изменится, ваше приложение будет знать, что это за новая песня. Также убедитесь, что это работает и в основном потоке.
Если ваше состояние воспроизведения обновляется при подключении, а ваш nowPlayingItem - нет, это подтвердит, что это ошибка. Я хотел бы представить отчет об ошибке по этой проблеме.
РЕДАКТИРОВАТЬ: Посетите https://developer.apple.com/support/resources/bug-reporting.html и прокрутите вниз. Последний вопрос говорит, что вы можете связаться с TSI для обхода ошибок. Вы получаете 2 запроса TSI на то, чтобы быть разработчиком бесплатно, поэтому вы можете использовать один из них, чтобы спросить их, есть ли у них обходной путь использования частной библиотеки, пока ошибка не будет исправлена.
На самом деле вы не получите MPMediaItem, потому что ваш iPhone не воспроизводит песни, но аксессуар вашего автомобиля, подключенный к iPhone, получает доступ к медиатеке. При этом он отвечает за обновление всех метаданных объектов (песен), к которым был получен доступ, особенно за счет увеличения количества воспроизведения и обновления даты последнего доступа к песне. Он также хранит некоторую информацию о том, где находится песня (позиция) в библиотеке iTunes.
Эта информация читается на экране блокировки для обновления обложки. Это также то, что помогает приложению iPod оставаться там, где оставлен аксессуар вашего автомобиля.
Так что нажмите на библиотеку и получите последнюю информацию оттуда. Посмотрите пример проекта TopSongs, чтобы начать.
Я почти уверен, что ответ - нет, вы не можете, по крайней мере, с любым открытым API, но вы должны сообщить об ошибке в Apple по двум причинам:
Причина, по которой MPNowPlayingInfoCenter не предоставляет вам информацию, заключается в том, что она должна быть специально реализована приложением, воспроизводящим музыку, если приложение Apple воспроизводит ее, то оно должно быть реализовано, чтобы сообщить об ошибке.
Теперь, если вы скажете, что [[MPMusicPlayerController iPodMusicPlayer] playState] отражает изменения в воспроизведении, это будет означать, что iPodMusicPlayer по-прежнему остается приложением, отвечающим за воспроизведение, поэтому о нулевом значении MPMediaItemPropertyTitle следует сообщить Apple как об ошибке.
Кроме того, непубличная информация по этой теме, вероятно, покрывается NDA МФУ, и никто не собирается рисковать его задницей.