Concurrent playback limiting allows one to control how many streams can be watched simultaneously from a specific end-user account. This can be useful to reduce account-sharing or to put in place subscription plans with different concurrent viewing limits.

Limiting Concurrent Playback

Overview

Concurrent playback limiting allows one to control how many streams can be watched simultaneously from a specific end-user account. This can be useful to reduce account-sharing or to put in place subscription plans with different concurrent viewing limits.

The feature can be enabled and configured via the Entitlement Message.

Additions to player-side logic may be needed, depending on the base capabilities of the player and the DRM system used.

Concept

Concurrent playback limiting is based on the following aspects:

  • Issuing short-duration licenses that need to be frequently renewed - this forces players to continuously ping the license service with requests to extend the license duration (aka "license renewal" or "heart-beat" requests)

  • The regular pings give information about the number of active unique client devices and playback sessions. When the pings stop, the license will run out, and the playback session can be assumed to be terminated - allowing a playback slot to be reliably freed.

  • Unique client devices and distinct sessions are differentiated using the relevant DRM-specific identifiers contained in the license requests, which make them tamper-resistant.

  • By knowing the currently active devices and playback sessions, it is possible to enforce limits (concurrency limit) and set a blocking strategy (concurrency mode). For example, the number of distinct client devices or total playback sessions can be restricted, and either viewer could be blocked from starting a new playback or stopped from continuing an old one.

Concurrency limits and modes

Concurrency blocking behavior can be customized by configuring the limit and mode settings in the Entitlement Message (EM). See Appendix A for full examples.

{
  ...
  "license_server": {
    "access_control": {
      "concurrency_mode": 1 // default 0 (disabled)
      "concurrency_limit": 5, // default 3
    }
  },
  "session": {
    "user_id": "user_account_01000"
  }
  ...
}

Concurrency Limit

Specifies the maximum amount of active playback sessions or devices for a specific end-user account. Blocking behavior depends on the selected mode.

Allowed values are: 1 - 10.

Concurrency Mode

Concurrency mode determines the way the concurrent playback limit is enforced. There are four modes.

1. Block oldest session

"concurrency_mode": 1

In this mode, new playbacks can always be started without delay, and the oldest sessions will be stopped from renewing their license when the concurrency limit is exceeded. Temporarily, active playbacks may exceed the limit.

Warning
This mode is not supported for PlayReady, as there is no DRM-level support for session tracking (only devices can be tracked).

2. Block new session

"concurrency_mode": 2

New playbacks are blocked when the number of active sessions reaches the limit. Older sessions can continue playing. To start a new session, users may need to wait until a playback slot is freed.

Warning
This mode is not supported for PlayReady, as there is no DRM-level support for session tracking (only devices can be tracked).

3. Block new device

"concurrency_mode": 3

New playbacks are blocked when the number of actively playing client devices reaches the concurrency limit. This is similar to "block new session," except playbacks are tracked per device, not per session. In this mode, the number of playback sessions on the same device is not limited. For example, playbacks are in multiple tabs of the same browser.

Note
PlayReady uses this mode by default, always. The only alternative, is to disable it ("0").
Caution
When using Widevine DRM in this mode, make sure Desktop browser players set the EME "persistentState" to "required". See EME documentation. Otherwise, the obtained Client ID of the browsers may not be unique and distinct browser clients on distinct machines will appear as a single device.
Warning
In case of browsers, clearing browser application data or entering "private/incognito mode" can cause the Client ID to change, making it appear as a new device requiring a free playback slot to start playing.

4. Disabled

"concurrency_mode": 0

Disables concurrency tracking and limiting for a specific DRM. This is the default mode. This mode can be used per-DRM to selectively omit a DRM from concurrency tracking:

{
  ...
  "license_server": {
    "access_control": {
      "concurrency_mode": 1 // block oldest session
      "concurrency_limit": 3,
      "fairplay": {
        "concurrency_mode": 0 // disabled
      }
    }
  }
  ...
}

