Set playback policies
The player enforces playback policies on cloud queues to determine how users can play individual items or a container consisting of a radio station or a group of items. This enables you to offer programmed radio compliant with a set of standards, such as the Digital Millennium Copyright Act (DMCA). For example, you can set policies that:
- Limit the number of times a user can skip to the next item
- Prevent users from skipping an item consisting of an advertisement
- Limit whether users can shuffle or crossfade items in the queue
There are policies for playback contexts, such as a programmed radio station, and policies for individual items, such as items. The player calculates the policy for the currently playing item by using the policy for the playback context and overriding it with the policy for the individual item if it is different. For example, if the canSeek
policy for the context is true and the canSeek
policy for an item is false, the canSeek
policy for the item overrides the policy for the playback context and prevents the user from seeking within the item.
Use playback policies to enforce rules on your content
Your cloud queue sets playback policies on the player. These policies affect player behavior. For example, to allow a user to jump to a new position (seek) in a track, set the canSeek
value to true. To prevent a user from seeking within a track, set the canSeek
value to false. Players only load playback policies after processing a loadCloudQueue command. Players ignore any playback policies sent in subsequent GET /context
responses until the next loadCloudQueue
command.
Players use a default value if you omit a policy from your GET /context
response. See Playback Policy List for a complete list of playback policies and their default values.
Use your GET /context response to send playback policies to the player
A user action sends the loadCloudQueue
command to a player to start a cloud queue. The player then sends a GET /context
request to your service to get the container metadata, reporting options, and playback policies. The player stores the playback policies and sends GET /itemWindow to request a list of tracks. Here's an example workflow:
To reduce latency, you may want to play the track immediately, to do so provide track metadata and set playOnCompletion
to true in the loadCloudQueue
command. Here's an example workflow:
In this case, there's a period of time when the player is playing audio but hasn't loaded any playback policies. This is between processing the loadCloudQueue
command and receiving your GET /context
response. During this period most playback capabilities are disabled. Users can only pause, stop, or change playback until the player processes your GET /context
response.
Players periodically send GET /version
requests to poll your cloud queue. If the context version changes, the player sends GET /context
to update the context.
Provide listeners with a limited ability to skip tracks
When listeners play your content on Sonos they will be able to skip the track currently playing. This could mean skipping to the next track (skipToNextTrack), skipping to the previous track (skipToPreviousTrack), or skipping to a track that is neither the previous or next track (skipToItem). Your service might need to limit the number of times a user can skip to follow a set of standards like the Digital Millenium Copyright Act (DMCA). You can use Sonos playback policies to enforce limits on the number of times a user can skip tracks.
For skipping, the playback policies you want to look at are canSkip
, canSkipBack
, and canSkipToItem
. These policies are true by default. Setting them to false will prevent users from skipping to the next track, the previous track, or another track. But these policies don’t limit skips, they enable or disable the skip capabilities for a container or track.
To limit skips, your service can use the limitedSkips
policy. When this policy is true, your service should send the limitedSkipsState
object in your GET /itemWindow
responses. Players look at the skipLimitReached
parameter in this object to find out if the user has reached the skip limit. Players disable skipping capabilities when skipLimitReached
is true.
When you set limitedSkips
to true, players send GET /itemWindow
requests on user actions, such as skipping. Players use the reason
parameter in GET /itemWindow
requests to report skipping to your service and find out if they should allow this skip. Players wait for your response before playing the next track. Send the skipLimitReached
parameter in the limitedSkipsState
object in your response.
Note that you can use the notifyUserIntent
playback policy to keep track of skips without enforcing skip limits. When you enable this policy, players send GET /itemWindow
requests on user actions and wait for your response before playing the next track. Unlike the skipLimits
policy, this isn't tied to any skip limiting behavior.
If the user has skips available, return skipLimitReached
with a value of false in your response. If the user is out of skips, set skipLimitReached
to true to tell the player not to skip the track. You can set skipLimitReached
back to false when your service restores skips to this user or account. Here is an example of a limitedSkipsState
object:
...
"limitedSkipsState": {
"skipsRemaining": 2,
"skipLimitReached": false
},
...
Sonos reserves the skipsRemaining
parameter in the limitedSkipsState
object for future use. Even though this value is not exposed to the player, you may find it useful for debugging as you develop this feature.
Use playback policies for individual items to prevent users from skipping advertisements
You can use playback policies for individual items to prevent users from skipping advertisements while still allowing them to skip other content.
For example, a user is listening to a programmed radio station that allows for a limited number of skips. The current song finishes and an advertisement starts playing. The user attempts to skip the advertisement but the player doesn’t allow the skip, even though this user has skips available.
You can instruct the player to deny the skip by setting canSkip
and canSkipBack
to false for this individual item, even though the container context allows for skipping. Additionally, your service could set the isVisible
policy to false for an item to prevent it from appearing in the queue.
When you set playback policies for individual items, they override any values that you set in in the context. We recommend doing this for advertisements, as described above.
Here is an example of a policies object for an advertisement:
policies : {
"canSkip": false,
"canSkipToItem": false,
"canCrossfade": false,
"isVisible": false
}
For this item, we also set the canCrossfade
policy to false so that the advertisement won’t crossfade with either the track before or after it.
Understand the errors associated with skip limit enforcement
There are two playback errors that players event when a skip command fails. When players deny a skip because the playback policies don’t allow it, they send the ERROR_DISALLOWED_BY_POLICY
. This is the error the player sends in the previous example with the advertisements.
The other playback error that players event when a skip command fails is ERROR_SKIP_LIMIT_REACHED
. Players send this error when a user tries to skip but the account has already reached the limit of skips allowed by your service.
Skip enforcement workflow
Here is a sample flow for a cloud queue with a service that allows only one skip:
See Playback Policy List for a complete list of playback policies and their default values.
Updated 7 months ago