user1899931
user1899931

Reputation: 107

AVPlayer making extraneous http request prior to playback of HLS / AES-encrypted video

We're using AVPlayer on iOS 8.4 to play HLS, AES-encrypted video.

Our .m3u8 files include the url of the license server, e.g.:

EXT-X-KEY:METHOD=AES-128,URI="https://...."

In our iOS application, we're using AVAssetResourceLoaderDelegate method resourceLoader:shouldWaitForLoadingOfRequestedResource: to intercept the request that gets sent by the AVPlayer (or some object within AVFoundation) to the license server. Within that method, we add a token (required by the license server) to the request's queryString.

The license server receives the request with the token, returns the encryption key, and playback begins. In other words, everything works as expected.

However, we're noticing (using the "Charles" http monitor) that following the creation of the AVPlayerItem and prior to the invocation of the resourceLoader: method, AVFoundation sends an initial request to the license server url; a request that's not "routed" through method resourceLoader:. This request is rejected at the server as our iOS code never has a chance to append the token before the request goes out.

Summary of events:

• AVPlayerItem/AVAsset is created and initialized with the url of the .m3u8 index file.

• Something within the AVFoundation framwork makes a request to the license server specified in the .m3u8 file. This initial request is NOT intercepted by method  recourceLoader:shouldWaitForLoadingOfRequestedResource: and the unmodified request hits the license server.  Because the request doesn't contain a required token in the queryString, it fails and no encrypton key is returned.

A second request is made by AVFoundation to the licesnse server. This request IS caught by recourceLoader:...and modified appropriately. The license server returns an encryption key and playback begins.

This behavior can be replicated using Apple's AVARLDelegateDemo app.

Questions:

Is the initial http request sent by AVFoundation normal?

If so, why is it necessary and why isn't it getting "routed" through the resourceLoader: method?

Is it possible to suppress the initial request or modify it before it's sent?

Thank you!

Upvotes: 5

Views: 2699

Answers (1)

Simon Tillson
Simon Tillson

Reputation: 3618

The simple answer to this issue is that the AVAssetResourceLoaderDelegate will only handle requests for URLs which cannot be processed in the normal way.

In your case, the URL for your key is a normal https:// URL, so the AVPlayer will try to process this request itself. Without the token though, this request is rejected by your server. Therefore, the AVAssetResourceLoaderDelegate will then pass the request to your delegate to handle it.

To avoid the 'extraneous' request, modify your playlist so that the encryption key URL has an invalid scheme. Use something like crypt://... instead of https://....

That way, you will receive the resource loader call on the first try, and you can replace the crypt:// scheme with https:// and add your token before making the request yourself in the normal way.

It's just how AVAssetResourceLoaderDelegate works, I'm afraid. Check out Apple's sample app here for more details: https://developer.apple.com/library/ios/samplecode/sc1791/

Upvotes: 4

Related Questions