User ID

To associate license requests with an end-user account, a unique but otherwise freely chosen User ID has to be provided in the Entitlement Message.

    "session": {
      "user_id": "user_account_01000"
    }

Configuring license renewals

In addition to choosing a concurrency limit and mode, license renewals need to be enabled and configured to ping the license service at desired intervals.

Due to the different capabilities of specific DRM systems, the server-side varies somewhat and needs to be set up per DRM. Additional player logic may also need to be implemented, depending on the player base capabilities.

  • License renewal interval determines the frequency of concurrency checks and license duration extensions. Small intervals allow for greater concurrency control precision at the expense of more requests and costs. Depending on the mode, an too large interval may tie up a playback slot or allow playbacks to be longer than desired. A typical renewal interval could be 5 minutes (300 seconds).

  • Grace period is the time that playback should be allowed to continue while a license is being renewed and a concurrency check is being performed. The grace period should provide enough time to carry out the license renewal and concurrency check procedure in potentially fluctuating network conditions and, potentially, also to retry license renewal in case of bigger network or backend problems. Other pros and cons are the same as for the renewal interval. A typical grace period could be 1 minute (60 seconds).

  • License renewal interval + grace period determine the maximum playback duration in case the license can’t be renewed for any reason - i.e., they determine the license duration. Together, in a typical scenario, the total license duration may be *6 minutes: 300-second renewal interval + 60-second grace period = 360 seconds.

Widevine configuration

  • Widevine has the most built-in support for license renewals, and renewal on the client side is fully automatic, at the expense of needing slightly more configuration on the server side.

  • Renewal interval is set by the "renewal_delay" EM setting - Widevine clients automatically trigger a license renewal request after the specified amount of time passes from the start of the playback session or the last successful renewal.

  • The renewal grace period is set by the "renewal_recovery" EM setting.

  • "allow_renewal" must be set to "true."

There are additional retry-related settings available - see the Entitlement Message.

FairPlay configuration

  • FairPlay has partial built-in license renewal support. Renewals must be triggered manually by player code calling renewal-specific framework functions. And license service can only set the total license duration time. This means the player must know the desired interval and have the logic to trigger it regularly.

  • FairPlay "duration" must be set to the total license duration. In the case of the typical example above, this would be 360 seconds (6 min). Going with the typical grace period, the player should trigger renewal once 300 seconds have passed. When a successful response is received, the license interval should be reset, and playback can continue for another 360 seconds.

  • FairPlay "real_time_expiration" must be set to "true" - if license expiry is not checked in real-time, concurrency control can’t work properly.

PlayReady configuration

  • PlayReady has no built-in support for license renewals or session tracking. This means that on the server side, similarly to FairPlay, only the overall license duration can be set and player code must be aware of the desired interval duration and issue new license requests accordingly. In the PlayReady case, there are no renewal-specific framework functions to call - the player must just trigger new license requests for the same content.

  • PlayReady’s "duration" must be set to the total license duration, e.g., 360 seconds in the typical case.

  • PlayReady "real_time_expiration" must be set to true.

Example 1 - Minimalistic configuration

{
  "version": 1,
  "com_key_id": "69e54088-e9e0-4530-8c1a-1eb6dcd0d14e",
  "message": {
    "type": "entitlement_message",
    "version": 2,
    "license": {
      "widevine": {
        "allow_renewal": true
        "renewal_delay": 300,
        "renewal_recovery": 60,
      },
      "fairplay": {
        "duration": 360,
        "real_time_expiration": true
      },
      "playready": {
        "duration": 360,
        "real_time_expiration": true
      }
    },
    "license_server": {
      "access_control": {
        "concurrency_mode": 1
      }
    },
    "session": {
      "user_id": "user_account_01000"
    },
    "content_keys_source": {
      "inline": [
        {
          "id": "302f80dd-411e-4886-bca5-bb1f8018a024"
        }
      ]
    }
  }
}