現在、iOS アプリで Fairplay ストリーミングを再生しようとしています。
Apple の HLSCatalog を参考にして、ストリーム URL と証明書を追加しようとしました。以下は私のコードです
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 | assetId と HU を取得するためにサーバーの再生コンテキストを解析中にエラーが発生しました。」
ストリームは、ポータルを介して Apple の Safari ブラウザで再生できるため、ストリームは問題ではないと思いますが、私の実装にはいくつかの手順がありません。
前もって感謝します。