P. Unto
P. Unto

Reputation: 246

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

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.

Upvotes: 4

Views: 1657

Answers (2)

ForeverEnjoy
ForeverEnjoy

Reputation: 11

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

Upvotes: 1

Jirui
Jirui

Reputation: 189

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.

Upvotes: 2

Related Questions