Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
349 views
in Technique[技术] by (71.8m points)

ios - How to let AVPlayer retrieve playlist secured by SSL?

We′re developing a HTTP-streaming iOS app that requires us to receive playlists from a secured site. This site requires us to authenticate using a self signed SSL certificate.

We read the credentials from a .p12 file before we use NSURLConnection with a delegate to react to the authorization challenge.

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    [[challenge sender] useCredential:  self.credentials forAuthenticationChallenge:challenge];
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return YES;
}

By doing this initial connection to the URL where we′re getting the .m3u8 playlist we′re able to play back the playlist using AVPlayer. The problem is that this method only works in the simulator.

NOTE: We′re able to download the playlist using the NSURLConnection on device. This must mean that the AVPlayer somehow can′t continue using the trust established during this initial connection.

We have also tried adding the credentials to the [NSURLCredentialStorage sharedCredentialStorage] without any luck.

Below follows our shotgun approach for that:

NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
                                         initWithHost:host
                                         port:443
                                         protocol:@"https"
                                         realm:nil
                                         authenticationMethod:NSURLAuthenticationMethodClientCertificate];



[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:creds
                                                    forProtectionSpace:protectionSpace];

    NSURLProtectionSpace *protectionSpace2 = [[NSURLProtectionSpace alloc]
                                         initWithHost:host
                                         port:443
                                         protocol:@"https"
                                         realm:nil
                                         authenticationMethod:NSURLAuthenticationMethodServerTrust];



[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:creds
                                                    forProtectionSpace:protectionSpace2];

EDIT: According to this question: the above method doesn′t work with certificates.

Any hint to why it doesn′t work on device, or an alternate solution is welcome!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...