class TuneInPlayer(A_ProviderPlayerTemplate): def __init__(self): try: self.tunein_service = MusicService('TuneIn') except Exception: self.tunein_service = None def play_station(self, device, name, shuffle=False): if self.tunein_service is None: return False res = self.tunein_service.search('stations', term=name) if 'mediaMetadata' not in res: return "radio not found" if isinstance(res['mediaMetadata'], list): radio_id = res['mediaMetadata'][0]['id'] elif isinstance(res['mediaMetadata'], dict): radio_id = res['mediaMetadata']['id'] else: raise TypeError("Unknown type for tune in search metadata") radio_uri = self.tunein_service.get_media_uri(radio_id) try: device.play_uri(radio_uri.replace('http', 'x-rincon-mp3radio')) except Exception: # unknown problem playing radio uri... return False return True
def __init__(self, spotify_refresh_token=None, speaker_index=None, locale=None): # find the device devices = soco.discover() if devices is None or len(list(devices)) == 0: time.sleep(1) devices = soco.discover() if devices is None or len(list(devices)) == 0: return try: speaker_index = int(speaker_index) except Exception: speaker_index = 0 if speaker_index >= len(list(devices)): speaker_index = 0 self.device = list(devices)[speaker_index] try: self.tunein_service = MusicService('TuneIn') except Exception: self.tunein_service = None try: self.spotify_service = MusicService('Spotify') except Exception: self.spotify_service = None self.max_volume = MAX_VOLUME if spotify_refresh_token is not None: self.spotify = SpotifyClient(spotify_refresh_token) self.previous_volume = None
def __init__(self, soco, username, service_type): super(DeezerSocoPlugin, self).__init__(soco) account = Account() account.username = username account.service_type = service_type self.__ms = MusicService('Deezer', account=account) self.__dz = deezer.Client()
def __init__(self, spotify_refresh_token=None): try: self.spotify_service = MusicService('Spotify') except Exception: self.spotify_service = None if spotify_refresh_token is not None: self.spotify = SpotifyClient(spotify_refresh_token) else: self.spotify = None
def play_spotify_album(player, uri): # need to convert from x-rincon-cpcontainer:1004206cspotify%3aalbum%3a2pbkqNS3aQJfEgm20nUe5P # to spotify:album:2pbkqNS3aQJfEgm20nUe5P print('playing spotify album') spotify = MusicService('Spotify') spotid = urllib.parse.unquote(uri[21::]) start = spotid.find('spotify:') spotid = spotid[start::] # x.stop() x.clear_queue() spotify_add_album.spotify_add_album(x, spotify, spotid) x.play_from_queue(0)
def play_radio_station(player, uri): """Plays the selected radio station. The URI must be in the format as it is currently returned from soco: x-sonosapi-stream:s25111?sid=254&flags=32 """ verbose_output("Switching to radio station {0}".format(uri)) service = MusicService('TuneIn') didl = DidlItem(title="DUMMY", parent_id="DUMMY", item_id="DUMMY", desc=service.desc) meta = to_didl_string(didl) player.avTransport.SetAVTransportURI([('InstanceID', 0), ('CurrentURI', uri), ('CurrentURIMetaData', meta)]) player.play()
class SnipsSonos: """ Sonos skill for Snips. """ def __init__(self, spotify_refresh_token=None, speaker_index=None, locale=None): # find the device devices = soco.discover() if devices is None or len(list(devices)) == 0: time.sleep(1) devices = soco.discover() if devices is None or len(list(devices)) == 0: return try: speaker_index = int(speaker_index) except Exception: speaker_index = 0 if speaker_index >= len(list(devices)): speaker_index = 0 self.device = list(devices)[speaker_index] try: self.tunein_service = MusicService('TuneIn') except Exception: self.tunein_service = None try: self.spotify_service = MusicService('Spotify') except Exception: self.spotify_service = None self.max_volume = MAX_VOLUME if spotify_refresh_token is not None: self.spotify = SpotifyClient(spotify_refresh_token) self.previous_volume = None def pause_sonos(self): if self.device is None: return self.device.pause() def volume_up(self, level): if self.device is None: return level = int(level) if level is not None else 1 current_volume = self.device.volume self.device.volume = min(current_volume + GAIN * level, self.max_volume) self.device.play() def volume_down(self, level): if self.device is None: return level = int(level) if level is not None else 1 self.device.volume -= GAIN * level self.device.play() print self.device.volume def set_volume(self, volume_value): if self.device is None: return self.device.volume = volume_value self.device.play() def set_to_low_volume(self): if self.device.get_current_transport_info( )['current_transport_state'] != "PLAYING": return None if self.device is None: return self.previous_volume = self.device.volume self.device.volume = min(6, self.device.volume) self.device.play() def set_to_previous_volume(self): if self.device is None: return if self.previous_volume is None: return None self.device.volume = self.previous_volume if self.device.get_current_transport_info( )['current_transport_state'] == "PLAYING": self.device.play() def stop_sonos(self): if self.device is None: return self.device.stop() def turn_on_radio(self, radio_name): if self.device is None: return None if self.tunein_service is None: return None res = self.tunein_service.search('stations', term=radio_name) if 'mediaMetadata' not in res: return "radio not found" if isinstance(res['mediaMetadata'], list): radio_id = res['mediaMetadata'][0]['id'] elif isinstance(res['mediaMetadata'], dict): radio_id = res['mediaMetadata']['id'] else: raise TypeError("Unknown type for tune in search metadata") radio_uri = self.tunein_service.get_media_uri(radio_id) try: self.device.play_uri(radio_uri.replace('http', 'x-rincon-mp3radio')) except Exception: # unknown problem playing radio uri... return None def play_playlist(self, name, _shuffle=False): if self.device is None: return if self.spotify is None: return tracks = self.spotify.get_tracks_from_playlist(name) if tracks is None: return None self.device.stop() self.device.clear_queue() if _shuffle: shuffle(tracks) for track in tracks: self.add_from_service(track['track']['uri'], self.spotify_service, True) self.device.play_from_queue(0) def play_artist(self, name): if self.device is None: return if self.spotify is None: return tracks = self.spotify.get_top_tracks_from_artist(name) if tracks is None: return None self.device.stop() self.device.clear_queue() for track in tracks: self.add_from_service(track['uri'], self.spotify_service, True) self.device.play_from_queue(0) def play_album(self, album, _shuffle=False): if self.device is None: return if self.spotify is None: return tracks = self.spotify.get_tracks_from_album(album) if tracks is None: return None self.device.stop() self.device.clear_queue() if _shuffle: shuffle(tracks) for track in tracks: self.add_from_service(track['uri'], self.spotify_service, True) self.device.play_from_queue(0) def play_song(self, name): if self.device is None: return if self.spotify is None: return track = self.spotify.get_track(name) if track is None: return None self.device.stop() self.device.clear_queue() self.add_from_service(track['uri'], self.spotify_service, True) self.device.play_from_queue(0) def play_next_item_in_queue(self): if self.device is None: return try: self.device.next() except Exception: print "Failed to play next item, maybe last song?" def play_previous_item_in_queue(self): if self.device is None: return try: self.device.previous() except Exception: print "Failed to play previous item, maybe first song?" def add_from_service(self, item_id, service, 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. if self.device is None: return 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="Snips")] didl = DidlItem( title="Snips", # This is ignored. Sonos gets the title from the item_id parent_id="Snips", # Ditto item_id=didl_item_id, desc=service.desc, resources=res) self.device.add_to_queue(didl) def get_info(self): # Get info about currently playing tune info = self.device.get_current_track_info() return info['title'], info['artist'], info['album'] def add_song(self): # Save song in spotify title, artist, _ = self.get_info() self.spotify.add_song(artist, title) def play(self): # Save song in spotify self.device.play()
# -*- coding: utf-8 -*- 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.80") # <------- Your IP here service = MusicService("Deezer") # <------ Your Music Service here track_id = service.get_metadata(item_id='radio-37635')['mediaMetadata']['id'] 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)
def __init__(self): try: self.tunein_service = MusicService('TuneIn') except Exception: self.tunein_service = None
# -*- coding: utf-8 -*- 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.80") # <------- Your IP here service = MusicService("Deezer") # <------ Your Music Service here track_id = service.get_metadata(item_id='radio-37635')['mediaMetadata']['id'] 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.
def list_music_services(): print(MusicService.get_subscribed_services_names())
#speaker.play_uri("x-rincon-cpcontainer:spotify%3auser%3aspotifydiscover%3aplaylist%3a2fNlVzK3IlghhG87HZqpCA?sid=9&flags=8224&sn=9") #speaker.add_to_queue("x-sonos-spotify:spotify%3auser%3aspotifydiscover%3aplaylist%3a2fNlVzK3IlghhG87HZqpCA?sid=9&flags=8224&sn=9") if __name__ == "__main__": LOG_LEVEL = logging.FATAL # FATAl, DEBUG, INFO logging.basicConfig(format="%(asctime)s [%(levelname)s]: %(message)s", level=LOG_LEVEL) #logging.getLogger("soco").setLevel(logging.FATAL) logging.info("Start program") # list_players() player = get_device("Mobil") player = SoCo('192.168.1.36') print("Plaver is: '{}'".format(player.ip_address)) albums = player.music_library.get_albums(search_term='White') for album in albums: print('Added:', album.creator, "-", album.title) spotify = MusicService('Spotify') print(spotify.available_search_categories) print(spotify.search("artists", "The Cure")) #s = get_device("Küche") #q = s.get_queue() #s.add_to_queue("spotify:track:7HFaTkpIeG0pXINEm7EEG4") #play_weekly_discover_in_room(player) logging.info("End program")
#!/usr/bin/env python # -*- 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.105") # <------- 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.
from pprint import pprint import json from soco.plugins.spotify import Spotify, SpotifyTrack def json_pprint(thing): print(json.dumps(thing, indent=4)) from soco.music_services import MusicService zone_list = list(soco.discover()) sonos = zone_list[0] print(MusicService.get_subscribed_services_names()) spotify = MusicService('Spotify') print(spotify.available_search_categories) search_term = 'Corinne Bailey Rae' result = spotify.search(category='artists', term=search_term) print result for search_result in result['mediaCollection']: if search_result['title'] == search_term: print search_result json_pprint(spotify.get_metadata(search_result['id'])) b_resultlist = spotify.get_metadata(search_result['id']) for b_result in b_resultlist['mediaCollection']: if b_result['title'] == 'Top Tracks':
#!/usr/bin/env python import soco import json import string from soco.discovery import by_name """Spotify imports:""" from soco.music_services import MusicService from soco.data_structures import DidlItem, DidlResource from soco.compat import quote_url """Sonos configuration""" device = soco.discovery.any_soco() #find device. print('Current device found:' + str(device)) """Spotify configuration""" spotify = MusicService('Spotify') album_id = "spotify:album:5qo7iEWkMEaSXEZ7fuPvC3" # <------ an album track_id = "spotify:track:2qs5ZcLByNTctJKbhAZ9JE" # <------ a track """Get current speaker state""" device_state = device.get_current_transport_info()['current_transport_state'] print("Current Speaker state:" + device_state) """Print current Track""" device_current_track = device.get_current_track_info()['playlist_position'] #print(device_current_track) response = spotify.get_media_metadata( item_id='spotify:track:5NXHXK6hOCotCF8lvGM1I0') print(response) #make device play. #device.stop() #device.stop()