Limiting Concurrent Streams per Viewer

By default, your Ooyala Backlot provider account limits each viewer account to 2 concurrent streams. This feature discourages viewers from sharing their credentials with friends who don’t have accounts. If the viewer, or someone with their account credentials, tries to open an additional stream while the maximum number of streams is open, the player displays a message and refuses to open the stream. This default limit applies across all of the syndication groups (aka publishing rules) within your provider account. You change this limit, and you can enable or disable the limit on a per-group basis. You can also enable or disable this setting for the default group. You can change your Ooyala Backlot provider account limit. You can also set this type of limit at the asset level. For example, your provider account limit could be 3, and your asset-level limit could be 1. In this case, three friends or family members could log in using the same credentials and watch three different assets concurrently, but would be blocked from watching any particular asset concurrently.

Change the limit for your provider account

To change the provider account limit, ask your contact person at Ooyala to set the new limit. Also enable this limit using the Backlot UI or a Backlot API call. This approach is intended to prevent the limit from being changed accidentally.

In the Backlot UI

  1. Log in to Backlot UI.
  2. Click the PUBLISH tab.
  3. Click the Syndication Controls subtab.
  4. On the left, select the appropriate Syndication Group or Default Group.
  5. On the right, verify that the checkbox for Require Ooyala Player Token is checked. (Available only if your Ooyala account includes this functionality. To enable Ooyala Player Token, contact your account manager.)
  6. Under Require Ooyala Player Token, check Limit per-user concurrent streams. You have now enabled the restriction of concurrent streams for your account, but you have not set the limit.
  7. Contact your Ooyala contact person to set the provider level limit.

With the Backlot API

  1. Add the restrict_concurrent_streams property to the publishing rules and set its value to true. For example, add this property to a previously created publishing rule by making a call to https://api.ooyala.com:
    [PATCH]/v2/publishing_rules/9b70a34a67881c7a291d8b{
       “restrict_concurrent_streams” : “true”
    }
  2. Ask your Ooyala contact to set the provider level limit.

Enabling An Asset Limit

You can enable a concurrent stream limit at the asset level and set it yourself with a Backlot API call.

With the Backlot API

  1. Set the asset limit by adding the property max_concurrent_streams to the appropriate publishing rules. Include an integer that represents the asset limit. In the following example, this property is added to a previously created publishing rule by making a call to https://api.ooyala.com:
    [PATCH]/v2/publishing_rules/9b70a34a67881c7a291d8b{
       “restrict_concurrent_streams” : “true”, “max_concurrent_streams” : “1”
    }

Using Publishing Rules and Entitlements to Apply an Asset Limit

You can apply limits to an asset using three different approaches:

  • You can use Rights Locker to create an entitlement that contains an asset limit, and then use Backlot to apply that entitlement to an asset (using Require user entitlement).
  • You can use Backlot create a syndication group (aka publishing rule) that contains an asset limit, and associate an group with an asset (using the Publish or Manage tab).
  • You can do both: Apply an entitlement to an asset and associate that asset with a group. In this case, the entitlement's limit overrides the groups' limit.
Note: To take down an unauthorized stream, delete an asset's entitlement, as described in Stopping Unauthorized Streams
Provider Level Limit Asset Limit Resulting Limits
- - No more than 2 (default) per user account per provider.
3 - No more than 3 per user account per provider.
3 1 1 per asset. No more than 3 per user account per provider.
1 3 1 per asset and 1 per user account per provider.

Asset Limit Use Case

The scenario requiring an asset limit:
  • A publisher named "Movie Provider" wants to sell the movie Ooyala Movie as an Electronic Sell Through (EST) asset. 
  • Ooyala Movie must have an asset limit of 3.
  • User "Fan" purchases Ooyala Movie from Movie Provider.

To restrict Fan from watching Ooyala Movie on more than 3 concurrent streams, Movie Provider could perform one of the following actions:

  • Create a publishing rule in Backlot ("EST" publishing rule, for example) with restrict_concurrent_stream set to true and max_concurrent_stream set to 3.
  • Associate Ooyala Movie with a "default" publishing rule in the Backlot UI by enabling Require user entitlement.
  • Using Ooyala Rights Locker API, create an entitlement for the user, Fan, that allows him to watch Ooyala Movie, and associate the "EST publishing rule" with this entitlement. See Rights Locker API Reference.

How It Works

Concurrent stream limits can be enforced on HTML5 players, Flash players, Google Android, and Apple iOS.

