How to let AVPlayer retrieve playlist secured by SSL?

江枫思渺然 提交于 2019-11-28 18:29:17

From iOS 6 onwards AVAssetResourceLoader can be used for retrieving an HTTPS secured playlist or key file.

An AVAssetResourceLoader object mediates resource requests from an AVURLAsset object with a delegate object that you provide. When a request arrives, the resource loader asks your delegate if it is able to handle the request and reports the results back to the asset.

Please find the sample code below.

// AVURLAsset + Loader
AVURLAsset      *asset          = [[AVURLAsset alloc] initWithURL:url options:nil];
AVPlayerItem    *playerItem     = [AVPlayerItem playerItemWithAsset:asset];
AVAssetResourceLoader *loader   = asset.resourceLoader;
[loader setDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

// AVPlayer
AVPlayer        *avPlayer       = [AVPlayer playerWithPlayerItem:playerItem];

You will need to handle the resourceLoader:shouldWaitForLoadingOfRequestedResource:delegate method which will be called when there is an authentication need and you can use NSURLConnection to request for the secured resource.

(BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader    shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{

 //Handle NSURLConnection to the SSL secured resource here
  return YES;
}

Hope this helps!

P.S : The proxy approach using CocoaHTTPServer works well but using an AVAssetResourceLoader is a more elegant solution.

Nailer

It seems that until Apple lets us control what NSURLConnections the AVPlayer uses the only answer seems to be to implement a HTTP loopback server.

To quote the apple representative that answered our support question:

Another option is to implement a loopback HTTP server and point client objects at that. The clients can use HTTP (because their requests never make it off the device), while the loopback HTTP server itself can use HTTPS to connect to the origin server. Again, this gives you access to the underlying NSURLConnections, allowing you to do custom server trust evaluation.

Using this technique with UIWebView is going to be tricky unless you completely control the content at the origin server. If the origin server can return arbitrary content, you have to grovel through the returned HTTP and rewrite all the links, which is not much fun. A similar restriction applies to MPMoviePlayerController/AVPlayer, but in this case it's much more common to control all of the content and thus be able to avoid non-relative links.

EDIT: I managed to implement a loopback server using custom implemenations of the HTTPResponse and HTTPConnection classes found in CocoaHTTPServer

I can´t disclose the source, but I used NSURLConnection together with a mix of the AsyncHTTPResponse and DataHTTPResponse demonstration responses.

EDIT: Remember to set myHttpServerObject.interface = @"loopback";

EDIT: WARNING!!! This approach does not seem to work with airplay since the airplay device will ask 127.1.1.1 for encryption keys. The correct approach seems to be defined here: https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/AirPlayGuide/EncryptionandAuthentication/EncryptionandAuthentication.html#//apple_ref/doc/uid/TP40011045-CH5-SW1

"Specify the keys in the .m3u8 files using an application-defined URL scheme."

EDIT: An apple TV and iOS update has resolved the issue mentioned in the edit above!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!