3

I'm currently trying to implement a service to handle DRM with FairPlay streaming on a tvOS App. Here is my workflow :

  1. I get the app certificate as Data

  2. From this certificate i get the SPC Datas, using :

    resourceLoadingRequest.streamingContentKeyRequestData(forApp: applicationCertificate, contentIdentifier: assetIDData, options: resourceLoadingRequestOptions)
    
  3. From the SPC Datas encoded to base64Data I request POST (with SPC in payload) on our server to get the license which gives me the CKD Datas

  4. Then when I get the CKC Datas, I use them as below :

     guard let dataRequest = resourceLoadingRequest.dataRequest else {
        print("no data is being requested in loadingRequest")
        let error = NSError(domain: AssetLoaderDelegate.errorDomain, code: -6, userInfo: nil)
        resourceLoadingRequest.finishLoading(with: error)
        return
     }
     dataRequest.respond(with: datas)
     resourceLoadingRequest.finishLoading() 
    

But after these steps I get the error :

Error Domain=AVFoundationErrorDomain Code=-11835 "Cannot Open" UserInfo={NSUnderlyingError=0x170440de0 {Error Domain=NSOSStatusErrorDomain Code=-42681 "(null)"}, NSLocalizedFailureReason=This content is not authorized., NSLocalizedDescription=Cannot Open}

Does anyone have an idea or a tips ?

Additional infos :

  • the playback process works with non-protected content.

  • playerItem.errorLog() returns nil.

  • playerItem.status == .failed returns true.

  • all the server side process seems to be OK since it's already used for the website and Smart TV.

Jqvk Blqck
  • 33
  • 4
  • I know it's off topic. But can you share how to get `applicationCertificate` please? – Hlung Aug 22 '17 at 10:14
  • Hi, I am also stuck at this similar problem. Did you find any solution for this ? – sahilchaddha1993 Nov 11 '17 at 07:38
  • 1
    @Hlung You get Your Application Certificate from a hosted server (recommended) or load into your App Bundle (Testing Purposes) and can gets its Data Bytes and send to ```loadingRequest.streamingContentKeyRequestData(forApp: certificateData, contentIdentifier: assetIdentifierData, options: nil) ``` . Your Certificate should most probably be in .cer format. And you can get its Data Bytes by : ```let certificateURL = Bundle.main.url(forResource: "certificate", withExtension: "der"), let certificateData = try? Data(contentsOf: certificateURL)``` – sahilchaddha1993 Nov 11 '17 at 07:42

1 Answers1

2

I recently ran into this exact same problem. The problem is the CKC response data returned from streamingContentKeyRequestData(forApp... is not just data, it is base 64 encoded string data. All you need to do is decode it before you respond to the data request:

 dataRequest.respond(with: Data(base64Encoded: datas)!)

For production code you'll want to handle the optionality properly. Hope this helps!

Tucker Sherman
  • 459
  • 7
  • 17