Подтвердить что ты не робот

Есть ли способ получить доступ к воспроизводимой в настоящий момент треку, когда iPhone подключен к аксессуару?

Я пытаюсь получить информацию о воспроизводимой в данный момент треке в приложении iOS. Это работает очень хорошо, в то время как iPhone не подключен к аксессуару. Если я подключу его к своей машине (Opel Astra, iPhone jack), следующий код перестанет работать как описано в документации:

Если вы создаете музыкальный проигрыватель 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];

Я даже попробовал "хакерские" вещи, чтобы получить доступ к свойствам "private" (исходный код):

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 

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

4b9b3361

Ответ 1

Apple просто "исправила это" в iOS 6.1 после того, как сообщила об этом как об ошибке. Следующий код теперь работает, пока мой iPhone подключен к моей машине:

MPMediaItem *nowPlayingMediaItem = [iPod nowPlayingItem];

NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];

NSLog(@"Playing title: %@", title);

И, что мне действительно нравится: также можно изменить игровую дорожку с помощью iPod-приложения - приложение появляется, как вы ожидаете, вместо большого белого экрана, подключенного к аксессуару. Таким образом, это также может работать программно.

Ответ 2

Используете ли вы потоки? Если это так, запустите код в основном потоке. Если нет, зарегистрируйтесь для уведомлений MPMusicPlayerController для изменения элемента. Таким образом, когда песня изменится, ваше приложение узнает, что такое новая песня. Также убедитесь, что это работает и в главном потоке .

Если ваше состояние воспроизведения обновляется при подключении, но ваш nowPlayingItem нет, это подтвердит, что это ошибка. Я отправил отчет об ошибке для этой проблемы.

EDIT: Посетите https://developer.apple.com/support/resources/bug-reporting.html и прокрутите страницу вниз. В последнем вопросе вы можете связаться с TSI для работы с ошибками. Вы получаете 2 запроса TSI для бесплатного разработчика, поэтому вы можете использовать один из них, чтобы спросить их, есть ли у них работа с частной библиотекой до тех пор, пока ошибка не будет исправлена.

Ответ 3

Я уверен, что ответ отрицательный, вы не можете с какой-либо публичной api, но вы должны подать ошибку с яблоком по двум причинам:

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

Теперь, если вы скажете, что [[MPMusicPlayerController iPodMusicPlayer] playbackState] отражает изменения в воспроизведении, это означало бы, что iPodMusicPlayer по-прежнему является приложением, отвечающим за воспроизведение, поэтому давая вам нуль для MPMediaItemPropertyTitle, также следует сообщать яблоку в виде ошибки.

Кроме того, непубличная информация по этой теме, скорее всего, покрывается MFi NDA, и никто не рискует своей задницей.

Ответ 4

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

Эта информация считывается экраном блокировки для обновления обложки. Это также помогает iPod-приложению продолжить работу с вашим автомобильным аксессуаром.

Итак, войдите в библиотеку и получите последнюю информацию оттуда. Посмотрите пример проекта TopSongs, чтобы начать работу.