To enforce the concurrent stream limits, the player has to keep sending the heartbeat requests to Ooyala systems. Sending of heartbeat requests is already implemented on the Ooyala Flash player, HTML5 player, Chromecast, iOS and Android SDKs. On these platforms, you don't need to write any code for sending the heartbeat requests. Using any other player will require that you implement the heartbeat. You can configure the heartbeat by contacting your Ooyala contact person.

The Ooyala service keeps a count of the active streams for each of your viewers (customer accounts). When a viewer attempts to access your content, your client application program calls Ooyala’s Authorization API. The system returns:

  • An indication that a heartbeat is required: require_heartbeat
  • An authorization token: auth_token
  • A heartbeat interval in seconds: heartbeat_interval

As long as the client maintains the heartbeat, the count of concurrent streams is maintained. After the viewer leaves the page or exits the mobile application, the client no longer sends the heartbeat, and the service lowers the count.

Please note that the account_id is needed to create a token for concurrent streams.

The table below shows the sequence of actions, from left to right and downward.
Viewer The client application Ooyala
Access content First GET to Authorization API Increment concurrent stream count by one.
Return:
  • require_heartbeat set to true
  • auth_token
  • heartbeat_interval in seconds
  Immediately send auth_token to Ooyala as heartbeat  
Begin and continue playback Send auth_token as heartbeat every heartbeat_interval seconds Respond “OK”

Maintain concurrent stream count

End playback Stop sending heartbeat Decrement the counter by one

When the viewer closes the player in the web page or client application, the service stops receiving a heartbeat. After a period, the service stops the stream, invalidates the auth_token, and decreases the count of concurrent streams by one.

For security reasons, Ooyala does not disclose the precise length of time before the service invalidates the auth_token.

Syntax of Heartbeat HTTP Request and Response

The syntax of the GET request to maintain the heartbeat is as follows:

[GET]/sas/player_api/v1/auth_heartbeat/pcode/pcode/auth_token/auth_token

where pcode is your provider code and auth_token is the value of the auth_token property returned by the Ooyala service.

Note: To enforce content protection, when the client receives the first response that includes the auth_token, it immediately sends a heartbeat. It does not wait for heartbeat_interval seconds before sending the first heartbeat.

After that, the client GETs the heartbeat continually at heartbeat_interval seconds until the viewer exits the player web page or application.

To use the asset limits feature, send embed_code as a query parameter:
[GET]/sas/player_api/v1/auth_heartbeat/pcode/pcode/auth_token/auth_token?
embed_code=embed_code

The response to a successful heartbeat request looks like this:

{
   "auth_token"=>"ABC",
   "message"=>"OK",
   "expires"=>1360877041,
   "signature"=>"2sBWFegOi+hqvz4ektiHM/VzO3cUoQ2c+5/YOgyldtw="
}

Any message other than “OK” indicates failure. In that case, the client application should stop playback.

Full Example with All Properties

The following example shows a first-time GET to the Authorization API. The response in this example highlights the following properties: require_heartbeat, auth_token, and heartbeat_interval. The service uses these properties to enforce the concurrent stream limit. Note that the actual values returned are much longer. The strings than is shown here have been shortened for ease of reading. Then follows the request/response sequence to maintain the heartbeat.

First Request
[GET]http://player.ooyala.com/sas/player_api/v1/authorization/embed_code/FoeGbkH9m/VxMDhwFbICE7ojQ9jZM? domain=gnarly.com&embedToken=http%3A%2F%2Fplayer.ooyala.com%2Fsas%2Fembed_token%FoeGbkH9%3Faccount_id%3DTest_Account%26 api_key%3xxx%26expires%3Dyyy%26signature%3zzz
Response
{  
   "authorization_data"   =>   {  
      "VxMDhwNzoq2j8qfyiG6FbICE7ojQ9jZM"      =>      {  
         "authorized"         =>true,
         "code"         =>"0",
         "message"         =>"authorized",
         "request_timestamp"         =>"1360878715",
         "retry"         =>nil,
         "synd_rule_failures"         =>nil,
         "require_heartbeat"         =>true,
         "streams"         =>         [  
            {  
               "delivery_type"               =>"hds",
               "url"               =>               {  
                  "format"                  =>"encoded",
                  "data"                  => 
 "aHR0cDovLmY0bQ=="
               }
            }
         ]
      }
   },
   "user_info"   =>   {  
      "ip_address"      =>"192.168.1.1",
      "domain"      =>"gnarly.com",
      "request_timestamp"      =>"1360878715",
      "account_id"      =>"johnsmith",
      "country"      =>"UNKNOWN",
      "timezone"      =>-8.0,
      "continent"      =>"NA"
   },
   "debug_data"   =>   {  
      "server_latency"      =>"58.778999999999996",
      "request_id"      =>"4f397d7f6091ce8e7d43354c424095fe",
      "user_info"      =>      {  
         "request_timestamp"         =>"1360878715"
      }
   },
   "auth_token"   => 
 "WGd5uZ29WTFBpeDlnPT0K",
   "heartbeat_data"   =>   {  
      "heartbeat_interval"      =>300
   },
   "signature"   =>"b09xu7UxL/uFRJ9MOkmhISpRSF21zcOK+7iv1LfcNVA="
}
Immediately Send Heartbeat
 [GET]http://player.ooyala.com/sas/player_api/v1/auth_heartbeat/pcode/FoeGbkH9m/auth_token/WGd5uZ29WTFBpeDlnPT0K
