MPNowPlayingInfoCenter not reacting properly when pausing playback
Asked Answered
M

3

46

I am trying to get MPNowPlayingInfoCenter to work properly when pausing playback. (I have a streaming music app that uses AVPlayer for playback, and I am playing back in my Apple TV over Airplay.) Everything but pausing seems to be reflected correctly in the Apple TV UI. I am initializing it like this:

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSDictionary *songInfo = @{
    MPMediaItemPropertyTitle: title,
    MPMediaItemPropertyArtist: artist
};
center.nowPlayingInfo = songInfo;

Since I am streaming, I do not have duration info upon starting the playback. When I get “ready” signal from the stream, I update the duration that shows up correctly on my Apple TV:

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];
[playingInfo setObject:[NSNumber numberWithFloat:length] forKey:MPMediaItemPropertyPlaybackDuration];
center.nowPlayingInfo = playingInfo;

I can also seek with this technique when the user seeks the track:

[playingInfo setObject:[NSNumber numberWithFloat:length * targetProgress] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];

The one thing I can NOT figure out is, how to pause the playhead on my Apple TV. When user taps pause in my UI, I am trying to do something like:

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];        
[playingInfo setObject:[NSNumber numberWithFloat:0.0f] forKey:MPNowPlayingInfoPropertyPlaybackRate];            
center.nowPlayingInfo = playingInfo;

Instead of pausing, this seeks the playhead back to zero and keeps advancing it.

How do I get the playhead to pause correctly in my Apple TV UI?

Manchu answered 1/8, 2012 at 3:58 Comment(5)
Did you try just to pause your AVPlayer?Helfant
@RomanTemchenko yes, when the user invokes pause UI control on device, then in addition to the infocenter experiments, I do [player pause]; where player is an AVPlayer instance. It has no effect in Apple TV UI. The audio actually stops and resumes as expected, but the playback progress has the issues that I describe.Manchu
I could never get it to pause correctly, so instead, I set the duration, rate and position to zero. This had the effect of simply removing the progress bar for the time completely, which was good enough for my purposes.Howerton
A playback rate of 0 is not a "rate". I'm not sure if it will work, but have you tried something like [playingInfo setObject:[NSNumber numberWithFloat:0.000001f] forKey:MPNowPlayingInfoPropertyPlaybackRate];?Operate
(That is, move the playhead verrrrry slowly.) If it works, you could use an NSTimer to reset the MPNowPlayingInfoPropertyElapsedPlaybackTime periodically while it's paused.Operate
K
15

I've the solution! Set only the MPMediaItemPropertyPlaybackDuration

1 - When you start the track, set the property with the total duration of the track:

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSDictionary *songInfo = @{
    MPMediaItemPropertyTitle: title,
    MPMediaItemPropertyArtist: artist
    MPMediaItemPropertyPlaybackDuration : [NSNumber numberWithFloat:length]
};
center.nowPlayingInfo = songInfo;

2 - when you pause the track... do nothing.

3 - when you play the track, set the property with the currentTrackTime:

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];        
[playingInfo setObject:[NSNumber numberWithFloat:player.currentTrackTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];            
center.nowPlayingInfo = playingInfo;
Kassala answered 11/2, 2014 at 1:12 Comment(4)
shouldn't it be MPNowPlayingInfoPropertyElapsedPlaybackTime instead of MPNowPlayingInfoPropertyPlaybackRate??Entwistle
shouldn't it be player.currentPlaybackTime instead of player.currentTrackTime or am I wrong?Bronchiole
Yes @Pedro, it's depend of the name of you propertyKassala
this solution setups elapsed time to zero at the lock screen player, so doesn't work at allBenton
F
3

Here what you searching, this working very good add this to your Class:

- (void)remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {

    if (receivedEvent.type == UIEventTypeRemoteControl) {

        switch (receivedEvent.subtype) {

            case UIEventSubtypeRemoteControlTogglePlayPause:[self playPause:nil];

                break;

            default: break;
        }
    }
}

you can add functions for forward or backward with adding other CASE code like this:

case UIEventSubtypeRemoteControlBeginSeekingBackward:[self yourBackward:nil];
                break;

and to calling play pause you need to create a action like this:

- (IBAction)playPause:(id)sender {

    if (yourPlayer.rate == 1.0){

        [yourPlayer pause];
    } else if (yourPlayer.rate == 0.0) {

        [yourPlayer play];
    }
}

Important: any case you adding need the IBAction

Hope this help you

Fiftieth answered 30/4, 2013 at 13:57 Comment(0)
M
-2
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSDictionary *songInfo = @{
    MPMediaItemPropertyTitle: title,
    MPMediaItemPropertyArtist: artist
};

the call like

center setnowPlayingInfo = songInfo;
Megan answered 1/10, 2013 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.