使用HLS视频时,仅在具有AVPlayerViewController和AVPlayer的iOS 13上视频播放问题 [英] Video playback issues only on iOS 13 with AVPlayerViewController and AVPlayer when using HLS video

查看:92
本文介绍了使用HLS视频时,仅在具有AVPlayerViewController和AVPlayer的iOS 13上视频播放问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以播放视频的应用程序.它与iOS 11、12和iOS 13兼容.在iOS 11和12上,使用AVPlayerViewController甚至只是AVPlayerLayer都能正常播放视频.

I have an app that plays back videos. It's compatible with iOS 11, 12 and iOS 13. On iOS 11 and 12, video playback works properly as expected using either AVPlayerViewController or even just AVPlayerLayer.

但是,在iOS 13上,我开始收到一些报告:突然有很多用户在更新iOS时未加载视频(或仅加载音频,或者仅加载第一帧).我确实很难复制它,但是有人提到它主要是由于网络连接不良而引起的,并且可以肯定地说,使用Network Link Conditioner可以复制它.

However, on iOS 13 I started getting reports that suddenly video wasn't loading (or would only load audio, or only the first frame) for quite a few users when they updated iOS. I had a really hard time replicating it, but some mentioned it occurred mostly with poor network connections, and sure enough with Network Link Conditioner I was able to reproduce it.

它特别影响HLS视频(例如Reddit使用的与花哨的实时流兼容的视频).它可以与MP4一起正常使用.这是一个失败的示例URL: https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8

It specifically affects HLS video (the fancy livestream compatible one that Reddit uses, for instance). It continues to work fine with MP4. Here's an example URL that fails: https://v.redd.it/gl3chx2kd4v31/HLSPlaylist.m3u8

以下是触发它的网络链接调节器配置文件: https://i.imgur.com/XWsKUeM. jpg

Here's a Network Link Conditioner profile that triggers it: https://i.imgur.com/XWsKUeM.jpg

这是一个触发它的示例项目,显示了AVPlayerViewController和AVPlayer(点击下载,Google很奇怪): https://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view

Here's a sample project that triggers it, showing both AVPlayerViewController and AVPlayer (hit Download, Google is being weird): https://drive.google.com/file/d/1RS5DvUypdOLFCYJe1Pt2Ig0fQljZDLs2/view

以下是使用AVPlayerViewController进行展示的示例代码:

Here's sample code showing it off with 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设备上尝试使用完全相同的代码,则可以正常运行.

If I try that exact same code on an iOS 12 device instead it works perfectly.

有人对如何解决它有任何建议吗?如果您有时有时重新开始,则可以正常播放视频,但不够可靠,因此似乎无法解决该问题.视频内容绝对不是我在iOS开发中的强项,所以我开始有点挠头,对您的帮助将非常感激.

Does anyone have any suggestions on how to fix it? If you scrub back to the beginning sometimes you can get the video to play back properly, but not reliably enough so to seemingly build a solution off that. Video stuff definitely isn't my forte in iOS development so I'm starting to scratch my head a little, any help would be super appreciated.

注意:我很清楚这是(可能)一个iOS错误,我将提交Radar,但我现在仍然必须对其进行处理.

推荐答案

您需要对playerItems状态进行kvo才能知道何时可以播放.然后在playerItem状态更改为准备播放,请呼叫您的player.play.

You need to kvo on the playerItems status in order to know when it is ready to play. Then in the playerItem status change to ready to play call your 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.
        }
    }
}


这篇关于使用HLS视频时,仅在具有AVPlayerViewController和AVPlayer的iOS 13上视频播放问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