Response
{
   "auth_token"=>"ABC",
   "message"=>"OK”,
   "expires"=>1360877041,
   "signature"=>"2sBWFegOi+hqvz4ektiHM/VzO3cUoQ2c+5/YOgyldtw="
}
Heartbeat Interval

By default, this value is 300 seconds. This limit is configurable at the provider level, which will override the default value. The lower limit of the heartbeat interval is capped at 30 seconds. Please contact your account manager to configure this limit.

[GET]http://player.ooyala.com/sas/player_api/v1/auth_heartbeat/pcode/FoeGbkH9m/auth_token/WGd5uZ29WTFBpeDlnPT0K
Response
{
   "auth_token"=>"ABC",
   "message"=>"OK",
   "expires"=>1360877046,
   "signature"=>"2sBWFegOi+hqvz4ektiHM/VzO3cUoQ2c+5/YOgyldtw="
}

Configurable Padding (Heartbeat Latency)

Configurable padding determines the lifetime of a stream. If this attribute is not set, a default latency of 30 seconds will be used. We recommend setting a default latency greater or equal to 10 seconds. Please contact your account manager to configure this limit.

When the Limit is Reached

When the limit is reached the viewer fails authorization. The response body, under the authorized failure message, includes code set to 18 and an explanatory message.

 .
 .
 .
{  
   "authorized"   =>false,
   "code"   =>"18",
   "message"   =>"Too many open videos. Close other videos on this account and try again in a few minutes.",
   "request_timestamp"   =>"1361401545",
   "retry"   =>nil,
   "synd_rule_failures"   =>nil,
   "require_heartbeat"   =>true
}
 .
 .
 .
Ooyala’s HTML5 and Flash players catch this error message and display a pop-up message to the viewer.

Exceptions You Must Catch on Mobile Applications

On mobile client applications (Google Android and Apple iOS), when authorization fails or a heartbeat fails, the following exceptions are thrown.
Google Android Apple iOS When Thrown
ERROR_AUTHORIZATION_

FAILED

OOOoyalaErrorCodeAuthorizationFailed Concurrent stream limit reached
ERROR_AUTHORIZATION_

HEARTBEAT_FAILED

OOOoyalaErrorCodeHeartbeatFail Failure in heartbeat request

When these exceptions are thrown, your client applications must catch them to display an appropriate message. For instance, on Android in Java, enclose your GETs for authorization and for a heartbeat in a try/catch structure. For iOS use whatever mechanism is standard for your company to accomplish “exception handling.”

Other Behavioral Recommendations on Mobile and Desktop

In any application, if the viewer pauses a video, you should still send heartbeat requests.

On both desktops and mobile devices, a viewer can suspend an application into the background:

  • Your mobile application should save a timestamp before backgrounding and then cease sending heartbeats. When the viewer resumes the application, check the saved timestamp. If the elapsed time is less than heartbeat_interval, simply resume playback. Otherwise, you should require reauthorization, get a fresh auth_token and start a new heartbeat.
  • A suspended desktop application cannot continue sending heartbeats. This increases the likelihood that an auth_token will expire before activity resumes.

To stop heartbeats completely:

  • On a desktop browser, the viewer has to exit the page.
  • On a mobile application, the viewer has to exit the application.

About Channel Changing

For viewers who are channel changing, your program can pass previous auth_tokens for authorization so the count is not incremented against the limit. In this case, the viewer can quickly switch videos without raising the concurrent stream count.

Was this article helpful?