我有一个播放视频的应用程序。它与iOS 11、12和iOS 13兼容。在iOS 11和12上,使用AVPlayerViewController
或什至AVPlayerLayer
都能正常播放视频。
但是,在iOS 13上,我开始收到报告,说有相当多的用户在更新iOS时突然没有加载视频(或仅加载音频,或者仅加载第一帧)。我确实很难复制它,但是有人提到它主要是由于网络连接不良而引起的,而且可以肯定的是,使用Network Link Conditioner可以复制它。
它特别影响HLS视频(例如Reddit使用的与花哨的实时流兼容的视频)。它可以与MP4一起正常使用。这是一个失败的示例URL:https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8
以下是触发它的网络链接调节器配置文件:https://i.imgur.com/XWsKUeM.jpg
这是一个触发它的示例项目,其中同时显示了AVPlayerViewController和AVPlayer(点击下载,Google很奇怪):https://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view
以下是使用AVPlayerViewController进行展示的示例代码:
let assetURL = URL(string: "https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8")!
// The following MP4 URL *does* work, for instance
// let assetURL = URL(string: "https://giant.gfycat.com/DependentFreshKissingbug.mp4")!
let player = AVPlayer(url: assetURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
如果我在iOS 12设备上尝试使用完全相同的代码,则可以正常运行。
有人对如何解决它有任何建议吗?如果您有时有时重新开始,则可以正常播放视频,但不够可靠,因此似乎无法解决该问题。视频内容绝对不是我在iOS开发中的强项,所以我开始有点挠头,对您的任何帮助将非常感激。
注意:我很清楚这是(可能是)一个iOS错误,我将提交Radar,但我现在仍然必须对其进行处理。
答案 0 :(得分:1)
您需要对playerItems状态进行了解,以了解何时可以播放。然后在playerItem状态更改为准备播放,请呼叫您的player.play。
playerItem.addObserver(self,
forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
// Only handle observations for the playerItemContext
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItemStatus
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
// Switch over status value
switch status {
case .readyToPlay:
// Player item is ready to play.
case .failed:
// Player item failed. See error.
case .unknown:
// Player item is not yet ready.
}
}
}