【问题标题】:MPRemoteCommandCenter control center pause button doesn't update even after the audio file is paused即使在音频文件暂停后,MPRemoteCommandCenter 控制中心的暂停按钮也不会更新
【发布时间】:2015-09-13 04:51:43
【问题描述】:

我正在开发一个处理 MPRemoteCommandCenter 类的录音应用程序。我已经设置了命令中心来播放和暂停命令。下面添加了代码 sn-p。我遇到了 pauseCommand 问题。

我从应用程序开始播放音频文件,该文件更新控制中心以及正在播放的文件并将播放按钮更改为暂停按钮。现在,当文件正在播放时,我从控制中心选择暂停按钮暂停音频。 这是在应用程序中调用 pauseCommand 处理程序,音频文件已暂停,但控制中心继续更新搜索栏,暂停按钮不会更改为播放按钮。

-(void) setupRemoteControls
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];

[commandCenter.pauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent *event) {

    if ([self pauseAudioPlayback]) 
        return MPRemoteCommandHandlerStatusSuccess;
    else
        return MPRemoteCommandHandlerStatusCommandFailed;
} ];

[commandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent *event) {

    if ([self resumeAudioPlayback])
        return MPRemoteCommandHandlerStatusSuccess;
    else
        return MPRemoteCommandHandlerStatusCommandFailed;
} ];

}

// pauseAudioPlayback 和 resumeAudioPlayback 方法都调用此方法

- (void) updateRemoteControls
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];

if (self.audioPlayer)
{
    if (self.isPlaying)
        commandCenter.playCommand.enabled = NO;
    else if (self.isPlayPaused)
        commandCenter.playCommand.enabled = YES;
}
else
    [self clearNowPlayingInfo];

}

如果需要任何其他信息,请告诉我。

【问题讨论】:

  • 今天,我已将我的 iOS 升级到 8.4,现在当我运行相同的代码时,现在单击控制中心上的暂停按钮,应用程序正在接收处理程序以及搜索栏控制中心正在暂停,但控制中心的暂停图标没有变为播放图标。但是已经解决了一个问题(寻求栏暂停)。这是否确认问题出在操作系统方面而不是我的代码上,还是代码本身的问题至少用于更新控制中心中的图标。
  • 你解决了这个问题吗?我们应该像@pgmarchenko 所说的那样停用 AVAudioSession 吗?我一直在寻找解决方案而没有制作 AVAudioSession.setActive(false)

标签: ios objective-c


【解决方案1】:

首先阅读此answer。它包含基本信息。

@pgmarchenko speaks 正确。使用 MPNowPlayingInfoPropertyPlaybackRateMPNowPlayingInfoPropertyElapsedPlaybackTime 来更新搜索栏。阅读更多here

命令中心的播放/暂停按钮本身会根据您的播放器状态切换到正确的状态。我使用 IOS 12Swift 5AVPlayer 播放音频文件,一切正常。例如,

player.pause() //Audio file playback pauses and command center pause button changes to play button
player.play() //Audio file playback continues and command center play button changes to pause button

但是我遇到了另一个问题。当音频文件完成播放时,命令中心的暂停按钮不会被播放按钮取代,尽管它应该。 为了解决这个问题,我使用 actionAtItemEnd 属性并将其设置为 none(默认情况下它处于暂停状态)。

player.actionAtItemEnd = .none

注意播放器播放完音频文件后处于playing状态。您需要处理这一刻并暂停。例如使用AVPlayerItemDidPlayToEndTime

var player = AVPlayer()

override func viewDidLoad() {
    let playerItem = AVPlayerItem(url: url)
    player = AVPlayer(playerItem: playerItem)
    player.actionAtItemEnd = .none

    NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(notification:)), name: .AVPlayerItemDidPlayToEndTime, object: playerItem)
}

@objc func playerDidFinishPlaying(notification: Notification) {
    print("timeControlStatus:", self.streamingPlayer.timeControlStatus.rawValue) //timeControlStatus: 2
    player.pause()
}

现在,当播放器将音频文件播放到最后时,命令中心的暂停按钮将替换为播放按钮。我认为这是 Apple 的错误。

Deactivating 音频会话也会更改命令中心中的按钮。但我认为每次都停用会话是错误的。例如,当您暂停歌曲并将应用程序发送到后台时,标准 Apple Music 应用程序会停用会话。几秒钟后,当您从命令中心暂停时,应用程序处于后台。

