步骤1 :
let queue = DispatchQueue(label: "fairplay.resourcerequests", attributes: [])
let url = URL(string: videoUrl)! // Streaming the video from this URL
let videoAsset = AVURLAsset(url: url, options: nil)
videoAsset.resourceLoader.setDelegate(self, queue: queue)
第2步:
extension PlayerViewController : AVAssetResourceLoaderDelegate{
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
let url = loadingRequest.request.url
var error: NSError?
print("Player Delegate Method")
print("URL Schema Is \(url?.scheme! ?? "")")
if((url?.scheme ?? "") == "skd"),
let assetString = url!.host, let assetID = assetString.data(using: String.Encoding.utf8) // Get the URI for the content key.{guard let fetchedCertificate = self.fetchedCertificate else { return false} // Get the application certificate from the server.
let requestedBytes = try loadingRequest.streamingContentKeyRequestData(forApp: fetchedCertificate, contentIdentifier: assetID, options: nil)
do{
print("Online Video Streaming Going On")
let responseData = try contentKeyFromKeyServerModuleWithRequestData(requestedBytes, assetString: assetString, expiryDuration: expiryDuration)
guard let dataRequest = loadingRequest.dataRequest else {
// print("Failed to get instance of AVAssetResourceLoadingDataRequest (loadingRequest.dataRequest).")
return false
}
dataRequest.respond(with: responseData)
if let infoRequest = loadingRequest.contentInformationRequest,
expiryDuration != 0.0
{
infoRequest.renewalDate = Date(timeIntervalSinceNow: expiryDuration)
infoRequest.contentType = "application/octet-stream"
infoRequest.contentLength = Int64(responseData.count)
infoRequest.isByteRangeAccessSupported = false
}
// Treat the processing of the requested resource as complete.
loadingRequest.finishLoading()
// The resource request has been handled regardless of whether the server returned an error.
return true
}catch let e as NSError
{
error = e
// print("content key error\(error)")
}
}catch let e as NSError {
error = e
// Resource loading failed with an error.
// print("streamingContentKeyRequestDataForApp failure: \(error.localizedDescription)")
}}}
第 3 步:
func contentKeyFromKeyServerModuleWithRequestData(_ requestBytes: Data, assetString: String, expiryDuration: TimeInterval?=0.0, persitent:Bool?=true) throws -> Data {
// If the key server provided a CKC, return it.
// if let ckcData = ckcData {
// return ckcData
// }
// else
// {
let base64Decoded = requestBytes.base64EncodedString(options: NSData.Base64EncodingOptions())
//MARK: Get Fairplay license for the current user
NSLog("using ticket: %@", streamTicket )
if let returnData:Data = mediaMakerDRMLicenseCall(base64Decoded, ticket: streamTicket)
{
if returnData.count <= 0
{
// Otherwise, the CKC was not provided by key server. Fail with bogus error.
// Generate an error describing the failure.
throw NSError(domain: "com.example.apple-samplecode", code: 0, userInfo: [
NSLocalizedDescriptionKey: NSLocalizedString("Item cannot be played.", comment: "Item cannot be played."),
NSLocalizedFailureReasonErrorKey: NSLocalizedString("Could not get the content key from the Key Server.", comment: "Failure to successfully send the SPC to the Key Server and get the content key from the returned Content Key Context (CKC) message.")
])
}
else
{
return returnData
}
}
//}
}
第4步:
func mediaMakerDRMLicenseCall(_ playerSPC : String, ticket : String) -> Data{// API Call to fetch license from client server}