HLS AVPlayer modify master manifest

Hi,

I am using AVPLayer for play HLS video(live, vod).

Is there any possibility to modify master manifest on the fly? The goal to remove some of variants from the playlist.

Example:

We have master manifest which contains several variants:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/lo_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=440000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/hi_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=640000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/high/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5"
http://example.com/audio/index.m3u8

And I want dynamically remove all variants except the last and have in the result:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5"
http://example.com/audio/index.m3u8

Thanks in advance for any help!

PS: URLProtocol doesn't suitable for this https://developer.apple.com/forums/thread/75328

Hi ! Have you ever got solution for this issue ?

2 possibilities I used before:

  • Setup a Charles proxy and prepare a rewrite rule using regular expressions that match the unwanted renditions and replace them with a blank string
  • Define a resourceLoaderDelegate (https://developer.apple.com/documentation/avfoundation/avassetresourceloaderdelegate) on your avAsset and give the master m3u8 a custom protocol (e.g. mymasterprotocol://example.com/master.m3u8). Upon interception in the delegate, you can do the actual remote playlist request with http protocol, filter out the stuff you don't want to keep using string operations and only return the renditions you are interested in from the delegate method.

When setting up the avAsset:

self.avAsset.resourceLoader.setDelegate(resourceLoaderDelegate, queue: self.resourceLoaderDelegateQueue)

In the resourceLoaderDelegate implement:

func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
    let request: URLRequest = loadingRequest.request
    let url: URL = request.url!
    let scheme: String = url.scheme!
   
    if scheme == "mymasterprotocol" {
        handleRemoteMasterRequestAndFilterStuff(loadingRequest: loadingRequest)
        return true
    }
     
    return false
}
HLS AVPlayer modify master manifest
 
 
Q