问题
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-1Response 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