Skip to content

Instantly share code, notes, and snippets.

@lawrenceakka
Last active October 3, 2019 20:10
Show Gist options
  • Save lawrenceakka/2d21dca590b4fa7e3af2 to your computer and use it in GitHub Desktop.
Save lawrenceakka/2d21dca590b4fa7e3af2 to your computer and use it in GitHub Desktop.
A quick demo showing how to add a music service track to the queue
# -*- coding: utf-8 -*-
"""Demo to add a music service track or album to a queue."""
from __future__ import unicode_literals
from soco import SoCo
from soco.data_structures import DidlItem, DidlResource
from soco.music_services import MusicService
from soco.compat import quote_url
device = SoCo("192.168.1.136") # <------- Your IP here
service = MusicService("Spotify") # <------ Your Music Service here
album_id = "spotify:album:5qo7iEWkMEaSXEZ7fuPvC3" # <------ an album
track_id = "spotify:track:2qs5ZcLByNTctJKbhAZ9JE" # <------ a track
def add_from_service(item_id, service, device, is_track=True):
# The DIDL item_id is made of the track_id (url escaped), but with an 8
# (hex) digit prefix. It is not clear what this is for, but it doesn't
# seem to matter (too much) what it is. We can use junk (thought the
# first digit must be 0 or 1), and the player seems to do the right
# thing. Real DIDL items sent to a player also have a title and a
# parent_id (usually the id of the relevant album), but they are not
# necessary. The flow charts at http://musicpartners.sonos.com/node/421
# and http://musicpartners.sonos.com/node/422 suggest that it is the job
# of the player, not the controller, to call get_metadata with a track
# id, so this might explain why no metadata is needed at this stage.
# NB: quote_url will break if given unicode on Py2.6, and early 2.7. So
# we need to encode.
item_id = quote_url(item_id.encode('utf-8'))
didl_item_id = "0fffffff{0}".format(item_id)
# For an album:
if not is_track:
uri = 'x-rincon-cpcontainer:' + didl_item_id
else:
# For a track:
uri = service.sonos_uri_from_id(item_id)
res = [DidlResource(uri=uri, protocol_info="DUMMY")]
didl = DidlItem(title="DUMMY",
# This is ignored. Sonos gets the title from the item_id
parent_id="DUMMY", # Ditto
item_id=didl_item_id,
desc=service.desc,
resources=res)
device.add_to_queue(didl)
add_from_service(track_id, service, device, True)
add_from_service(album_id, service, device, False)
@relevitt
Copy link

relevitt commented Jun 4, 2016

Hi Lawrence,

In the line 'didl_item_id = "0fffffff{0}".format(item_id)', do you know how to get the actual 8 (hex) digit prefix?

This is needed if one wishes to add, eg, a spotify playlist to sonos favorites. If one uses "0fffffff{0}".format(item_id)', then the spotify playlist will appear under sonos favorites, but it will be greyed out in the sonos app and cannot be queried or played.

I've been looking at the information available via MusicService('Spotify') and MusicService('Spotify').account and cannot find anything which correlates with the 8 (hex) digit prefix, so for the time being I seem to have reached a dead end.

The prefix appears in the sonos favorite DIDL-Lite once a spotify playlist has been successfully added by using the sonos app and I've confirmed that if one obtains the prefix that way and then uses it (instead of 0fffffff), then the spotify playlist will be added successfully to sonos favorites with full functionality.

However, that's not a viable way of obtaining the prefix if one is attempting to build an application that works independently of the sonos app.

Hope you can help!

Richard

@lawrenceakka
Copy link
Author

@relevitt sorry for the delay, I've only just seen this. Unfortunately, I done know what the prefix means. I assume it encodes the music service or account I'd in some way, but like you I don't know how. Let me know if you find out!

@samaelv95
Copy link

thanks for the example, it served for me. i was trying to add a url from spotify to a playlist in sonos and your code served well !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment