<img src="https://img.shields.io/badge/%20-ENTERPRISE-B10031" style="float:left"/><br /> <img src="https://img.shields.io/badge/iOS-V4-009727?logo=apple" style="float:left"/><br />

FairPlay Streaming (FPS) securely delivers keys to Apple mobile devices, enabling the playback of encrypted video content. FPS allows a content provider to securely deliver an AES 128-bit content key from the provider’s key server. The content provider encrypts the H.264 video content with the content key. Then, FPS decrypts the encrypted video content with the content key.

The `JWPlayerKit` does not provide the following:

  • Encrypt streams

  • Implement a key server

  • Support offline DRM

The SDK (`JWPlayerKit`) detects when a stream is FairPlay-encrypted and asks your app to provide the necessary information and key to decrypt the content. This approach gives you the flexibility to encrypt your content and manage your keys the way you prefer.

<br /> <hr />

## FPS Compliance

In order to be <a href="https://developer.apple.com/streaming/fps/" target="_blank">FPS-compliant</a>, you must complete the following tasks:

  • Write a Key Security Module that is installed in a key server's software.

  • Add code that enables your app to request the content decryption key from your key server.

  • Create the formatting and encryption software for the media content server. This software prepares the encrypted content stream according to the Apple HTTP Live Streaming (HLS) specification.

<br /> <hr />

## Implementation

FairPlay decryption only works on a physical device and will not work on a simulator.

Use the following steps to set up DRM playback in your app:

  1. Create a [`JWPlayerViewController`](🔗).<br /><br />

  2. Load a configuration with the protected stream file.

  1. Conform to <a href="https://sdk.jwplayer.com/ios/v4/reference/Protocols/JWDRMContentKeyDataSource.html" target="_blank">JWDRMContentKeyDataSource protocol</a> in the class that you would like to handle the data source logic for playing protected content.<br /><br />

  2. Implement the `contentIdentifierForURL(_ url: URL, completionHandler: (_ contentIdentifier: Data?) -> Void)` <a href="https://sdk.jwplayer.com/ios/v4/reference/Protocols/JWDRMContentKeyDataSource.html#/c:@M@JWPlayerKit@objc(pl)JWDRMContentKeyDataSource(im)contentIdentifierForURL:completionHandler:" target="_blank">delegate method</a> in your class. <br /> When called, this delegate method requests the identifier for the protected content to be passed through the delegate method's completion block.

  1. Implement the `appIdentifierForURL(_ url: URL, completionHandler: (Data?) -> Void)` <a href="https://sdk.jwplayer.com/ios/v4/reference/Protocols/JWDRMContentKeyDataSource.html#/c:@M@JWPlayerKit@objc(pl)JWDRMContentKeyDataSource(im)appIdentifierForURL:completionHandler:" target="_blank">delegate method</a> in your class.<br /> When called, this delegate method requests an Application Certificate binary which must be passed through the completion block.

The Application Certificate must be encoded with the X.509 standard with distinguished encoding rules (DER). It is obtained when registering an FPS playback app with Apple, by supplying an X.509 Certificate Signing Request linked to your private key.

  1. Implement the `contentKeyWithSPCData(_ spcData: Data, completionHandler: (Data?, Date?, String?) -> Void)` <a href="https://sdk.jwplayer.com/ios/v4/reference/Protocols/JWDRMContentKeyDataSource.html#/c:@M@JWPlayerKit@objc(pl)JWDRMContentKeyDataSource(im)contentKeyWithSPCData:completionHandler:" target="_blank">delegate method</a> in your class.

<br />

When the key request is ready, this delegate method provides the key request data (SPC - Server Playback Context message) needed to retrieve the Content Key Context (CKC) message from your key server. The CKC message must be returned via the completion block under the response parameter.

After your app sends the request to the server, the FPS code on the server sends the required key to the app. This key is wrapped in an encrypted message. Your app provides the encrypted message to the `JWPlayerKit`. The `JWPlayerKit` unwraps the message and decrypts the stream to enable playback on an iOS device.

<br />

For resources that may expire, specify a renewal date in the completion block and the content type.

<br />