The basic idea combines a preload hint in the Playlist with a blocking request for the hinted segment (a new client behavior). So there would be two blocking requests against the edge — one for the playlist update and one for the segment. This allows the client to avoid a second round-trip time for the segment request, without requiring H2 push (or any Link headers).
This change has several benefits:
- It allows segments to be vended by a different server / authority domain than the playlist (and supports app-generated and app-proxied playlists)
- Eliminating the _HLS_push parameter reduces the complexity and caching matrix of the origin API
- Having the CDN edge also block on the segment request improves cache fill performance
- It removes the requirement that CDNs support H2 Push
- while it is a little more work for MSE-based clients, it is more transparent than the black box that is the H2 push cache
Here's how it works: upon writing a playlist whose last part is filePart88.0.mp4, the end of the playlist looks like this:
...
#EXT-X-PART:DURATION=0.40000,URI="filePart87.8.mp4"
#EXT-X-PART:DURATION=0.40000,INDEPENDENT=YES,URI="filePart87.9.mp4"
#EXT-X-PART:DURATION=0.36667,URI="filePart87.10.mp4"
#EXTINF:3.96667,
fileSequence87.mp4
#EXT-X-PART:DURATION=0.40000,INDEPENDENT=YES,URI="filePart88.0.mp4"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="filePart88.1.mp4"
When the client sees the PRELOAD-HINT tag it issues a speculative GET for filePart88.1.mp4 along with its playlist GET for _HLS_part=1. This flows through the edge to the origin, which blocks on it until filePart88.1.mp4 is complete and can be delivered at link speed (to enable ABR measurement, basically, the same time it gets added the playlist as a PART tag). Then the origin sends both responses: the playlist containing filePart88.1.mp4 and filePart88.1.mp4 itself. From a delivery point of view, this performs about the same over H2 as a playlist update followed by a Push. (To be clear: we are not backing away from HTTP/2, just H2 Push.)
We considered allowing the URI in the PRELOAD-HINT to differ from the one in the corresponding PART tag, but abandoned that idea because it makes the job of filling the edge cache complicated. So part URIs always need to be active to support the blocking behavior (but don't remain in the playlist very long anyway).
Attached is an updated draft of the LL-HLS spec, as well as a redline against the current public version. I'll send out another email when it goes live on
developer.apple.com.