Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save asisadh/05ef160ea64fbd84110556ad0ea11ac3 to your computer and use it in GitHub Desktop.
Save asisadh/05ef160ea64fbd84110556ad0ea11ac3 to your computer and use it in GitHub Desktop.
FairPlay integration with Native AVPlayer Swift.
extension ViewController: AVAssetResourceLoaderDelegate{
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForRenewalOfRequestedResource renewalRequest: AVAssetResourceRenewalRequest) -> Bool {
return self.resourceLoader(resourceLoader, shouldWaitForLoadingOfRequestedResource: renewalRequest)
}
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
guard let url = loadingRequest.request.url else {
print("🔑", #function, "Unable to read the url/host data.")
loadingRequest.finishLoading(with: NSError(domain: "com.icapps.error", code: -1, userInfo: nil))
return false
}
let dataRequest = loadingRequest.dataRequest
self.requestApplicationCertificate { certificate in
let assetString = url.absoluteString.replacingOccurrences(of: "skd://", with: "")
let assetId = Data(bytes: assetString.cString(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!, count: assetString.lengthOfBytes(using: .utf8))
// var error: Error? = nil
let requestBytes = try! loadingRequest.streamingContentKeyRequestData(forApp: certificate!, contentIdentifier: assetId, options: nil)
self.requestContentKeyAndLeaseExpiryfromKeyServerModule(withRequestBytes: requestBytes) { response, error in
if response != nil {
// Provide license response to the loading request.
if let response = response {
dataRequest!.respond(with: response)
}
// You should always set the contentType before calling finishLoading() to make sure you
// have a contentType that matches the key response. */
loadingRequest.contentInformationRequest?.contentType = AVStreamingKeyDeliveryContentKeyType
loadingRequest.finishLoading() // Treat the processing of the request as complete.
} else {
loadingRequest.finishLoading(with: error)
}
}
}
return true
}
func handlePersistableContentKeyRequest(keyRequest: AVPersistableContentKeyRequest){
}
func requestApplicationCertificate(with completion: @escaping AppCertificateRequestCompletion) {
// This function gets the FairPlay application certificate, expected in DER format, from the
// configured URL. In general, the logic to obtain the certificate is up to the playback app
// implementers. Implementers should use their own certificate, received from Apple upon request.
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)
let urlString = "FairPlay_Certificate"
let url = URL(string: urlString)
var requestTask: URLSessionDataTask? = nil
if let url = url {
requestTask = session.dataTask(with: url, completionHandler: { data, response, error in
completion(data)
})
}
requestTask?.resume()
}
func requestContentKeyAndLeaseExpiryfromKeyServerModule(withRequestBytes requestBytes: Data?, completion: @escaping ContentKeyAndLeaseExpiryRequestCompletion) {
// Implements communications with the Axinom DRM license server.
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)
let AX_DRM_LICENSE_URL = "LICENSE_URL"
var token = ""
let group = DispatchGroup()
group.enter()
let urlToken = URL(string: "PRIVATE_TOKEN_URL")!
let getTokenTask = session.dataTask(with: urlToken, completionHandler: { data, response, error in
if error == nil{
let tokenStr = String(data: data!, encoding: String.Encoding.utf8)
token = tokenStr?.replacingOccurrences(of: "\"", with: "") ?? ""
print(token)
group.leave()
}
})
getTokenTask.resume()
group.wait()
// Send the license request to the license server.
let urlString = AX_DRM_LICENSE_URL
let url = URL(string: urlString)
var ksmRequest: NSMutableURLRequest? = nil
if let url = url {
ksmRequest = NSMutableURLRequest(url: url)
}
ksmRequest?.httpMethod = "POST"
ksmRequest?.httpBody = requestBytes
ksmRequest?.setValue(token, forHTTPHeaderField: "X-AxDRM-Message")
let requestTask: URLSessionDataTask = session.dataTask(with: ksmRequest! as URLRequest, completionHandler: { data, response, error in
completion(data, error)
})
requestTask.resume()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment