MPNowPlayingInfoCenter在音频流中断时消失

31

我的应用程序通过 AVPlayer 播放流式音频,并使用 MPNowPlayingInfoCenter 在设备锁屏界面上显示有关流的信息。

当音频实际播放时,这很正常,但是如果由于网络减速而导致流媒体出现故障(即我收到 AVPlayerItemPlaybackStalledNotification ),设备锁屏界面上的信息就会消失。但是,如果流恢复播放,则该信息将重新出现。

这很令人困惑,因为当正在播放的信息从锁屏界面消失时,它给人的印象是应用程序已停止播放。但是,当锁屏界面 UI 表明这不会发生时,它会恢复播放。

是否有一些方法可以确保现在播放的信息在网络速度问题导致流媒体未能播放时仍然可见?似乎唯一保持一致的锁屏界面 UI 的方法是在出现故障时实际中断网络连接,这有点愚蠢但至少不会让人困惑。

如果需要更多细节:

  • 当应用程序收到该通知时,它所做的唯一事情就是更新 UI。
  • 当当前节目存在时,应用程序永远不会清除 MPNowPlayingInfoCenter ,因此只要流媒体应该正在播放,就应该显示非空数据。

你是否正在从时间观察器中设置信息中心字典?例如:addPeriodicTimeObserverForInterval: - yairsz
不,我没有使用时间观察器。现在播放的信息只有在直接响应用户操作并且应用程序进入前台时才会更新。 - Tom Harrington
你是否在监听 AVPlayerItemPlaybackStalledNotification ?如果不监听会发生什么?另外,关于缓存数据流方面有什么需要注意的吗? - Miralem Cebic
谁拥有这个字典,它是一个强属性还是一个局部变量? - yairsz
@MiralemCebic 是的,我正在监听那个通知。如果我不监听它,那么我就无法更新UI,所以它看起来仍在播放,即使没有声音。当接收到该通知时,我不会更改现在播放的信息。 - Tom Harrington
@yairsz 这个字典是本地的,但由于 MPNowPlayingInfoCenter 声明 nowPlayingInfocopy 实例变量,所以这应该没有关系。无论如何,它通常都可以正常工作,除非发生音频卡顿。 - Tom Harrington
2个回答

1

即使在网络问题时设置锁屏,我也没有遇到任何问题。

我还在处理流媒体。

我认为只有当音频会话处于活动状态时,锁屏才会受到影响。

在这里,您可以查看我的代码,我没有遇到任何问题,希望这能对您有所帮助。

-(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;
    }

}

当出现停顿时,您是否调用此方法? - Tom Harrington
当我的音频存在时,我只是调用这个方法,也就是说,假设用户点击播放并且音频流正在播放,那么我就会调用这个方法。 - Bhavesh Lathigara
在这种情况下,它与我已经在做的没有什么不同。我激活音频会话,使用相同的音频类别,并将信息传递给MPNowPlayingInfoCenter。您是否收到AVPlayerItemPlaybackStalledNotification通知? - Tom Harrington
也许你是对的,但我没有使用AVPlayerItemPlaybackStalledNotification。 - Bhavesh Lathigara
那么你没有经历我在问题中描述的情况。 - Tom Harrington

1
如果我猜的话(而且我已经很久没有使用AVFoundation了),我会认为你的音频会话在数据停止流动通过音频缓冲区时被操作系统停用。一个技巧是维护第二个AVPlayer,它播放静音以填补死区,直到你缓冲足够的数据来恢复播放或达到某个超时并放弃。使用通知在播放器对象之间切换。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接