问题
I'm implementing Offline Playback with HLS Fairplay following the demo in the FairPlay Streaming Server SDK v4.0.1 that uses AVContentSessionKey. I download three contents, each content is downloaded and persisted correctly, both the .movpkg and its content key on the documents directory, when I turn off the WIFI these three contents downloaded plays correctly without any problems, before playing Im using this code:
let urlAsset = element.urlAsset!
ContentKeyManager.shared.contentKeySession.addContentKeyRecipient(urlAsset)
if !urlAsset.resourceLoader.preloadsEligibleContentKeys {
urlAsset.resourceLoader.preloadsEligibleContentKeys = true
}
self.present(playerViewController, animated: true, completion: {
AssetPlaybackManager.sharedManager.setAssetForPlayback(urlAsset)
})
So far so good. But the problem is when I close the application (Home button to close applications) and then play the downloaded contents, only the last content downloaded plays correctly, the other ones (first and second) send these error on the console.
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed"
UserInfo={NSUnderlyingError=0x1c065d760 {Error Domain=NSOSStatusErrorDomain Code=-16227 "(null)"},
NSLocalizedFailureReason=An unknown error occurred (-16227),
NSURL=file:///private/var/mobile/Containers/Data/Application/A950D8DB-B711-47E3-AAF5-C95CC9682430/Library/com.apple.UserManagedAssets.kkG8Ih/644986_7798B8476A473F68.movpkg/, NSLocalizedDescription=The operation could not be completed}
I double check the .movpkg with the keys in the documents directory and appears correctly
/Documents/.keys/one-key
/Documents/.keys/two-key
/Documents/.keys/three-key
Before the error occurs the ContentKeyDelegate is called and the key is loaded and passed to the request correctly.
if persistableContentKeyExistsOnDisk(withContentKeyIdentifier: assetIDString) {
let urlToPersistableKey = urlForPersistableContentKey(withContentKeyIdentifier: assetIDString)
guard let contentKey = FileManager.default.contents(atPath: urlToPersistableKey.path) else {
/
pendingPersistableContentKeyIdentifiers.remove(assetIDString)
return
}
/
Create an AVContentKeyResponse from the persistent key data to use for requesting a key for
decrypting content.
*/
let keyResponse = AVContentKeyResponse(fairPlayStreamingKeyResponseData: contentKey)
/
keyRequest.processContentKeyResponse(keyResponse)
return
}
If I print the contentKeyRecipients the three contents appears correctly
- (lldb) po
ContentKeyManager.shared.contentKeySession.contentKeyRecipients ▿ 3
elements
- 0 : AVURLAsset: 0x1c0234d40, URL = file:///private/var/mobile/Containers/Data/Application/E791A4DE-4261-46B7-A84D-D10B27035FAE/Library/com.apple.UserManagedAssets.kkG8Ih/539628_20469336224AA388.movpkg
- 1 : AVURLAsset: 0x1c0234fa0, URL = file:///private/var/mobile/Containers/Data/Application/E791A4DE-4261-46B7-A84D-D10B27035FAE/Library/com.apple.UserManagedAssets.kkG8Ih/644986_7798B8476A473F68.movpkg
- 2 : AVURLAsset: 0x1c42391c0, URL = file:///private/var/mobile/Containers/Data/Application/E791A4DE-4261-46B7-A84D-D10B27035FAE/Library/com.apple.UserManagedAssets.kkG8Ih/573744_62377F9549C45B93.movpkg
My tests are in iOS 11.1.2 and iOS 11.2 beta 2
I'm not sure what is happening, but seems to be a problem with the persisted key, I don't how if each content needs to be associated with one AVContentKeySession at time.
If someone faced a similar problem, any help would be appreciated.
Thanks in advance
回答1:
I'm having similar issue.
however, since I need to support iOS 10, I'm not using the new AVContentKeyResponse class. Instead, I'm loading the persistent content key myself, and pass it to the loading request.
Anyway, I'm getting exact the same error as you and same behavior. One thing to note is that if I remove the code that loads persistent content key from disk, and always fetch the key from server, then everything works. But this defeats the purpose of "offline" playback...
So it seems like the system thinks the persistent content key is invalid...
回答2:
Which TLLV you used on the server side to specify Rental Duration of the downloaded content? Did you use Content key duration TLLV or Offline Key TLLV? If you used Offline Key TLLV you need to double check that "Content ID" field is different for every downloaded movie.
回答3:
We had encounter this error message, too. It will happen when content exceed over expiration date which set in server side.
For example :
We give 10 minutes of expiration date for Video A
Download this Video A, and verify CKC delivery correctly (print log)
Play Video A without connection
Take a break (after 11 minutes), close App, and launch App again, select Video A to Play
Show below error message from AVPlayerItem.error.description:
Error Domain=AVFoundationErrorDomain Code=-11800
"The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16227),
NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x1d4257310
{Error Domain=NSOSStatusErrorDomain Code=-16227 "(null)"}}
You can refresh encrypted data again by
- AVAssetResourceLoaderDelegate
- or use AVContentSessionKey
Reference : https://developer.apple.com/videos/play/wwdc2018/507/
来源:https://stackoverflow.com/questions/47579882/offline-hls-fairplay-playback-error-when-the-app-is-closed-code-16227