Source#
Apple Developer Forums: https://developer.apple.com/forums/thread/813377
Problem#
A short looping hero/front-screen video is delivered as HLS because the product needs native selectable subtitles. After the first pass, AVPlayer requests the same .ts / .m4s segments again on every loop even though the media is unchanged and has already been downloaded once.
Network traces therefore look like:
loop 1
playlist → segment 1 → segment 2 → segment 3
loop 2
playlist → segment 1 → segment 2 → segment 3
loop 3
playlist → segment 1 → segment 2 → segment 3
The tempting assumption is that identical URLs plus normal HTTP cache headers should make subsequent loops local. Apple DTS clarified that this is not the supported persistence model for HLS playback.
Evidence level#
Apple Confirmed.
Apple DTS states that HLS media is not disk-cached by default for ordinary AVPlayer playback and that AVAssetDownloadURLSession is the supported API for persisting HLS assets. The forum poster then confirmed that moving this particular use case to MP4 with a soft WebVTT subtitle track allowed the loop to reuse cached media successfully.
Explanation#
Do not model AVPlayer HLS segment fetching as equivalent to ordinary app-controlled URLSession caching.
A better boundary is:
ordinary remote HLS playback
↓
AVPlayer manages playlist/segment loading
↓
transient playback buffering/cache
↓
not a contract for persistent segment reuse across loops
versus:
AVAssetDownloadURLSession
↓
asset download task
↓
managed local HLS package
↓
AVAssetCache / offline playback
AVURLAsset.assetCache is only available when the asset is configured to store or access media data from disk. AVAssetCache is the inspection API for locally persisted HLS media, including isPlayableOffline and cached media-selection options.
This means:
segment fetched once
≠
segment persisted for future loops
and:
HTTP URL is identical
≠
AVFoundation promises to serve the next playback pass from disk
Investigation#
Before treating repeated requests as a CDN or cache-header bug, separate three questions:
1. Is AVPlayer re-requesting the same resource?
2. Is that request actually transferred over the network or satisfied by an intermediary cache?
3. Does the product require persistent reuse across independent playback passes?
Capture:
request URL
response status
response bytes
Age / cache headers where relevant
loop number
player item identity
seek/restart method
Then distinguish two loop implementations:
A. replace/recreate the player item at end
B. keep the same item, pause at end, seek to zero, resume
Apple DTS suggested B as a lightweight experiment using actionAtItemEnd = .pause followed by a seek to zero. It may reduce unnecessary item lifecycle churn, but it is not a persistence guarantee and should not be described as HLS disk caching.
Solution / Guideline#
Choose the delivery model from the product requirement rather than trying to force HLS playback into a file-cache contract.
Option A — Persistent HLS is required#
Use AVAssetDownloadURLSession / AVAssetDownloadTask and play the managed local HLS asset.
Use this when the asset genuinely needs:
offline playback
persistent reuse
HLS rendition/media-selection behavior
FairPlay persistable-content-key integration when applicable
Option B — The content is a short loop with subtitles#
Consider file-based media with soft subtitles instead of HLS when ABR/live/HLS-specific behavior is unnecessary.
Apple DTS notes that AVFoundation supports subtitle formats such as WebVTT and iTunes Timed Text in .mov / .mp4 workflows. In the reported case, MP4 + soft VTT solved the product requirement and eliminated repeated HLS segment requests on each loop.
Option C — Keep remote HLS#
Accept that repeated HLS resource requests can occur. Optimize CDN/cache behavior server-side if useful, but do not build client correctness around assumed segment persistence inside AVPlayer.
Verification#
Run this matrix with the same short content:
A. HLS + recreate AVPlayerItem each loop
B. HLS + same item + actionAtItemEnd(.pause) + seek(0)
C. downloaded HLS via AVAssetDownloadURLSession
D. MP4/MOV + soft WebVTT subtitle track
Record per loop:
segment/media requests
transferred bytes
startup delay
subtitle availability
memory footprint
local assetCache state
Expected interpretation:
A/B still issue HLS requests
→ normal remote-HLS behavior; seek reuse is not persistence
C performs without remote media fetches
→ supported persisted-HLS path
D satisfies subtitles + loop with file caching
→ HLS was unnecessary for this product shape
Engineering rule#
Playback buffering is not storage semantics.
For AVFoundation, distinguish:
buffered for current playback
≠
HTTP response cached
≠
asset persisted for offline/reuse
If the requirement is "download once, replay locally many times," choose an API or media container that explicitly provides persistence rather than inferring it from the fact that AVPlayer previously fetched the bytes.
References#
- Apple Developer Forums: https://developer.apple.com/forums/thread/813377
AVAssetDownloadURLSession: https://developer.apple.com/documentation/avfoundation/avassetdownloadurlsessionAVAssetCache: https://developer.apple.com/documentation/avfoundation/avassetcache