Playback sessions enable your app to load music from a cloud queue onto a group of players. Your app can create a session and share it between different instances. For example, someone can be running your app on a phone and a tablet at the same time. A session gives your app semi-exclusive control over the music playing on a group. It is semi-exclusive because no other app can change the music (either by changing the station or modifying the list of songs in the queue) without either joining your session or creating a new one and evicting your session.
Another app can evict your session at any time. User actions can also evict your session. For example, if your app is using a session on a PLAYBAR® and the user turns on the TV, your session will be evicted so that the TV audio can start streaming on the PLAYBAR automatically. Additionally, since sessions are associated with a specific group instead of a specific player, they can move to a different player when the group coordinator changes.
If your app uses playback sessions, it should subscribe to
playbackSession events and handle cases when your session has been evicted by some external user action, and when your session was moved to a different player.
Your app can create a new playback session with the
createSession command. This command will unconditionally create a new session and cause any existing sessions on the group to be terminated and any associated apps to be evicted from the session. Use the
appContext parameters to identify the session.
Identify your app
appId parameter to identify your app. The format of
appId is up to you, but we recommend using a reverse DNS name, for example:
appId parameter is not an API key. See Connect for details about API keys.
Share control of a session
appContext parameter to determine how multiple instances of your app can share control of a session. Just like the
appId, the format of the
appContext parameter is up to you. For example, you could use the user account value. As a best practice, you should hash or encode any user-identifiable data so that it is only useful to your app.
If you want to allow for multiple instances of your app to control a session in parallel, set
appContext to an opaque string that identifies a user account. For example, if you provide a user account identifier as
appContext, then two instances of your app logged into the same user account would be able to control the same session on a group. This way any app instances associated with this account will be able to join the same session.
To allow for only one instance of your app to control a session at a time, implement your app to create a unique
appContext value for all app instances.
Sonos players use the
appContext parameter with the
appId to determine if a client can join a session or not. The sum total length of
appContext must be less than 255 bytes. Otherwise, the player will return an error.
Join existing sessions
If you designed your service to share control of a session amongst different instances of the same app, consider using the
joinOrCreateSession command. This enables your app to join a session if the
appContext parameters match. This command only creates a new session if there is no existing session in progress and no other source is currently playing.
There may be cases where your app simply wants to rejoin an existing session with the
joinSession command. For example, if a user was adding music to the cloud queue on your app, then put your app in the background to check their email on their phone, then switched back to your app. Your app would rejoin the session so that the user could continue adding music. As with the the
joinOrCreateSession command, your app can join a session if the
appContext parameters match.
Use a session to play music from a cloud queue
If you want your app to play music stored in your cloud queue:
- Subscribe to the
playbacknamespace so that you can receive any
playbackErrorevents that may occur.
- Create or join a playback session.
- Once your app has created or joined a playback session, use the
loadCloudQueuecommand to load a list of tracks from your cloud queue into the session.
Each song in the queue is uniquely identified by an immutable
itemId. You can use commands in the playbackSession or playback namespace to control playback options:
- Use the
skipToItemcommand to jump to another item in the queue,
seekto seek to a new position within the currently playing track,
refreshCloudQueueto tell the player to immediately refresh its cached copy of the list of songs (for example, to show the change in the queue if the user added a song to it),
- Control basic playback operations on the group such as
- Display artist name, album art, and other metadata using the
See play audio for more details.
Handle session eviction gracefully
If another user takes over control of the group while your app is connected to a session, your app will receive a
sessionError event with the
errorCode. Your app should handle this event by relinquishing control of the group and not sending any more Control API commands to it. Your app can also inform the user that it has lost control of Sonos. For example, we handle this on our Android cloud queue sample app by moving music playback to the local device so that it continues playing on the local device and stops playing on Sonos.
Your app must never automatically try to recreate a new session without user input. This would result in a bad user experience for the user on the other apps connected to Sonos in their household. For example, the user actions listed below could cause a session eviction:
- Another app creates a new session on the group your app is connected to,
- A user loads and plays something else on the group with a Sonos app,
- A user moves all the players in the group into another group with a Sonos app.
If your app automatically tried to recreate a new session, these user actions would fail, and no music would play! Please be aware that your app may not be the only one controlling the Sonos players in a household and on that note…
Play nice with other apps!
Your app controls playback using a session. But while your app has semi-exclusive control of the queue, other apps, including Sonos-designed apps, still need to be notified of events and errors that occur so that they can accurately reflect the current state of the system. Group coordinators must deliver playback status and errors to other apps that do not have access to the session. This is handled through group-based subscription. When playing tracks from a cloud queue, the metadata that all clients receive originates at the cloud queue server.
Here are some guidelines and best practices for your app and your cloud queue server:
- Your app should subscribe to the
playbackSessionnamespace for your session so that they are notified with an
sessionErrorevent when another app takes control of the queue.
- Your app should subscribe to the
playbacknamespaces to receive
playbackStatusevents, to populate a typical “Now Playing” screen. Note that other apps in the household will also subscribe to these namespaces.
- Your app should subscribe to the
playbacknamespace for the group before calling
loadCloudQueue. This ensures that your app will receive
playbackErrorevents that may occur in response to the first calls to the cloud queue.
- Other apps will subscribe to the
playbacknamespace for the group to receive
playbackErrorevents as well. Even though they may not be responsible for responding to cloud queue errors, these apps may still wish to present error status in their user interfaces, for example, they may want to inform the user if a playback error occurs because a track couldn’t be retrieved or the server couldn’t be contacted.
- In the response to
GET /itemWindow, your cloud queue server should deliver as much track metadata as it has available, since other apps may not have access to your cloud queue to get more information other than what you provide in the playback metadata event.