对不起 Swift,我不知道 Objective-C。如果有人有更好的想法,请告诉我。

【讨论】:

    【解决方案2】:

    请使用下面的代码而不是 mixWithOtherOptions 来配置 AVPlayer。

     let audioSession = AVAudioSession.sharedInstance()
            do {
                try audioSession.setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: [.init(rawValue: 0), .allowAirPlay])
                print("Playback OK")
                try AVAudioSession.sharedInstance().setActive(true)
                print("Session is Active")
            } catch {
                print(error)
            }
    

    希望这对某人有所帮助

    【讨论】:

      【解决方案3】:

      对于 iOS 9.2

      我已经尝试了几乎所有 MPNowPlayingInfoCenter 和 MPRemoteCommandCenter 中的设置组合。

      停止更新搜索栏设置就足够了

      MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
      MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime
      

      但要切换暂停按钮,需要在暂停 audioPlayback 后停用 AVAudioSession。

      AVAudioSession.sharedInstance().setActive(false)
      

      最后我的 pauseCommand 处理程序看起来像:

      MPRemoteCommandCenter.sharedCommandCenter().pauseCommand.addTargetWithHandler { (e) -> MPRemoteCommandHandlerStatus in
              player?.pause()
              let infoCenter = MPNowPlayingInfoCenter.defaultCenter()
              infoCenter.nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
              infoCenter.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime
      
              _ = try? AVAudioSession.sharedInstance().setActive(false)
      
              return MPRemoteCommandHandlerStatus.Success
      }
      

      希望,这对某人有帮助。

      【讨论】:

      • 我用于处理 MPRemoteCommandCenter.nextTrackCommand 的代码神秘地导致所有锁定屏幕控件都被禁用。我在播放下一首曲目之前停用了 AVAudioSession,它们保持启用状态。
      【解决方案4】:

      bruce1337 的回答似乎是正确的

      在 Swift 中,以下(最终)将播放按钮变为暂停,反之亦然:

      let nowPlaying = [MPMediaItemPropertyAlbumTitle: "Led Zep IV",
                        MPMediaItemPropertyTitle: "Black Dog",
                        MPNowPlayingInfoPropertyPlaybackRate: NSNumber(float: 1.0)]
      MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = nowPlaying
      

      【讨论】:

        【解决方案5】:

        这个问题令人费解,因为答案最终与不同的 API MPNowPlayingInfoCenter 有关。对我有用的是在我上面的 updateRemoteControls 方法版本中更新 MPNowPlayingInfo 的 MPNowPlayingInfoPropertyPlaybackRate:

        - (void) updateRemoteControls {
        
            if (self.audioPlayer) {
                MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
        
                // Get currently playing information from other method:
                NSMutableDictionary *displayInfo = [NSMutableDictionary dictionaryWithDictionary:[self currentDisplayInfo]];
        
                // A playback rate of 0.0f corresponds to a "not playing" state.
                float playbackRate = self.isPlaying ? 1.0f : 0.0f;
                [displayInfo setObject:[NSNumber numberWithFloat:playbackRate] forKey:MPNowPlayingInfoPropertyPlaybackRate];
        
                // This will update the lock screen button and hide the progress bar if the playback rate is 0.0f:
                infoCenter.nowPlayingInfo = displayInfo;
        
            } else {
        
                [self clearNowPlayingInfo];
        
            }
        
        }
        

        【讨论】:

          【解决方案6】:

          在您的 updateRemoteControls 方法中,尝试更改以下内容,看看是否有帮助...

          - (void) updateRemoteControls
          {
          MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
          
          if (self.audioPlayer)
          {
              if (self.isPlaying)
                  [commandCenter.playCommand setEnabled:NO];
              else if (self.isPlayPaused)
                  [commandCenter.playCommand setEnable:YES];
          }
          else
              [self clearNowPlayingInfo];
          }
          

          另外,你不应该更新 pauseCommand 吗?如果是这样,请使用与更改部分相同的逻辑。我目前遇到了与此类似的问题,所以如果您解决了这个问题,请告诉我。只是想我可以通过修复一些可能有错也可能没有错的语法来提供帮助:)

          【讨论】:

            猜你喜欢
            • 2016-08-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-09
            • 2015-12-14
            • 2016-09-10
            • 2014-08-21
            • 1970-01-01
            相关资源
            最近更新 更多