Customizing info view

When implementing getExtendedMetadata, you can customize the Info View screen to fit your service by customizing Sonos SMAPI actions, such as Add Song to Favorites or Remove Song from Favorites, or customizing music service actions for your service, such as Playlists featuring this song or Related Songs. See the sections below for details.

Customize Sonos Actions

Here's a sample Info View screen with a list of Sonos actions for a song:

Info view

You can customize the following actions shown above:

  • Start Radio
  • Save to Your Music (songs or albums)
  • Remove from Your Music (songs or albums)

You can customize these actions by changing the text from the default to something that is appropriate to your service. You can also customize each of the four states of the action:

  • Progress: shown if an action takes more than a few seconds to complete. This is a progress message that should indicate that the operation is still executing.
  • Success: shown if the action completes successfully.
  • Failure: shown if the action fails.
  • Prompt: only used when removing a song or album. For example, a message could prompt the user to confirm they really intend to remove an item from their favorites. If the attribute is configured with an empty string (""), the prompt is skipped and the action is executed immediately.

The customization is facilitated by creating a presentation map that maps a series of strings that are meaningful to our firmware to a series of string constants that are defined in the strings.xml file (see Strings and Localization for details).

The following is a step-by-step example of how to customize all four of the actions:

  1. Setup a Presentation Map XML file and host it on your server. The file can be named anything, but something close to pmap.xml seems to make good sense.
  2. Setup a Strings XML file (if you don't already have one) and host it on your server. The file can be named anything, but something close to strings.xml seems to make good sense.
  3. Customize the StringId values in the strings file to your liking. Remember to add an entry for each language that you support.
  4. Implement getExtendedMetadata() and add the Presentation Map and Strings XML files to your Service Descriptor. When you do this, the Sonos firmware will automatically customize the Info View using the string constants you entered.
     

Add Menu item overrides and Map stringid values

You can add the following menu item overrides to an "InfoView" type presentation map:

  • "AddTrackToFavorites" to enable listeners to add a song as a favorite on your music service.
  • "RemoveTrackFromFavorites" to enable listeners to remove a song from their favorites on your music service.
  • "AddAlbumToFavorites" to enable listeners to add an album as a favorite on your music service.
  • "RemoveAlbumFromFavorites" to enable listeners to remove an album from their favorites on your music service.
  • "RelatedPlay" to enable listeners to start a radio station based on the song or album.

You can map the string ID values for each menu item above using the following string IDs to reflect the state of the action:

  • FailureStringId for the string to show if the action fails.
  • InProgressStringId for the string to show when the action is in progress.
  • StringId for the string to show by default.
  • SuccessStringId for the string to show when the action is successful.
  • PromptStringId for the string to show as a prompt to confirm the action (only for remove actions).

The string ID value for the menu item in the presentation map corresponds to the "stringId" of the same name in the strings.xml file. For example, the ADD_TRACK_TO_YOUR_MUSIC string ID displays "Save to Your Music" when using the sample strings.xml file below.

Sample Presentation Map Entry

<PresentationMap type="InfoView">
 <Match>
  <MenuItemOverrides>
   <MenuItem MenuItem="AddTrackToFavorites" FailureStringId="FAILURE_ADD_TRACK" InProgressStringId="IN_PROGRESS_ADD_TRACK" StringId="ADD_TRACK_TO_YOUR_MUSIC" SuccessStringId="SUCCESS_ADD_TRACK"/>
   <MenuItem MenuItem="RemoveTrackFromFavorites" FailureStringId="FAILURE_REMOVE_TRACK" InProgressStringId="IN_PROGRESS_REMOVE_TRACK" StringId="REMOVE_TRACK_FROM_YOUR_MUSIC" SuccessStringId="SUCCESS_REMOVE_TRACK" PromptStringId=""/>
   <MenuItem MenuItem="AddAlbumToFavorites" FailureStringId="FAILURE_ADD_ALBUM" InProgressStringId="IN_PROGRESS_ADD_ALBUM" StringId="ADD_ALBUM_TO_YOUR_MUSIC" SuccessStringId="SUCCESS_ADD_ALBUM"/>
   <MenuItem MenuItem="RemoveAlbumFromFavorites" FailureStringId="FAILURE_REMOVE_ALBUM" InProgressStringId="IN_PROGRESS_REMOVE_ALBUM" StringId="REMOVE_ALBUM_FROM_YOUR_MUSIC" SuccessStringId="SUCCESS_REMOVE_ALBUM" PromptStringId=""/>
   <MenuItem MenuItem="RelatedPlay" StringId="RELATED_RADIO"/>  </MenuItemOverrides>
 </Match>
</PresentationMap>

Sample Corresponding Strings.xml file entry

<stringtables xmlns="http://sonos.com/sonosapi">
 <stringtable rev="6" xml:lang="en-US">
....
  <string stringId="ADD_TRACK_TO_YOUR_MUSIC">Save to Your Music</string>
  <string stringId="REMOVE_TRACK_FROM_YOUR_MUSIC">Remove from Your Music</string>
  <string stringId="SUCCESS_ADD_TRACK">Saved to Your Music</string>
  <string stringId="SUCCESS_REMOVE_TRACK">Removed from Your Music</string>
  <string stringId="IN_PROGRESS_ADD_TRACK">Saving to Your Music</string>
  <string stringId="IN_PROGRESS_REMOVE_TRACK">Removing from Your Music</string>
  <string stringId="FAILURE_ADD_TRACK">This track could not be saved to Your Music. Please try again.</string>
  <string stringId="FAILURE_REMOVE_TRACK">This track could not be removed from Your Music. Please try again.</string>
  <string stringId="ADD_ALBUM_TO_YOUR_MUSIC">Save to Your Music</string>
  <string stringId="REMOVE_ALBUM_FROM_YOUR_MUSIC">Remove from Your Music</string>
  <string stringId="SUCCESS_ADD_ALBUM">Saved to Your Music</string>
  <string stringId="SUCCESS_REMOVE_ALBUM">Removed from Your Music</string>
  <string stringId="IN_PROGRESS_ADD_ALBUM">Saving to Your Music</string>
  <string stringId="IN_PROGRESS_REMOVE_ALBUM">Removing from Your Music</string>
  <string stringId="FAILURE_ADD_ALBUM">This album could not be saved to Your Music. Please try again.</string>
  <string stringId="FAILURE_REMOVE_ALBUM">This album could not be removed from Your Music. Please try again.</string>
  <string stringId="RELATED_RADIO">Go to Radio</string>
...
 </stringtable>
...
</stringtables>

Customize Music Service Actions

You can also add and customize your own music service actions and use getExtendedMetadata to customize the Info View screen using your strings file and the relatedBrowse and relatedText elements in your presentation map. Here is a sample Info View screen with a list of custom actions for a song:

Info View custom

Some of the custom actions include:

  • Playlists featuring this track
  • Related tracks
  • Comments
  • Description

Unlike customizing Sonos Actions within Info View, these customizations use the strings.xml file and your getExtendedMetadata response to customize the strings shown in the Sonos app, instead of the strings.xml file and your presentation map.

Here's an example of some of the strings in the en-US strings.xml file for the above sample:

<string stringId="ARTIST_DESCRIPTION">Description</string>
<string stringId="ARTIST_WEBSITE">Website</string>
<string stringId="TRACK_COMMENTS">Comments</string>
<string stringId="DESCRIPTION">Description</string>
<string stringId="PURCHASE_URL">Online purchase link</string>
<string stringId="TRACKS_PLAYLISTS">Playlists featuring this track.</string>
<string stringId="TRACKS_RELATED">Related tracks</string>
<string stringId="SAVE_TRACK_FAILURE">Unable to like this track, please try again later.</string>
<string stringId="SAVE_TRACK_DURING">Liking</string>
<string stringId="SAVE_TRACK">Like</string>
<string stringId="SAVE_TRACK_SUCCESS">Liked</string>

Note that the Sonos app does not display all of the stringId values. For example, the Info View does not display the ARTIST_WEBSITE, even though it's listed in the sample strings.xml file shown above, as that element has no data for this track. As a best practice, if the element has no data, it should not be displayed.

The getExtendedMetadataResponse that would result in the above custom actions might look like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <s:Body>
      <ns:getExtendedMetadataResponse>
         <ns:getExtendedMetadataResult>
            <ns:mediaMetadata>
               <ns:id>track:123456</ns:id>
               <ns:itemType>track</ns:itemType>
               <ns:title>This is the title</ns:title>
               <ns:genre>Alternative</ns:genre>
               <ns:mimeType>audio/mp3</ns:mimeType>
               <ns:trackMetadata>
                  <ns:artistId>a:12345678</ns:artistId>
                  <ns:artist>Gattsby</ns:artist>
                  <ns:genre>Alternative</ns:genre>
                  <ns:duration>236</ns:duration>
                  <ns:albumArtURI>https://abc.efg.com/art_legacy.jpg</ns:albumArtURI>
                  <ns:canPlay>true</ns:canPlay>
                  <ns:canSkip>true</ns:canSkip>
                  <ns:canAddToFavorites>true</ns:canAddToFavorites>
               </ns:trackMetadata>
               <ns:dynamic>
                  <ns:property>
                     <ns:name>LIKED</ns:name>
                     <ns:value>0</ns:value>
                  </ns:property>
               </ns:dynamic>
            </ns:mediaMetadata>
            <ns:relatedBrowse>
               <ns:id>t-playlists:123456</ns:id>
               <ns:type>TRACKS_PLAYLISTS</ns:type>
            </ns:relatedBrowse>
            <ns:relatedBrowse>
               <ns:id>t-related:123456</ns:id>
               <ns:type>TRACKS_RELATED</ns:type>
            </ns:relatedBrowse>
            <ns:relatedText>
               <ns:id>track:123456</ns:id>
               <ns:type>TRACK_COMMENTS</ns:type>
            </ns:relatedText>
            <ns:relatedText>
               <ns:id>track:123456</ns:id>
               <ns:type>DESCRIPTION</ns:type>
            </ns:relatedText>
            <ns:relatedText>
               <ns:id>track:123456</ns:id>
               <ns:type>PURCHASE_URL</ns:type>
            </ns:relatedText>
         </ns:getExtendedMetadataResult>
      </ns:getExtendedMetadataResponse>
   </s:Body>
</s:Envelope>

The types listed in both the relatedText and relatedBrowse nodes correspond to a stringId of the same name in the strings.xml file. This string is what is shown in the Info View screen for the Sonos app.

For example, the "TRACKS_PLAYLISTS" type in the getExtendedMetadataResponse above corresponds to the "TRACKS_PLAYLISTS" stringId in the strings.xml file, which in turn shows the string constant of "Playlists featuring this track" in the Info View menu for that track on the Sonos app. See the table below for an illustration of this.

getExtendedMetadataResponse strings.xml Info View for track

<ns:relatedBrowse>
<ns:id>t-playlists:123456</ns:id>
<ns:type>TRACKS_PLAYLISTS</ns:type>
</ns:relatedBrowse>

<string
stringId="TRACKS_PLAYLISTS">
Playlists featuring this track.
</string>

When a user chooses an action that corresponds to a relatedBrowse node, the Sonos app will send a getMetadata call to your service using the given id. Your service should return the associated getMetadata response. For example, when a user chooses Related Songs, the Sonos app would send a getMetadata call with id "t-related:123456" and your service would respond with a mediaCollection of related songs.

When a user chooses an action that corresponds to a relatedText node the Sonos app will send a getExtendedMetadataText call to your service using the given id and type. Your service should return the associated getExtendedMetadataText() response. For example, when a user chooses Description, your service would return a text description of that song.

Sample getExtendedMetadataText request:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getExtendedMetadataText xmlns="http://www.sonos.com/Services/1.1">
      <id>T:123456789</id>
      <type>DESCRIPTION</type>
    </getExtendedMetadataText>
   </soap:Body>
</soap:Envelope>

Sample getExtendedMetadataText response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getExtendedMetadataTextResponse xmlns="http://www.sonos.com/Services/1.1">
      <getExtendedMetadataTextResult>
        This is the description of this song. It has a beat, and some instruments play and a person is singing.
      </getExtendedMetadataTextResult>
    </getExtendedMetadataTextResponse>
  </soap:Body>
</soap:Envelope>

See getExtendedMetadata for more information on implementing relatedBrowse and relatedText.

Add custom radio

You can add custom streams or programmed radio stations to the Info View using relatedPlay elements. For example, if you want to offer your users the ability to open a programmed radio station seeded by a specific artist, album, song, or genre. This operates in a similar manner to the custom music partner actions, in that when you respond to a getExtendedMetadata request, you would a relatedPlay element for the station.

getExtendedMetadataResponse

<ns:relatedPlay>
  <ns:id>
    prad:2
  </ns:id>
  <ns:itemType>
    program
  </ns:itemType>
  <ns:title>
    Radio Blues Program Radio
  </ns:title>
  <ns:canPlay>
    true
  </ns:canPlay>
</ns:relatedPlay>

When the station is playing, the Now Playing screen shows the title of the custom radio station.

Customizing the Start Radio String

The station displays as "Start Radio" in the info view by default. You can replace the "Start Radio" string by using a "RelatedPlay" <MenuItem> with a StringId for the string variable to use for the custom info view text, as described in the Customize Sonos Actions section above. For example, to change "Start Radio" to "Go to Radio", you would add this <MenuItem> to the <MenuItemOverrides> element:

<MenuItem MenuItem="RelatedPlay" StringId="RELATED_RADIO"/>

and add this <string> entry to your strings.xml file:

<string stringId="RELATED_RADIO">Go to Radio</string>

Sample request & response

We currently only support the first relatedPlay element returned, however we may support additional ones in the future. See getExtendedMetadata for details about the sub-elements of the relatedPlay element. See the sample getExtendedMetadata request and response below for an sample implementation.

Sample getExtendedMetadata request:

<s:Envelope
  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
  ...
  </s:Header>
  <s:Body>
    <getExtendedMetadata
      xmlns="http://www.sonos.com/Services/1.1">
      <id>
      track:15
      </id>
    </getExtendedMetadata>
  </s:Body>
</s:Envelope>

Sample getExtendedMetadata response:

<s:Envelope
        xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:ns="http://www.sonos.com/Services/1.1">
  <s:Body>
    <ns:getExtendedMetadataResponse>
      <ns:getExtendedMetadataResult>
        <ns:mediaMetadata>
          <ns:id>
            tr:15
          </ns:id>
          <ns:itemType>
            track
          </ns:itemType>
          <ns:title>
            Generations of Skipping Heartbeats
          </ns:title>
          <ns:isFavorite>
            false
          </ns:isFavorite>
          <ns:mimeType>
            audio/mp3
          </ns:mimeType>
          <ns:trackMetadata>
            <ns:artistId>
              ar:2
            </ns:artistId>
            <ns:artist>
              The Agrarians
            </ns:artist>
            <ns:albumId>
              al:2
            </ns:albumId>
            <ns:album>
              Love Songs from 2011
            </ns:album>
            <ns:duration>
              138
            </ns:duration>
            <ns:albumArtURI>
              https://example.com/assets/images/love_songs2011.jpg
            </ns:albumArtURI>
            <ns:canPlay>
              true
            </ns:canPlay>
            <ns:canAddToFavorites>
              true
            </ns:canAddToFavorites>
          </ns:trackMetadata>
          <ns:dynamic>
            <ns:property>
              <ns:name>
                LIKED
              </ns:name>
              <ns:value>
                0
              </ns:value>
            </ns:property>
          </ns:dynamic>
        </ns:mediaMetadata>
        <ns:relatedPlay>
          <ns:id>
            prad:2
          </ns:id>
          <ns:itemType>
            program
          </ns:itemType>
          <ns:title>
            Radio Blues Program Radio
          </ns:title>
          <ns:canPlay>
            true
          </ns:canPlay>
        </ns:relatedPlay>
      </ns:getExtendedMetadataResult>
    </ns:getExtendedMetadataResponse>
  </s:Body>
</s:Envelope>