【问题标题】:Video playback issues only on iOS 13 with AVPlayerViewController and AVPlayer when using HLS video使用 HLS 视频时,仅在带有 AVPlayerViewController 和 AVPlayer 的 iOS 13 上出现视频播放问题
【发布时间】:2020-02-23 09:07:31
【问题描述】:

我有一个可以播放视频的应用。它与 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(点击下载,谷歌很奇怪):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,但我现在仍然需要处理它。

【问题讨论】:

  • 任何进度更新???
  • 我们也面临同样的问题。有什么解决办法吗?
  • @christianselig - 更好地提交错误

标签: ios avplayer ios13 avplayerviewcontroller avplayerlayer


【解决方案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.
        }
    }
}


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多