Определить текущую информацию о песне в родном музыкальном приложении iOS

#ios #objective-c #ios7

#iOS #objective-c #ios7

Вопрос:

У меня возникли некоторые проблемы с получением текущей информации о воспроизводимой песне, например (название, исполнитель …) в родном музыкальном приложении iOS.

Это точная проблема, мое приложение использует a MPMusicPlayerController с iPodMusicPlayer этим свойством is call myPlayer . Когда пользователь управляет музыкой в моем приложении, я могу таким образом отображать текущую информацию о воспроизведении песни…

 - (void)getTrackDescription {

    // getting whats currently playing
    self.nowPlayingItem = [myPlayer nowPlayingItem];

    // song title currently playing
    self.title = [self.nowPlayingItem valueForProperty:MPMediaItemPropertyTitle];

    // if title is not fund Unknown will be displayed
    if (title == (id)[NSNull null] || title.length == 0) {
        title = @"Unknown";
    }

    // artist currently playing
    self.artist = [self.nowPlayingItem valueForProperty:MPMediaItemPropertyArtist];

    // if artist is not fund Unknown will be displayed
    if (artist == (id)[NSNull null] || artist.length == 0) {
        artist = @"Unknown";
    }

    //[self.currentlyPlaying setLineBreakMode:NSLineBreakByWordWrapping];

    // displaying current artist and title song playing
    [self.currentlyPlaying setText:[NSString stringWithFormat:@"%@ - %@", artist, title]];
}
  

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

Я попытался решить проблему таким образом…

 - (void)viewDidLoad {
    [super viewDidLoad];

    if (self.myPlayer.playbackState == MPMusicPlaybackStatePlaying || self.myPlayer.playbackState == MPMusicPlaybackStateSeekingForward || self.myPlayer.playbackState == MPMusicPlaybackStateSeekingBackward){
        // updating track name regardless the user uses app controllers or not
        [self getTrackDescription];
    } 
}
  

Я даже попытался прокомментировать условие if, чтобы узнать, получаю ли я информацию о песне таким образом, но это была та же проблема.

Что ж, я надеюсь, что кто-нибудь сможет мне помочь и объяснить, что я делаю не так..

Заранее спасибо …!

Обновить

Это то, что у меня есть на данный момент… Моя логика getTrackDescription та же, но подпись изменилась на эту - (void)getTrackDescription:(id)notification

 - (void)viewWillAppear:(BOOL)animated{

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter addObserver:self
                           selector:@selector(getTrackDescription:)
                               name:MPMusicPlayerControllerPlaybackStateDidChangeNotification
                             object:self.myPlayer];
    [self.myPlayer beginGeneratingPlaybackNotifications];

}

-(void)viewWillDisappear:(BOOL)animated{

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                               name:MPMusicPlayerControllerPlaybackStateDidChangeNotification
                                               object:self.myPlayer];
    [self.myPlayer endGeneratingPlaybackNotifications];
}
  

Ответ №1:

Что вам нужно сделать, так это добавить свой контроллер просмотра в качестве наблюдателя в уведомление MPMusicPlayerControllerNowPlayingItemDidChangeNotification, которое, как оно звучит, вызывается каждый раз, когда трек меняется в музыкальном проигрывателе. Не забудьте указать, когда проигрыватель должен начать / завершить генерирование этих уведомлений следующими способами.

 [[MPMusicPlayerController iPodMusicPlayer] beginGeneratingPlaybackNotifications];
[[MPMusicPlayerController iPodMusicPlayer] endGeneratingPlaybackNotifications];
  

Комментарии:

1. где я должен реализовать это в моем getTrackDescription или в viewDidLoad?

2. Вероятно, вам следует добавить себя в качестве наблюдателя viewWillAppear: и удалить наблюдателя viewDidDisappear: . Вы захотите вызвать getTrackDescription обратный вызов из уведомления.

3. Хорошо, я попытался реализовать то, что вы предложили, но у меня не получается, чтобы оно работало должным образом, можете ли вы увидеть мою часть обновления в сообщении и сообщить мне, в чем проблема .. или любая suggestions..@0x7fffffff

Ответ №2:

Это мой полный ответ на проблему..

1) Я установил эти два метода .. и установил Observer MPMusicPlayerControllerNowPlayingItemDidChangeNotification , который позаботится об обновлении информации о моей песне независимо.. с getTrackDescription которым все так же, как и в моем предыдущем сообщении..

 - (void)viewWillAppear:(BOOL)animated{

    // creating simple audio player
    self.myPlayer = [MPMusicPlayerController iPodMusicPlayer];

    // assing a playback queue containing all media items on the device
    [self.myPlayer setQueueWithQuery:[MPMediaQuery songsQuery]];

    self.notificationCenter = [NSNotificationCenter defaultCenter];

    [self.notificationCenter addObserver:self
                                selector:@selector(getTrackDescription:)
                                    name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
                                    object:self.myPlayer];

    [self.notificationCenter addObserver:self
                                selector:@selector(handle_PlayBackNotification:)
                                    name:MPMusicPlayerControllerPlaybackStateDidChangeNotification
                                    object:self.myPlayer];


    [self.myPlayer beginGeneratingPlaybackNotifications];

}

-(void)viewWillDisappear:(BOOL)animated {

    [self.notificationCenter removeObserver:self
                                name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
                                object:self.myPlayer];

    [self.notificationCenter removeObserver:self
                                    name:MPMusicPlayerControllerPlaybackStateDidChangeNotification
                                    object:self.myPlayer];

    [self.myPlayer endGeneratingPlaybackNotifications];

}
  

Тогда волшебство произойдет само по себе .. это просто то, что @0x7fffffff рекомендовал мне сделать, но мне пришлось немного покопаться, потому что я вообще не был знаком с уведомлениями..

Итак, на всякий случай, если вы хотите посмотреть, как я переключаю кнопку воспроизведения / паузы для Observer MPMusicPlayerControllerPlaybackStateDidChangeNotification этого, как я это сделал..

 - (void)handle_PlayBackNotification:(id)notification{

    if(myPlayer.playbackState == 1){

        // sets the pause image in play button
        [self.pauseBtn setBackgroundImage:[UIImage imageNamed:@"pauseBtn2.png"] forState:(UIControlStateNormal)];

    } else {

        // resets the image to normal play image
        [self.pauseBtn setBackgroundImage: nil forState:(UIControlStateNormal)];


    }

}
  

на всякий случай, это мое getTrackDescription

 - (void)getTrackDescription:(id)notification {

    // getting whats currently playing
    self.nowPlayingItem = self.myPlayer.nowPlayingItem;

    // song title currently playing
    self.title = [self.nowPlayingItem valueForProperty:MPMediaItemPropertyTitle];

    // if title is not fund Unknown will be displayed
    if (title == (id)[NSNull null] || title.length == 0) {
        title = @"Unknown";
    }

    // artist currently playing
    self.artist = [self.nowPlayingItem valueForProperty:MPMediaItemPropertyArtist];

    // if artist is not fund Unknown will be displayed
    if (artist == (id)[NSNull null] || artist.length == 0) {
        artist = @"Unknown";
    }

    // displaying current artist and title song playing
    [self.currentlyPlaying setText:[NSString stringWithFormat:@"%@ - %@", artist, title]];

}