How FairPlay Streaming Integrates with EME in Safari

This article provides a technical overview of how Apple’s FairPlay Streaming (FPS) integrates with the W3C Encrypted Media Extensions (EME) API to play DRM-protected video in the Safari web browser. It covers the role of the Content Decryption Module, the initialization of encrypted media, the cryptographic exchange between the browser and the license server, and the final decryption process that enables secure video playback.

The Core Components

To understand the integration, it is necessary to define the two main technologies involved:

  • Encrypted Media Extensions (EME): A standard W3C JavaScript API that provides a communication bridge between a web application and a browser's built-in Digital Rights Management (DRM) software.
  • FairPlay Streaming (FPS): Apple’s DRM technology. Within the EME framework in Safari, the native FairPlay client acts as the Content Decryption Module (CDM). The CDM is the secure environment responsible for handling keys and decrypting video content.

The Integration Workflow

FairPlay Streaming relies on the HTTP Live Streaming (HLS) protocol. When a user hits play on a protected video in Safari, EME and FairPlay execute a strict step-by-step handshake to authorize playback.

1. Detecting Encrypted Media

The process begins when the HTML5 <video> element loads an HLS manifest (.m3u8 file). Safari parses the manifest and encounters the #EXT-X-KEY tag, which indicates that the stream is encrypted with FairPlay.

Upon detecting this tag, Safari triggers an encrypted event on the video element. This event contains initialization data (initData), which includes the URI needed to identify the content key.

2. Initializing the FairPlay Key System

The web application listens for the encrypted event and uses the EME API to request access to the FairPlay CDM.

The application calls navigator.requestMediaKeySystemAccess() and passes the FairPlay key system identifier (typically com.apple.fps). Once Safari grants access, the application creates a MediaKeys object and attaches it to the HTML5 <video> element. This links the video player directly to the FairPlay CDM.

3. Supplying the Application Certificate

Before FairPlay can request a decryption key, it must establish a secure communication channel. The web application fetches a public FairPlay Application Certificate from a server and passes it to the CDM using the mediaKeys.setServerCertificate() method. The CDM uses this certificate to encrypt the upcoming license request.

4. Generating the Server Playback Context (SPC)

Next, the web application creates a MediaKeySession and calls the generateRequest() method, passing in the initData captured in step one.

The FairPlay CDM takes this data, combines it with device-specific information, encrypts it using the Application Certificate, and generates a payload known as the Server Playback Context (SPC). Once the SPC is ready, the CDM fires a message event back to the web application.

5. Acquiring the Content Key Context (CKC)

EME does not dictate how the license is transported; the web application must handle the network request.

The application intercepts the message event, extracts the SPC payload, and sends it via an XMLHttpRequest or fetch POST request to a FairPlay license server (also known as a Key Security Module or KSM). The license server decrypts the SPC, verifies that the user is authorized to watch the video, and packages the actual video decryption key into an encrypted response called the Content Key Context (CKC). The server then sends the CKC back to the browser.

6. Decryption and Playback

Upon receiving the CKC from the license server, the web application passes it into the FairPlay CDM by calling the mediaKeySession.update() method.

The CDM securely decrypts the CKC, extracts the content key, and begins decrypting the protected video segments. Because the FairPlay CDM is integrated directly into the Apple operating system (macOS or iOS), the decryption happens at the hardware level. The decrypted video frames are sent directly to the device's display pipeline, ensuring the raw video data is never exposed to the browser or the JavaScript environment.