AVPlayerLayer 进入背景后在隐藏控制器中并进入前景并显示后为空白
Posted
技术标签:
【中文标题】AVPlayerLayer 进入背景后在隐藏控制器中并进入前景并显示后为空白【英文标题】:AVPlayerLayer blank after entering background while being in a hidden controller and entering foreground and being shown 【发布时间】:2014-02-12 18:52:55 【问题描述】:我有一个使用 AVPlayerLayer 的应用程序(在 UIView 的子类中使用,就像 Apples AV Foundation Programming Guide 一样)。我有几个视图控制器被保存在对菜单负责的视图控制器中(使用了 JASidePanels)。问题如下:
一切正常,直到带有 AVPlayer 的视图控制器没有隐藏(显示其他视图)并且应用程序进入后台,再次返回并返回视图。这会导致 AVPlayerLayer 显示空白/透明。该项目已加载,我可以尝试播放它,确实它已播放但没有看到视频。
这种行为的解决方案是什么(以及它的原因是什么)?提前谢谢。
【问题讨论】:
你解决过这个问题吗? PS。相关xkcd:xkcd.com/979 我遇到了类似的问题,但视频没有恢复,而是变得透明。尝试在应用进入后台时暂停视频,然后在应用进入前台时播放视频。 在此处粘贴代码。这将有助于我们了解您的问题。 最后我只是在播放器中重新加载视频文件并“接受”这个错误;)。 【参考方案1】:player?.seek(to: .zero)
触发 AVPlayerLayer
渲染预览。
在我的情况下,为了在关闭/打开应用程序时顺利更新和暂停视频,我添加了以下内容:
private func setupObservers()
NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
@objc
private func willResignActive()
player?.pause()
@objc
private func didBecomeActive()
player?.seek(to: .zero)
【讨论】:
【参考方案2】:我不确定是什么原因造成的,但对我有用的解决方案是在 AVPlayerLayer 上重置播放器
avPlayerLayer = AVPlayerLayer(player: currentAvPlayer)
【讨论】:
【参考方案3】:SWIFT 3
我遇到了同样的问题。每次我的应用程序进入后台然后回到前台时,我的 AVPlayer 都会消失。下面是一个更简单的代码版本,适用于我……我需要在 UIApplicationWillEnterForeground 上重置播放器。如果您需要,我可以添加更多代码,请告诉我。它现在似乎正在工作。干杯!
import UIKit
import AVFoundation
class ViewController: UIViewController
var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!
var paused: Bool = false
override func viewDidLoad()
super.viewDidLoad()
// Be sure to add your file to your app (not in the assets folder) and add it to your target
let theURL = Bundle.main.url(forResource:"yourVideoFile", withExtension: "mp4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.frame = view.layer.bounds
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
// .none is for looping videos if you uncomment "p: AVPlayerItem" below.
// .pause is to pause at the end of the video and hold the last frame
avPlayer.actionAtItemEnd = .pause
view.layer.insertSublayer(avPlayerLayer, at: 0)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(notification:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: avPlayer.currentItem)
NotificationCenter.default.addObserver(self, selector: #selector(appMovingToForeground), name: Notification.Name.UIApplicationWillEnterForeground, object: nil)
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
avPlayer.play()
paused = false
func playerItemDidReachEnd(notification: Notification)
print("THE END")
// uncomment the following line for a looping video
// let p: AVPlayerItem = notification.object as! AVPlayerItem
// p.seek(to: kCMTimeZero)
func appMovingToForeground()
print("App moved to foreground!")
avPlayerLayer = AVPlayerLayer(player: avPlayer)
view.layer.insertSublayer(avPlayerLayer, at: 0)
// If you want your video or video loop to continue playing when app moves to foreground add:
// avPlayer.play()
// paused = false
【讨论】:
【参考方案4】:最后我只是在播放器中重新加载视频文件。
【讨论】:
以上是关于AVPlayerLayer 进入背景后在隐藏控制器中并进入前景并显示后为空白的主要内容,如果未能解决你的问题,请参考以下文章