Downloaded HLS stream doesn't work offline

Hi,


we implemented downloading vimeo hosted hls streams using AVAssetDownloadTask, but when attempting to play downloaded hls in airplane mode, sometimes it fails with NSURLErrorNotConnectedToInternet error. Usually downloaded videos work fine even when AVURLAsset is created from that filesystem *.movpkg url.


Before playing we check assetCache.isPlayableOffline and it's true! There are no subtitles or audio tracks, anything in the streams. How is it possible that iOS tells me I can play this without connection and then it doesn't work.


I checked AVPlayerItem's access and error logs and usually there are no error entries and access entries, but when there's an error entry it's for the master playlist url, but I see the playlist and stream downloaded when inspecting .movpkg directory and nothing suspicious in those xml.


I'm kinda lost now and don't know how to further investigate issue. Thanks for any help!

Replies

Hello,


I have same issue. I even check when I'm online that offline file is used (almost no network traffic visible in Profile in comparison with online content playback).

Have you find the solution for this problem?

Hi guys,


that's a problem mostly on iOS 10 or when using AVAssetDownloadTask. I recommend to drop support for iOS 10 and using AVAggregateAssetDownloadTask.

Your issue is very likely caused by HLS stream manifest containing higher bitrate than 10MBit (or perhaps 8Mbit). In that case even if you have the stream downloaded for offline playback, the player tries to start with lower bitrate, but because you don't have it, playback cannot continue. If you connect network monitor tool, you will see that player will switch to lower bitreate and downloads first segment of lower bitrate video (for example only one 10 second segment) and then immediately switches to higher bitrate. This low bitrate segment gets stored in your local movpkg and next time when you start playback, it works offline without any problems.

To fix this, you will have to either download highest bitrate and lowest bitrate (it can add a few percent of storage needed) or you need to limit high bitrate to be below 10Mbit. Or maybe it's just video being higher resolution than Full HD (1920x1080p) - don't rememebr precisely logic of the player.

I hope this info helps.

Regards.

Hi there,
we also ran into the same problem. We were able to fix it by sorting the stream playlist items in the master m3u8 file by bandwidth in descending order. This approach was also mentioned in session 503 of WWDC 2016 @ 33:15 (https://developer.apple.com/videos/play/wwdc2016/503) to better estimate the initial quality of the HLS playback.
Cheers!
Update:
After sorting the playlist items, the problem reappeared eventually. After another debugging session with different HLS streams, we noticed that downloaded HLS streams adhere to the `Cache-Control` HTTP header of the playlist URLs. In our case, a `must-revalidate` was included in the header value. This value led to the described problem after the cache became stale/expired (`max-age` value in `Cache-Control` header). Choosing an appropriated header value without including `must-revalidate`, resolved the problem instantly for us in a reproducible manner.

@mathe-box
do you have more information regarding the content adherence to caching headers? We are running into similar issues we are hosting on cdn the only headers I see is an expires and etag headers


Hi guys,

Where you put this AVAssetDownloadTask. Mainly all samples are for older versions and those do not work with the storyboard. Any ideas for that?