Video playback issues only on iOS 13 with AVPlayerViewController and AVPlayer when using HLS video

痞子三分冷 提交于 2020-05-25 16:57:18

问题


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.

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.

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

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

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

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()
}

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

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.

Note: I'm quite aware this is (likely) an iOS bug and I will file a Radar, but I still have to deal with it now.


回答1:


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.
        }
    }
}




来源:https://stackoverflow.com/questions/58585185/video-playback-issues-only-on-ios-13-with-avplayerviewcontroller-and-avplayer-wh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!