gpt4 book ai didi

swift - AVPlayer 音频锁屏更新停止工作,仅在另一个 AVPlayer 实例播放视频内容后

转载 作者:搜寻专家 更新时间:2023-11-01 05:32:18 40 4
gpt4 key购买 nike

总结:

如果您只使用 AVPlayer 在您的应用程序中播放流音频,那么锁屏更新将工作得很好(许多流 - 一个接一个)。但是,如果您使用 AVPlayer 播放流式音频,然后播放本地视频文件(即使在使用不同的 AVPlayer 实例和不同的 View Controller 时),那么当您尝试再次播放流式音频时 - 锁定屏幕上不会显示任何内容任何更多。与清理无关——因为连续播放多个音频文件效果很好并且每次都显示在锁定屏幕上,但是只要你播放 1 个视频文件(或者甚至在不调用 .play() 的情况下将它初始化为任何 AVPlayer它),音频锁屏更新永久停止工作,你需要重新启动应用程序才能再次工作。对我来说这听起来像是一个 AVFoundation 错误......

详分割类:

我有一个包含 View Controller A 和 B 的应用程序。 View Controller A 是 View Controller B 的呈现器(使用导航 Controller 推送它)。 A 和 B 内部都有一个单独的 AVPlayer(A 播放音频。B 播放视频。音频是流式传输的。视频是 docs 目录中的本地文件)。

VC A 配置其 AVPlayer 以使用艺术作品图像、进度状态、前进 15 秒、后退 15 秒按钮更新锁定屏幕。 如果只使用 View Controller A 的播放器播放音频,一切都会很好——无论我来回播放多少次(即 VC B 的播放器从未用于播放 ())。 (整个 Controller 正确取消初始化)锁定屏幕始终有效,并始终更新所有需要的播放信息。

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(通过单击导航栏中的返回 <),锁定屏幕的进度更新将永远不会再次显示(整个播放 UI 不会出现),但后台播放仍然有效。

因此,一旦我在另一个 View Controller 上使用另一个 AVPlayer,我的原始播放器将永远无法再次向锁屏 UI 发布更新,直到应用程序终止并重新启动。

  • 我尝试在 VC A 中对播放器进行全面清理并重新初始化。
  • 我试着不在 VC B 上调用 .play()。(在这种情况下,VC A 一切正常)。
  • VC B 的播放器未注册锁屏更新,因为它只是在应用中播放视频以供预览。

一旦 AVPlayer 的另一个实例被引入并用于在另一个 View Controller 中播放,Apple 的 AVPlayer 的底层功能就会破坏 VC A 的 AVPlayer 的锁屏更新功能。

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

我该如何解决这个问题?我不想从 superview 中删除 VC A 的播放器,并将其传递给 VC B,然后重新配置它,如果用户回来,则在 VC A 中再次重新配置它。 (非常费力且容易出错)。在用户第一次通过 VC B 的播放(这是我的快乐之路的一部分)之后,它目前还永久地阻止锁屏更新

提前致谢,亚历克斯

最佳答案

通过在 VC-B 中删除对 AVPlayerViewController 的依赖,我能够避免这个问题。现在我使用第三方组件:“Player”(Cocoapods:“Player”),它使用 AVPlayerLayer,但不使用 AVPlayerViewController。 https://cocoapods.org/pods/Player

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

看来是 AVPlayerViewController 导致了锁屏问题并破坏了它。切换到使用仍然使用 AVPlayer 而不是 AVPlayerViewController 的“Player”后,问题就消失了,现在我总是在锁定屏幕上看到我的播放控件。

关于swift - AVPlayer 音频锁屏更新停止工作,仅在另一个 AVPlayer 实例播放视频内容后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55170068/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com