When players send GET /itemWindow, they include a reason
parameter to indicate why. For example, the player sends reason=load
when sending GET /itemWindow
because of a loadCloudQueue command.
Reason values
This table and the following sections describe each possible reason value and give situations where the player would send it in a GET /itemWindow
request.
Value | Description |
---|---|
load | Sonos starts playback because of a loadCloudQueue command. |
pause | An explicit user action to pause playback. |
play | An explicit user action to start playback. |
queueCompleted | The player has finished fetching all of the audio for the current window. The player uses this reason to check for more tracks. |
refresh | The player sends this reason to center the current window on the track that is currently playing. |
resume | An explicit user action to resume a suspended session. For example, the user pressed resume in the Sonos app. |
skipNext | An explicit user action to skip to the next item. |
skipPrev | An explicit user action to skip to the previous item. |
skipToItem | An explicit user action to skip to an item in the queue that is neither the next item nor the previous item. |
Multiple reason values
In v2.2 of cloud queue, players can send requests with multiple reason values separated by a
+
symbol. Currently, the only time players do this is withreason=load+queueCompleted
.
load
The load
value indicates that the player is starting playback because of a loadCloudQueue
command. Players only make requests for this reason if you've enabled the limitedSkips
playback policy or if you don't include track metadata in the command. When you send track metadata in the command, the player starts playback immediately and the first GET /itemWindow
request will have a reason of refresh.
Example use case:
- A listener browses your app and selects a song from their favorite playlist.
- Your app sends a
loadCloudQueue
command to the player without track metadata. - The player sends
GET /context
to get the context for this session, and thenGET /itemWindow
with areason=load
to get the tracks.
pause
The pause
value indicates that the player received an explicit user action to pause playback. Players only send requests for this reason when you enable the notifyUserIntent
playback policy.
Example use case:
- A listener is enjoying a programmed radio station on Sonos.
- Before leaving for work, the listener uses the hardware controls on the player to pause playback.
- The player sends a
GET /itemWindow
request withreason=pause
.
play
The play
value indicates that the player received an explicit user action to start playback. Players send requests for this reason when playback was paused, but not suspended. Players only send requests for this reason when your service enables the notifyUserIntent
playback policy. Players don’t send requests for this reason when playback starts because of a loadCloudQueue
or skipToItem
command.
You can use your response to requests for this reason to refresh any URL that may have expired.
Example use case:
- A listener is playing a new album on Sonos from your service when they have to pause playback and answer a phone call.
- After the phone call, the listener uses your app to resume playback, which sends a play command to the player.
- The player sends a
GET /itemWindow
request withreason=play
.
queueCompleted
The queueCompleted
value indicates that the player finished fetching all the audio for the current window. The player is checking the cloud queue for more tracks. If there are no more tracks, the player pauses playback after the current audio finishes playing.
Example use case:
- A listener is enjoying a playlist on Sonos from your service.
- The player finishes fetching all of the audio for the current window.
- The player sends
GET /itemWIndow
withreason=queueCompleted
to check for more tracks.
refresh
The refresh
value indicates that the player is trying to update the current window on the track that is playing. Players send this request in the background once they have enough audio buffered.
Example use case:
- A listener is enjoying a programmed radio listening session without interruptions.
- As playback nears the end of the current window, the player sends a
GET /itemWindow
request withreason=refresh
to update the window around the track that is currently playing.
resume
The resume
value indicates that the player is resuming a suspended session.
Example use case:
- A listener is playing a programmed radio station. At the start of this session, your service set the
pauseTtlSec
playback policy to a time of your choosing. - After a time, the listener pauses the player.
- The amount of time you set in the
pauseTtlSec
playback policy goes by and the player suspends the session. - The listener returns and uses the player hardware inputs to press play. Because your suspended session is still in the queue, the player sends a
GET /itemWindow
request with areason=resume
to continue the session.
skipNext
The skipNext
value indicates that the player received an explicit user action to skip to the next item. Players only make requests for this reason if you enable either the limitedSkips
or notifyUserIntent
playback policy. In these cases, the player waits for your server's response before allowing the skip. Players don't send requests for this reason when they are starting playback.
Example use case:
- A listener is enjoying a programmed radio station.
- A track starts playing that the listener does not want to hear, so they use the player hardware inputs to skip to the next song.
- The player sends a
GET /itemWindow
request withreason=skipNext
to your server.
skipPrev
The skipPrev
value indicates that the player received an explicit user action to skip to the previous item. Players only make requests for this reason if you enable either the limitedSkips
or notifyUserIntent
playback policy. In these cases, the player waits for your server's response before allowing the skip. Players don't send requests for this reason when they are starting playback.
Example use case:
- A listener is listening to a playlist.
- The listener decides they want to hear the previous track again, so they use your app to return to the previous track.
- The player sends a
GET /itemWindow
request withreason=skipPrev
to your server.
skipToItem
The skipToItem
value indicates the user has skipped to the next track or to another track. This value is associated with the skipToItem
command. Players send this reason if you enable the limitedSkips
playback policy or if you don't include track metadata in the command. When you do include track metadata, the player begins fetching the audio and doesn’t immediately make a GET /itemWindow
request. Later, the player sends GET /itemWindow
with a reason of refresh
to build a window around the track metadata that you provided in the command.
Example use case:
- A listener is enjoying a playlist.
- The listener decides to use your app to select a different track in the playlist.
- This sends a
skipToItem
command to the player. - The player sends a
GET /itemWindow
request withreason=skipToItem
to your server. This request uses theitemId
from theskipToItem
command to request a window around this track.
Multiple reason values
load+queueCompleted
The combination of load+queueCompleted
indicates the player has downloaded all the track audio before sending the first GET /itemWindow
request.
Example use case:
- A listener uses your app to create a playback session on Sonos.
- They select a very short track to start the listening session.
- Your app sends a
loadCloudQueue
command with the track metadata for this track. - The player fetches the entire track before it requests an item window.
- The player sends a
GET /itemWindow
request withreason=load+queueCompleted
to your server.
Error handling
If the player sends an itemId that does not exist in the cloud queue, you should send a 404
(“Not Found”) error. The player stops playback, enters PLAYBACK_STATE_IDLE
, clears the queue, and waits until the user loads more content and selects a new item for playback.
The reason can be returned in the X-Rejected-Reason
HTTP header for your cloud queue server, for logging purposes. For example, you could return ANOTHER_STREAM_BEING_PLAYED
or STREAM_RATE_LIMIT_REACHED
.
See Error handling for how to handle errors as well as a list of client and server errors.