Avplayer音频锁定屏幕更新停止工作,仅在另一个Avplayer实例播放视频内容之后



摘要:

如果您仅使用Avplayer仅在应用程序中播放流音频,则锁定屏幕更新将正常工作(许多流 - 一个接一个)。但是,如果您使用avplayer播放两个流音频,然后播放本地视频文件(即使使用avplayer和其他视图控制器上的单独实例),那么当您尝试再次播放流音频时 - 锁定屏幕上都不会显示再过。与清理无关 - 因为仅播放多个音频文件可以正常工作并每次都显示在锁定屏幕上,但是一旦您播放1个视频文件(或者甚至在没有拨打.play .play()的任何Avplayer初始化它)它),音频锁定屏幕将永久停止工作,您需要重新启动该应用程序才能再次工作。对我来说,这听起来像是一个avoundation错误...

详细分解:

我有一个带有视图控制器A和B的申请。视图控制器A是View Controller B的主持人(使用导航控制器推动它)。A和B内部都有A 单独的 avplayer(A的播放音频。B的播放视频。音频是流式传输的。视频是DOCS目录中的本地文件)。

vc a配置其Avplayer,以使用艺术品图像,进度状态,前向15S,后部15S按钮更新锁定屏幕。只有使用查看器A的播放器用于播放音频,一切都很好 - 无论我向前返回多少次(即VC B的播放器从来都不习惯播放())。(整个控制器正确地降低)锁定屏幕始终有效,并始终更新所有必需的播放信息。

VC A(AVPLAYER1) -> push-> vc b(avplayer2)

这是注册锁定屏幕更新的代码(包括按钮和进度回调):

func setupNowPlaying() {
    var nowPlayingInfo = [String : Any]()
    nowPlayingInfo[MPMediaItemPropertyTitle] = title
    nowPlayingInfo[MPMediaItemPropertyArtist] = artist
    let artwork = MPMediaItemArtwork.init(boundsSize: self.artImage.size, requestHandler: { (size) -> UIImage in
        return self.artImage
    })
    nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
    guard let player = self.player else { return }
    guard let currentItem = self.player?.currentItem else { return }
    nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.asset.duration.seconds
    nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
    nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = currentItem.currentTime().seconds
    let rcc = MPRemoteCommandCenter.shared()
    let skipBackwardCommand = rcc.skipBackwardCommand
    skipBackwardCommand.isEnabled = true
    skipBackwardCommand.addTarget(handler: skipBackward)
    skipBackwardCommand.preferredIntervals = [15]
    let skipForwardCommand = rcc.skipForwardCommand
    skipForwardCommand.isEnabled = true
    skipForwardCommand.addTarget(handler: skipForward)
    skipForwardCommand.preferredIntervals = [15]
    UIApplication.shared.beginReceivingRemoteControlEvents()
    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

此外,以下内容是在AppDelegate(ApplicationWillResignactive)中连接的,以启用背景播放(标准内容):

    do {
        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay, .allowBluetooth, .allowBluetoothA2DP ])
        print("Playback OK")
        try AVAudioSession.sharedInstance().setActive(true)
        print("Session is Active")
    } catch {
        print(error)
    }

当VC B出现并使用其自己的单独的Avplayer 播放视频时,没有在锁定屏幕上显示任何内容的问题开始发生。VC A的Avplayer首先被暂停。如果我在VC B的播放器上调用.play(),那么当我回到VC A(通过返回<在nav bar中)时,锁定屏幕的进度更新将永远不会再次显示(整个播放uidive not'''出现),但是背景播放仍然有效。

因此,一旦我在另一个视图控制器上使用另一个Avplayer,我的原始播放器将永远无法将更新发布到锁定屏幕UI,直到应用程序终止并重新发布应用程序为止。

  • 我试图在VC A中的播放器上进行完整的清理并重新定位。
  • 我试图在VC B上不调用.play()。
  • VC B的播放器未在锁定屏幕更新中注册,因为它只是为了预览目的在应用中播放视频。

Apple的Avplayer在hood的某些东西中断了VC A的Avplayer锁定屏幕更新功能,一旦引入了Avplayer的另一个实例并用于在另一个View Controller中播放。

我知道这个问题与单独控制器上的第二个Avplayer有关,因为只是在VC B的播放器上没有调用.play(),请在VC A的播放器上修复屏幕锁定更新消失问题。>

我该如何解决这个问题?我不想将VC A的播放器从Superview中删除,并将其传递给VC B,然后重新配置,然后如果用户返回,则在VC A中再次对其进行重新配置。(非常费力,容易发生)。目前,在用户首次通过VC B的播放(这是我的快乐路径的一部分)之后,它还将永久更新。

预先感谢Alex

我能够通过在VC-B中删除对AvplayerviewController的依赖来避免此问题。现在,我使用的第三方组件称为:" player"(cocoapods:" player"),该组件使用Avplayerlayer,但不使用AvplayerviewController。https://cocoapods.org/pods/player

不幸的是,我丢失了播放UI控件(进度栏,播放按钮,全屏按钮 - AvplayerviewController免费提供给我)。因此,我将不得不构建一些自定义的播放控件。

因此,AvplayerviewController似乎在锁定屏幕上引起了问题并打破它。切换到仍然使用Avplayer但不使用AvplayerviewController的"播放器"后,问题就消失了,现在我总是在锁定屏幕上看到我的播放控件。

最新更新