[ Music ]
Hello, and thanks for tuning in.
My name is Anil Katti and I'm an AVFoundation Engineer at Apple.
Today, I'm going to present some best practices and recommended patterns for adopting AVContentKeySession API.
AVContentKeySession is an AVFoundation API that enables delivery of FairPlay Streaming keys on Apple platforms.
So, here's what I'll cover in the session.
I'll start with an overview of FairPlay streaming and AVContentKeySession.
I'll then present some ways you can optimize playback using AVContentKeySession.
I'll, also, cover some common pitfalls around FairPlay Streaming key delivery and answer a few frequently asked questions from developers, along the way.
So, let's get started.
FairPlay Streaming was introduced back in 2015 to help protect HLS streams delivered to our platforms.
FairPlay Streaming specification specifies a set of steps an app needs to follow in order to securely deliver content decryption keys so the platform could decrypt and play back encrypted media.
While delivering FairPlay Streaming keys your app works as a liaison between the platform and your key server.
When it receives an on-demand key loading request from AVFoundation it, in turn, requests for an Encrypted Key Request, also known as SPC.
The SPC is then sent to the key server, which responds back with an Encrypted Key Response, also known as CKC.
Finally, the app provided CKC back to AVFoundation so it could start decryption and playback.
Until recently, apps used the generic AVFoundation API called AVAssetResourceLoader to deliver content decryption keys.
But last year we introduced the new AVFoundation Class called AVContentKeySession that was designed specifically around content decryption keys.
We had two goals in mind for AVContentKeySession.
One, to simplify key loading process and provide applications better control over the life cycle of content decryption keys.
And two, serve as a home for new content protection features.
AVContentKeySession adoption has been great, so far.
And already, a majority of FairPlay Streaming keys delivered on our platforms come through AVContentKeySession.
The API has helped developers optimize key delivery in their applications.
I will present some ways you could get more out of the API.
But before that, let's see what makes AVContentKeySession different.
With AVAssetResourceLoader applications could load keys only when AVFoundation requires one and sends an on-demand key loading request.
This, typically, happens when AVFoundation downloads playlists, parses them, and then finds out that the content is encrypted.
Further, AVFoundation could send these key loading requests at any point during playback.
For example, AVFoundation sends new key loading requests if it's switched to a radian that uses a different key in the middle of the playback.
AVContentKeySession, essentially, changes that model.
It decouples key loading from media loading or playback and gives applications more control over the timing of key loading.
AVContentKeySession allows applications to initiate key loading on their own at any point in time.
This opens up new use cases, allows applications to optimize key delivery, and improve different aspects of playback experience.
Playback startup is one such thing AVContentKeySession could help improve.
Instead of waiting for AVFoundation to send on demand key loading requests.
After requesting playback, you could use AVContentKeySession to proactively load keys that you predict might be required in the near future based on user actions.
You could do all this, even before a user picks something to play.
We call this key preloading or prewarming.
Further, if you have assets that use multiple keys across different radians, you could batch up all key requests before even talking to your key server.
This reduces some load on the key server, and also, eliminates round trips for each keys.
You could initiate key loading process by calling processContentKeyRequest method on an AVContentKeySession instance.
Once you call this method AVContentKeySession will send you an AVContentKeyRequest object by invoking the delegate callback.
AVContentKeySession allows you to perform FairPlay Streaming specific operations like request encrypted key requests and respond with encrypted key response.
Okay. So, now let's say you have successfully preloaded a particular key.
Is it possible that the key is requested again after the playback starts?
Yes, that's possible.
The app could receive an on-demand key loading request if the playback route changes, for instance.
Keep in mind that the user could decide to AirPlay the content to an Apple TV or plug in a Lightning to Digital AV adapter.
And in these cases, we need new keys for decryption.
So, the app should always be prepared to answer on-demand key loading requests, even when it preloads keys.
Here's another frequently asked question around this topic.
How could the app preload all keys that might be required during playback?
Well, in order to preload a key, you need the corresponding key identifier.
The one that's specified in EXT-X-KEY tag in the HLS playlist.
We recommend that you obtain all key identifiers and asset [inaudible] from your server in an out-of-band fashion.
Another option is to include all key identifiers in the master playlist as session keys while authoring the content and use preloads eligible content keys property on AVAssetResourceLoader.
At this point I would like to point out that we have a dedicated session about optimizing HLS performance in general, not just key delivery.
You should definitely check that out.
Moving on from preloading, AVContentKeySession could also help you scale your live offering.
Are you wondering how?
Well, you could use AVContentKeySession to disperse key loading requests from clients that are streaming your live content.
Typically, live streams rotate keys periodically in order to add an extra layer of protection for the content.
It is easy to imagine that these keys appear at the exact same time when clients refresh live playlists.
When that happens, millions of clients request keys, all at once, resulting in huge impulse load on the key server.
When you disperse this key request event across a small time window before they appear and before the EXT-X-KEY tag appears in the playlist, you're, basically, load balancing requests reaching your key server.
We covered this use case in detail with sample code during last year's session on HLS.
So, do check out the sessions were recording on developerapple.com or WWDC app.
Apart from allowing you to manage and deliver content decryption keys AVContentKeySession also serves as a home for new FairPlay Streaming content protection features.
We released one such feature last year.
We call it Offline Rentals.
Offline Rentals is a FairPlay Streaming feature that allows you to specify two expiration durations on persistent keys; storage and playback duration.
Storage duration specifies for how long you wish the key to be valid while it is sitting in your storage.
That is, before being used for playback.
It is, typically, large, like 30 days.
Playback duration, on the other hand, specifies how long you with the key to be valid after it was used for playback.
It is, typically, shorter than storage duration.
For example, 24 hours.
This feature allows you to specify such expiration durations when you create persistent keys and the platform ensures that the two expiration durations are enforced, even when the device is offline.
So, you might be wondering how and where can you specify these two expiration durations.
FairPlay introduced a new TLLV called Offline Key TLLV for this purpose.
This has to be signaled in the CKC that is used while requesting persistent key.
In terms of code, you generate a persistent key by calling this method on AVPersistableContentKeyRequest Object.
This returns a persistent key data blob that you should save in your app storage and use it to answer future key loading requests.
Note that this key is valid until the end of storage duration, 30 days from our example.
So, when you use this key to start the playback for the first time you might receive an updated persistent key through a new delegate callback.
When the delegate callback is involved you should discard the original persistent key and save this updated persistent key in your app storage.
You should use this to answer future key loading requests.
Note that this updated persistent key is valid until the end of playback duration, 24 hours from our example.
So, with that, let's shift gears and talk about error handling, now.
Error handling is one of the most important topics from the perspective of improving playback experience.
Successfully loading keys involves a number of steps and something is bound to fail at some point or another.
So, when something fails the first thing you should do is report the failure back to AVFoundation using AVContentKeyRequest or AVAssetResourceLoadingRequest.
Some errors are fatal and some are not.
You should help platform make that decision.
Another thing you should do is monitor error logs and access logs, investigate the root cause.
And try to mitigate errors so your users can get the best experience they deserve on our platforms.
If you haven't already, you should also check out one of our recorded sessions from last year to learn more about error handling, in general.
Over the years we've seen developers fall into a few pitfalls around FairPlay Streaming key delivery.
We have seen apps that hold on to key responses for too long.
When AVFoundation sends you a key loading request you should provide a response as soon as possible.
Delays in key delivery could result in playback timing out.
By the way, you should be able to identify and debug timeouts by surveying your playerItems accessLogs.
Another pitfall is around HDCP enforcement.
It is important to keep in mind that HDCP requirement for your assets is signaled inside encrypted key response from your key server.
If you wish to enforce different HDCP levels for different radians, you should specify different key identifiers for those radians.
And provide appropriate key responses from your key server.
Lastly, you should be careful while responding to key loading requests with persistent keys because persistent keys are tied to the device they were generated on.
For example, you should not use a persistent key to respond to a key loading request from an AirPlay session.
Doing so will result in playback failure.
We made some API changes in iOS 11.2 to help you avoid and catch such issues sooner, rather than later.
Let me walk you through some code snippets to explain.
If you are using AVContentKeySession to deliver keys, now you won't even be able to RequestPersistableContentKey request object if the AVContentKeyRequest cannot accept the persistent key as a response.
So, when requesting a PersistableContentKeyRequest field you should respond with an online FairPlay Streaming key from your key server.
If you are using AVAssetResourceLoader, before responding with a persistent key data blob you should check if persistent key is listed as one of the accepted content types in the newly introduced allowedContentTypes property.
So, I hope this provided some overview of AVContentKeySession and clarified a few questions you might have had.
To summarize, we covered what makes AVContentKeySession different.
We saw how this API could be used to improve playback startup and scale live streaming.
We spoke a little bit about Offline Rentals, what it really is, and how to do it the right way.
We, finally, highlighted best practices around handling errors while delivering FairPlay Streaming keys and common pitfalls that you should be aware of.
Thank you, for listening.
And please, visit developer.apple.com for more information about this session and other related sessions.