我目前正在尝试在我的 iOS 应用程序中播放 Fairplay 流媒体。
当我尝试添加我的流 URL 和证书时,我将 Apple 的 HLSCatalog 作为参考。下面是我的代码
func resourceLoader(_ resourceLoader: AVAssetResourceLoader,
shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
// We first check if a url is set in the manifest.
guard let url = loadingRequest.request.url else {
print("Unable to read the url/host data.")
loadingRequest.finishLoading(with: DRMError.noURLFound)
return false
}
// Get the content id. Content id will be stored in the host of the request url
guard let contentId = url.host, let contentIdData = contentId.data(using: String.Encoding.utf8) else {
print("Unable to read the content id.")
loadingRequest.finishLoading(with: DRMError.noContentIdFound)
return false
}
// Request SPC data from OS
var _spcData: Data?
var _spcError: Error?
do {
_spcData = try loadingRequest.streamingContentKeyRequestData(forApp: certificateData, contentIdentifier: contentIdData, options: [AVAssetResourceLoadingRequestStreamingContentKeyRequestRequiresPersistentKey: true as AnyObject])
} catch {
_spcError = error
print("Failed to get stream content key with error: \(error)")
}
guard let spcData = _spcData, let dataRequest = loadingRequest.dataRequest else {
loadingRequest.finishLoading(with: DRMError.noSPCFound(underlyingError: _spcError))
print("Unable to read the SPC data.")
return false
}
let stringBody: String = "spc=\(spcData.base64EncodedString())&assetId=\(contentId)"
var ckcRequest = URLRequest(url: self.keyServerUrl)
ckcRequest.httpMethod = "POST"
ckcRequest.httpBody = stringBody.data(using: String.Encoding.utf8)
URLSession(configuration: URLSessionConfiguration.default).dataTask(with: ckcRequest) { data, _, error in
guard let data = data else {
print("Error in response data in CKC request: \(error)")
loadingRequest.finishLoading(with: DRMError.unableToFetchKey(underlyingError: _spcError))
return
}
// The CKC is correctly returned and is now send to the `AVPlayer` instance so we
// can continue to play the stream.
var ckcString = String(data: data, encoding: .utf8)!
if ckcString.prefix(5) == "<ckc>" {
let start = ckcString.index(ckcString.startIndex, offsetBy: 5)
let end = ckcString.index(ckcString.index(before: ckcString.endIndex), offsetBy: -5)
let range = start..<end
ckcString = String(ckcString[range])
}
guard let ckcData = Data(base64Encoded: ckcString) else {
print("Can't create base64 encoded data")
loadingRequest.finishLoading(with: DRMError.cannotEncodeCKCData)
return
}
// If we need non-persistent token, then complete loading
// dataRequest.respond(with: data)
// loadingRequest.finishLoading()
// If we need persistent token, then it is time to add persistence option
var persistentKeyData: Data?
do {
persistentKeyData = try loadingRequest.persistentContentKey(fromKeyVendorResponse: ckcData, options: nil)
} catch {
print("Failed to get persistent key with error: \(error)")
loadingRequest.finishLoading(with: DRMError.unableToGeneratePersistentKey)
return
}
// set type of the key
loadingRequest.contentInformationRequest?.contentType = AVStreamingKeyDeliveryPersistentContentKeyType
dataRequest.respond(with: persistentKeyData!)
loadingRequest.finishLoading()
}.resume()
return true
}
当我点击 URL 请求并尝试获取内容密钥时,它给了我以下错误:
“FPS 错误代码 = -42581 | 解析服务器播放上下文以检索资产 ID 和 HU 时出错。”
流可以通过我们的门户在苹果的 safari 浏览器中播放,所以我认为流不是问题,但我的实现缺少一些步骤。
提前致谢。