Playback sessions

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.

Create sessions

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 appId and appContext parameters to identify the session.

Identify your app

Use the 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": "com.companyname.appname"

The appId parameter is not an API key. See Subscribe for details about API keys.

Share control of a session

Use the 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 appId and 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 appId and 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 appId and 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:

  1. Subscribe to the playback namespace so that you can receive any playbackError events that may occur.
  2. Create or join a playback session.
  3. Once your app has created or joined a playback session, use the loadCloudQueue command 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 skipToItem command to jump to another item in the queue,
  • seek to seek to a new position within the currently playing track,
  • refreshCloudQueue to 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 play, pause, skipToNext and skipToPrevious,
  • Display artist name, album art, and other metadata using the playbackMetadata command.

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 ERROR_SESSION_EVICTED 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 playbackSession namespace for your session so that they are notified with an ERROR_SESSION_EVICTED sessionError event when another app takes control of the queue.
  • Your app should subscribe to the playbackMetadata and playback namespaces to receive metadataStatus and playbackStatus events, 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 playback namespace for the group before calling loadCloudQueue. This ensures that your app will receive playbackError events that may occur in response to the first calls to the cloud queue.
  • Other apps will subscribe to the playback namespace for the group to receive playbackError events 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.