Limiting concurrent media streams
Introduction
AminoTV supports helping clients track concurrent viewing across multiple devices by providing an API for them to interact with.
Clients can use this API to give an approximation to how many streams a user account is watching.
It's not possible for AminoTV to track the actual stream consumption because we do not always have control over the distribution network. For example when using a CDN or third party backend we have no sight of what streams are currently active.
Implementation
The MediaPlaySession entity
Amino models a MediaPlaySession in the domain language as an entity that can be used to track playback sessions for a user.
An example of the API response representing this resource is:
{ "data": [ { "type": "MediaPlaySession", "id": "6b6bf3e1-555b-45cb-b5d3-63a2ff7be9e3 ", "attributes": { "service": "live", "ip4_address": "86.190.137.158", "device_type": "stb", "play_started_timestamp": 1551091684, "last_updated_timestamp": 1551091736 } } ] }
Note that the IP address is not sufficient to identify a session; A person watching on the STB at home may have the same IP address as somebody watching on their mobile phone upstairs on the same home router Wi-Fi network.
Authentication
Calls to the API must be authenticated by passing your access token in the HTTP headers.
We accept this as a bearer token in the Authorization header.
Managing sessions
The client should call the MediaPlaySession based on user activity, as below:
User action | API calls | Any additional logic to perform | Endpoint |
---|---|---|---|
Before the user is able to play media | GET an index of the current sessions | Check that the number of sessions does not equal or exceed the configured system value | Media play sessions#/Media%20Play%20Sessions/indexMediaPlaySession |
When the user starts to play media | POST to create a new session | Store the id of the media playback session locally | Media play sessions#/Media%20Play%20Sessions/postMediaPlaySession |
When the user stops playing media | DELETE the session | Use the id that was returned to you in the POST response to identify the resource | Media play sessions#/Media%20Play%20Sessions/deleteMediaPlaySession |
Periodically | PATCH the session | Media play sessions#/Media%20Play%20Sessions/patchMediaPlaySession |
Device type and limits
The limit is applied per device type, meaning the user is allowed a set number of MediaPlaySessions per device type. If the limit needs to apply across different types of devices, then all clients sharing a limit should use the same value for device_type with this API.
Showing a list of playback sessions
The client can call the GET method on the resource index to obtain a list of sessions that are currently registered.
This may be useful if the user has been denied starting a new playback session and wants to know which devices are currently watching.
Creating a new session
The client could retrieve an index of the current sessions so that it is able to tell the user whether she can start a new stream or not.
If the client has reached their maximum number of sessions then the frontend should not allow the user to play media.
When the user starts playing media the client should POST to the endpoint detailed above to create a new session.
When the client calls the API to create a new session the server will check the number of sessions that already exist.
The server will respond with the details of the session that has been opened. The client should store the id of the entity so that it can make future calls that reference it.
If the account is not allowed to play another stream then the API will respond with a "403 Forbidden" error, with a body as below:
{ "id": 56071904, "code": "df1e80a", "title": "Too many sessions", "details": "You have tried to open a new playback session but you are already at the maximum allowable limit. You need to stop playing content on another device in order to watch on this one." }
Clients should allow streaming on any other response code that "403 Forbidden". This strategy will make the component non-critical and prevent outages in case of e.g. storage failures.
Periodical PATCH calls to the session
The client is expected to periodically PATCH the session to update the "last_updated_timestamp" field to the current unix timestamp.
This is used by the server to determine if a particular session is being actively watched.
Sessions that are not updated will be removed by the server after a set interval. Note that this will not affect playback, the client will still be able to watch the stream even if the MediaPlaybackSession is removed.
Therefore, it is essential that the client calls PATCH in order to prevent the server from incorrectly assuming the session is no longer active.
Deleting a session when the user stops watching
The client is expected to call the DELETE method on the resource when the user stops watching the media.
We expect that clients will not give users the ability to delete a session without stopping playback.
We realize that it is not always possible for the client to call this endpoint; For example the client could switch off the device or there could be a physical failure in the network.
The server will regularly check for sessions that have not been updated and delete them automatically.
Example flow
Description | URL | Number of MediaPlaySessions after call is made |
---|---|---|
User account is not watching anything | 0 | |
User starts watching something on their set top box | POST /users/{user_id}/media_play_sessions | 1 |
Another person in the household starts watching something on a their mobile | POST /users/{user_id}/media_play_sessions | 2 |
Each device periodically tells the server that the session is still active | PATCH /users/{user_id}/media_play_sessions/{media_play_session_id} | 2 |
The second user presses stop on their mobile device | 2 | |
The first user switches off the set top box without giving the client a chance to delete their session | DELETE /users/{user_id}/media_play_sessions/{media_play_session_id} | 1 (zombie session) |
Some time later the periodic clean up job runs on the server and deletes the zombie session | 0 |