iOS: bug in AVPlayerItem when receiving `304 Not Modified` response

只谈情不闲聊 提交于 2019-12-10 21:50:47

问题


This is a very weird bug.

I have a tableView with each cell using an AVPlayer to stream a video from a remote server (think a Vine-like timeline). So when I scroll, the cells that get reused reconfigure their player with the new video.

The problem is: if I scroll back and forth very fast, getting the same video in and out of the screen, the request sent by the AVPlayer eventually changes, to include the HTTP Headers If-None-Match and If-Modified-Since, which are not there the rest of the time. It systematically makes the server return a 304 Not Modified response.

That doesn't seem to please the AVPlayer's playerItem, which changes its status to AVPlayerItemStatusFailed (interestingly, the AVPlayer's status is still AVPlayerStatusReadyToPlay). The error is AVErrorUnknown (-11800) with an OSStatus -12983 (which isn't documented anywhere and is in no header in the entire iOS SDK).

That's when it gets weird: whatever I do next, the AVPlayer and its playerItem are irrevocably burnt. Even if I reconfigure them with another asset, they'll just return this status and show a black frame. Weirder still: even if I initialize another AVPlayer, AVPlayerItem and AVAsset, it just won't play anymore, I have to kill and restart the app.

At this point, I'm pretty clueless. Any idea what's happening here? Preventing the player from including these headers in its connection would fix it, but it's not exposing its request serializer.


回答1:


304 Not Modified

I have encountered 304 Not Modified response, which happens when AVPlayer replay same video, and AVPlayerItem.status becomes failed, detail error is content range mismatch - should be start 0 length 2 is start 0 length 1048575. But, the difference is that playback is normal if AVPlayer switch to play other video.

Detail Http request and response example:

Request part
If-Modified-Since: Sat, 24 Jun 2017 03:41:12 GMT
Range:bytes=0-1

Response part
HTTP/1.1 304 Not Modified
Content-Range: bytes 0-1048575/13852554

Solution:
Modify server-side logic, change Content-Range value to bytes 0-1/13852554 or delete Content-Range directly, then playback will start normally.




回答2:


I met the same issue. so I add If-None-Match: ${unique value} header to prevent return 304. it work to me.

    var player = AVQueuePlayer()
    func play(url: String) {
        let headers = ["If-None-Match": "1"]
        let options = ["AVURLAssetHTTPHeaderFieldsKey": headers]
        let asset = AVURLAsset(url: URL(string: url)!, options: options)
        let playItem = AVPlayerItem(asset: asset)
        player.replaceCurrentItem(with: playItem)
        player.automaticallyWaitsToMinimizeStalling = false
        player.playImmediately(atRate: 1)
    }


来源:https://stackoverflow.com/questions/29243822/ios-bug-in-avplayeritem-when-receiving-304-not-modified-response

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