Search code examples
pythonsonos

How can I play a Sonos playlist using Python soco?


I am trying to load a sonos playlist from Python soco so that I can control music from my PC.

Thanks to the developers of soco. It's been very handy playing individual tracks from my music library, and streaming internet audio. I just haven't figured out how to use the sonos playlist.

Let zone be a SoCo object representing a Sonos speaker or speaker pair. Each zone has a current queue stored in its zone.contentDirectory. I think I need to replace this queue with the tracks from the playlist, but I haven't found how to enumerate the tracks on the playlist. Also, playing the playlist URI does not work.

The list of sonos playlists is available with

import soco

zone = soco.Soco('192.168.1.249')
zone.get_playlists()

A specific playlist is available by its title with

pl = zone.get_sonos_playlist_by_attr('title', 'Dance').

When I look at the details of the playlist, the only track information seems to be a uri on the Sonos device.

>>> pprint(pl.to_dict())
{u'desc': None,
 u'item_id': u'SQ:28',
 u'parent_id': u'SQ:',
 u'resources': [{u'bitrate': None,
                 u'bits_per_sample': None,
                 u'color_depth': None,
                 u'duration': None,
                 u'import_uri': None,
                 u'nr_audio_channels': None,
                 u'protection': None,
                 u'protocol_info': 'file:*:audio/mpegurl:*',
                 u'resolution': None,
                 u'sample_frequency': None,
                 u'size': None,
                 u'uri': 'file:///jffs/settings/savedqueues.rsq#28'}],
 u'restricted': True,
 u'title': u'Dance'}

But this uri cannot be played with zone.play_uri().

>>> zone.play_uri('file:///jffs/settings/savedqueues.rsq#28')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/soco/core.py", line 104, in inner_function
    return function(self, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/soco/core.py", line 483, in play_uri
    ('CurrentURIMetaData', meta)
  File "/usr/local/lib/python2.7/dist-packages/soco/services.py", line 181, in _dispatcher
    return self.send_command(action, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/soco/services.py", line 408, in send_command
    self.handle_upnp_error(response.text)
  File "/usr/local/lib/python2.7/dist-packages/soco/services.py", line 469, in handle_upnp_error
    error_xml=xml_error
soco.exceptions.SoCoUPnPException: UPnP Error 714 received: Illegal MIME-Type from 192.168.1.249

I think I need to replace the queue with the tracks from the playlist uri, but how do I get them?


Solution

  • You've to use a different method. At first you have to clear the queue (if you want to remove old tracks), then you can use add_uri_to_queue to add the playlist tracks to Sonos queue, finally you can use play.

    import soco
    
    sonos = soco.SoCo("192.168.1.249")
    
    uri = "file:///jffs/settings/savedqueues.rsq#28"
    sonos.clear_queue()
    sonos.add_uri_to_queue(uri=uri)
    sonos.play_from_queue(index=0)