MPNowPlayingInfoCenter Disappears when audio stream stalls
Asked Answered
S

2

31

My app plays streaming audio via AVPlayer, and uses MPNowPlayingInfoCenter to display info about the stream on the device lock screen.

This works fine when audio is actually playing, but if the stream stalls due to network slowdowns (i.e. I receive AVPlayerItemPlaybackStalledNotification) the information disappears from the lock screen. But then if the stream resumes playing, it reappears.

This is confusing because when the now-playing info disappears from the lock screen it gives the appearance that the app has stopped playback. But then it resumes playback, when the lock screen UI seems to indicate that this won't happen.

Is there something I can do to make sure the now playing info remains visible whenever the stream should be playing but currently is not due to network speed issues? It seems like the only way to keep a consistent lock screen UI is to actually kill the network connection when it stalls, which is kind of stupid but at least not confusing.

In case more detail would help:

  • When the app gets that notification, the only thing it does is update the UI.
  • The app never clears MPNowPlayingInfoCenter when there's a current program, so as long as the stream is supposed to be playing, there's non-empty data that should be getting displayed.
Squander answered 21/4, 2015 at 0:0 Comment(6)
Are you setting the info center dictionary from a time observer? For example: addPeriodicTimeObserverForInterval:Photometry
No, I'm not using a time observer. The now-playing info is only updated in direct response to user actions and when the app enters the foreground.Squander
Are you listening on AVPlayerItemPlaybackStalledNotification ? What happens when you not listening? And what is about caching your data-streams?Ernie
Who owns the dictionary, is it a strong property or a local variable?Photometry
@MiralemCebic Yes I'm listening for that notification. If I don't listen for it then I can't update the UI, so it looks like it's still playing even though there's no sound. I don't change the now-playing info when that notification is received.Squander
@Photometry The dictionary is a local, but since MPNowPlayingInfoCenter declares nowPlayingInfo to be a copy ivar, that shouldn't matter. Regardless it works normally except when an audio stall occurs.Squander
D
1

If I were to take a guess (and it's been a while since I've used AVFoundation) I would assume your audio session is being deactivated by the OS as soon as data stop flowing through the audio buffer. One trick would be to maintain a second AVPlayer which plays back silence to fill in the dead spots until you've buffered enough data to resume playback or reached some timeout and just give up. Use the notification to switch between player objects.

Darill answered 2/6, 2015 at 7:29 Comment(0)
B
1

I am not getting any issue when set the lock screen even in network problem.

I am also dealing with streaming.

And I think lock screen only affected when audio session is active or not.

Here you can see my code and I am not getting any issue hope this will help to you.

-(void)setLockScreen
{
    Class playingInfoCenter = NSClassFromString(@"MPNowPlayingInfoCenter");
    if (playingInfoCenter)
    {
        [[AVAudioSession sharedInstance] setActive:YES error:nil];
        NSError *myErr;
        if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&myErr])
        {
            // Handle the error here.
            NSLog(@"Audio Session error %@, %@", myErr, [myErr userInfo]);
        }
        else
        {
            [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
            [self becomeFirstResponder];
        }
        MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:imgViewLogo.image];
        NSArray *keys = [NSArray arrayWithObjects:
                         MPMediaItemPropertyTitle,
                         MPMediaItemPropertyArtist,
                         MPMediaItemPropertyArtwork,
                         MPNowPlayingInfoPropertyPlaybackRate,
                         nil];
        NSArray *values = [NSArray arrayWithObjects:
                           [[self.arrChannel objectAtIndex:[AppDelegate sharedAppDelegate].selectedRow] objectForKey:@"name"],
                           [[AppDelegate sharedAppDelegate].dictChannelsConfig objectForKey:@"venueName"],
                           albumArt,
                           [NSNumber numberWithInt:1],
                           nil];
        NSDictionary *mediaInfo = [NSDictionary dictionaryWithObjects:values forKeys:keys];
        keys = nil;
        values = nil;
        albumArt = nil;
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:mediaInfo];
        mediaInfo = nil;
    }

}
Bureaucratize answered 3/6, 2015 at 6:1 Comment(5)
Do you call this method when a stall happens?Squander
I am just calling this method when my audio is there, I mean suppose User Hit play and audio streaming is there then I am calling this method.Bureaucratize
In that case it's no different from what I'm already doing. I activate the audio session, use the same audio category, and pass information to MPNowPlayingInfoCenter. Do you receive AVPlayerItemPlaybackStalledNotification?Squander
May be you are right but I am not using AVPlayerItemPlaybackStalledNotificationBureaucratize
Then you are not experiencing the situation which I described in the question.Squander

© 2022 - 2024 — McMap. All rights reserved.