Is it possible to cache HLS segments with AVPlayer?
Let's start with really good news - iOS 10 and up - gives this out of the box.No more need for hacks soon. More details can be found in the following WWDC16 session about whats new in HTTP Live Streaming:https://developer.apple.com/videos/play/wwdc2016/504/
Now back to the current state of things - iOS 9 and lower:With AVPlayer, no. But you can cache HLS segments via a local HTTP server and play the local stream with AVPlayer.
AVPlayer and AVAsset don't contain the necessary information when dealing with HLS playback (It behaves differently than a MP4 static file for example).
TL;DR - You need to use HTTP requests to get the segments and serve them using a local HTTP Server.
A few companies, including the one I'm working for, are using this strategy.
Use a connection to download the segments at the quality you want, rebuild the manifest and flatten it all into one directory and one quality and then use a local http server inside the app to serve it to AVPlayer (AVPlayer can only play HLS streams served over HTTP - not from file assets).
There are edge cases, such as, buffering if you want to play and download in one run, rebuilding the m3u8 manifest correctly, and different AVPlayer states with disk reading.
I've found this out from first hand knowledge, both having such a system in production for 5 years and other video products in the App Store that use the same solution - in total serving many users.
This is also the best solution we've found for android.
Actually, we can get AVPlayer to play a video from network but if you want to to cache the downloaded data to play it locally, with AVPlayer that seems impossible now.
Fortunately, there are a great API is the resourceLoader object in AVURLAsset, which you can provide controlled access to a remote audio file to AVPlayer. This works like a local HTTP proxy but without all the hassles.
You can find more detail on https://gist.github.com/anonymous/83a93746d1ea52e9d23f
Starting with iOS 10, you can use
AVFoundation to download and store HLS movies on users' devices while they have access to a fast, reliable network, and watch them later without a network connection.
This wwdc2016/504/ session talks about
Offline HLS. It is about downloading and persisting assets using
AVAssetDownloadURLSession, which is a subclass of
URLSession, and here is used to manage
AVAssetDownloadTasks. The APIs mentioned in this session are available after iOS10.
wwdc2017/504 session introduced
AVAggregateAssetDownloadTask in iOS11.
An AVAssetDownloadTask used for downloading multiple AVMediaSelections for a single AVAsset, under the umbrella of a single download task.
Apple provides an example project for using
AVFoundation to Play and
Persist HTTP Live Streams. Demo doc. The demo project uses
/wwdc2017/504 also introduced a new API,
AVAssetDownloadStorageManager, to manage the policy for automatic purging of downloaded
- Expiration date
- Priority (important, default)
// Get the singletonlet storageManager = AVAssetDownloadStorageManager.shared()// Set the policylet newPolicy = AVMutableAssetDownloadStorageManagementPolicy() newPolicy.expirationDate = myExpiryDatenewPolicy.priority = .important storageManager.setStorageManagementPolicy(newPolicy, forURL: myDownloadStorageURL)