def play_media(self, media_type, media_id, **kwargs): # Play a piece of media. # <ServiceCall media_player.play_media: media_content_type=music, media_content_id=http://192.168.13.91:8123/api/tts_proxy/74a4297365735b6c107b85e034347ce013eeae01_en_-_google.mp3, entity_id=['media_player.mt_office']> self._parent.send('mrad.setzone "{}"'.format(self._zoneId)) self._parent.send('mrad.setsource') media_type = media_type.lower() if media_source.is_media_source_id(media_id): media_type = "music" media_id = (asyncio.run_coroutine_threadsafe( media_source.async_resolve_media(self._hass, media_id, self.entity_id), self._hass.loop, ).result().url) media_id = async_process_play_media_url(self.hass, media_id) if media_type == "music": self._parent.send('duckplay "{}"'.format(media_id)) elif media_type == "scene": self._parent.send('recallscene "{}"'.format(media_id)) elif media_type == "preset": self._parent.send('recallpreset "{}"'.format(media_id)) elif media_type == "radiostation": self._parent.send('playradiostation "{}"'.format(media_id)) else: _LOGGER.error("Unexpected media_type='%s'.", media_type)
def play_media( # noqa: C901 self, media_type: str, media_id: str, **kwargs: Any) -> None: """ Send the play_media command to the media player. If media_id is a Plex payload, attempt Plex->Sonos playback. If media_id is an Apple Music, Deezer, Sonos, or Tidal share link, attempt playback using the respective service. If media_type is "playlist", media_id should be a Sonos Playlist name. Otherwise, media_id should be a URI. """ # Use 'replace' as the default enqueue option enqueue = kwargs.get(ATTR_MEDIA_ENQUEUE, MediaPlayerEnqueue.REPLACE) if spotify.is_spotify_media_type(media_type): media_type = spotify.resolve_spotify_media_type(media_type) media_id = spotify.spotify_uri_from_media_browser_url(media_id) is_radio = False if media_source.is_media_source_id(media_id): is_radio = media_id.startswith("media-source://radio_browser/") media_type = MEDIA_TYPE_MUSIC media_id = (run_coroutine_threadsafe( media_source.async_resolve_media(self.hass, media_id, self.entity_id), self.hass.loop, ).result().url) if media_type == "favorite_item_id": favorite = self.speaker.favorites.lookup_by_item_id(media_id) if favorite is None: raise ValueError(f"Missing favorite for media_id: {media_id}") self._play_favorite(favorite) return soco = self.coordinator.soco if media_id and media_id.startswith(PLEX_URI_SCHEME): plex_plugin = self.speaker.plex_plugin result = process_plex_payload(self.hass, media_type, media_id, supports_playqueues=False) if result.shuffle: self.set_shuffle(True) if enqueue == MediaPlayerEnqueue.ADD: plex_plugin.add_to_queue(result.media) elif enqueue in ( MediaPlayerEnqueue.NEXT, MediaPlayerEnqueue.PLAY, ): pos = (self.media.queue_position or 0) + 1 new_pos = plex_plugin.add_to_queue(result.media, position=pos) if enqueue == MediaPlayerEnqueue.PLAY: soco.play_from_queue(new_pos - 1) elif enqueue == MediaPlayerEnqueue.REPLACE: soco.clear_queue() plex_plugin.add_to_queue(result.media) soco.play_from_queue(0) return share_link = self.coordinator.share_link if share_link.is_share_link(media_id): if enqueue == MediaPlayerEnqueue.ADD: share_link.add_share_link_to_queue(media_id) elif enqueue in ( MediaPlayerEnqueue.NEXT, MediaPlayerEnqueue.PLAY, ): pos = (self.media.queue_position or 0) + 1 new_pos = share_link.add_share_link_to_queue(media_id, position=pos) if enqueue == MediaPlayerEnqueue.PLAY: soco.play_from_queue(new_pos - 1) elif enqueue == MediaPlayerEnqueue.REPLACE: soco.clear_queue() share_link.add_share_link_to_queue(media_id) soco.play_from_queue(0) elif media_type in (MEDIA_TYPE_MUSIC, MEDIA_TYPE_TRACK): # If media ID is a relative URL, we serve it from HA. media_id = async_process_play_media_url(self.hass, media_id) if enqueue == MediaPlayerEnqueue.ADD: soco.add_uri_to_queue(media_id) elif enqueue in ( MediaPlayerEnqueue.NEXT, MediaPlayerEnqueue.PLAY, ): pos = (self.media.queue_position or 0) + 1 new_pos = soco.add_uri_to_queue(media_id, position=pos) if enqueue == MediaPlayerEnqueue.PLAY: soco.play_from_queue(new_pos - 1) elif enqueue == MediaPlayerEnqueue.REPLACE: soco.play_uri(media_id, force_radio=is_radio) elif media_type == MEDIA_TYPE_PLAYLIST: if media_id.startswith("S:"): item = media_browser.get_media( self.media.library, media_id, media_type) # type: ignore[no-untyped-call] soco.play_uri(item.get_uri()) return try: playlists = soco.get_sonos_playlists() playlist = next(p for p in playlists if p.title == media_id) except StopIteration: _LOGGER.error('Could not find a Sonos playlist named "%s"', media_id) else: soco.clear_queue() soco.add_to_queue(playlist) soco.play_from_queue(0) elif media_type in PLAYABLE_MEDIA_TYPES: item = media_browser.get_media( self.media.library, media_id, media_type) # type: ignore[no-untyped-call] if not item: _LOGGER.error('Could not find "%s" in the library', media_id) return soco.play_uri(item.get_uri()) else: _LOGGER.error('Sonos does not support a media type of "%s"', media_type)
def play_media(self, media_type: str, media_id: str, **kwargs: Any) -> None: """ Send the play_media command to the media player. If media_id is a Plex payload, attempt Plex->Sonos playback. If media_id is an Apple Music, Deezer, Sonos, or Tidal share link, attempt playback using the respective service. If media_type is "playlist", media_id should be a Sonos Playlist name. Otherwise, media_id should be a URI. If ATTR_MEDIA_ENQUEUE is True, add `media_id` to the queue. """ if spotify.is_spotify_media_type(media_type): media_type = spotify.resolve_spotify_media_type(media_type) media_id = spotify.spotify_uri_from_media_browser_url(media_id) is_radio = False if media_source.is_media_source_id(media_id): is_radio = media_id.startswith("media-source://radio_browser/") media_type = MEDIA_TYPE_MUSIC media_id = (run_coroutine_threadsafe( media_source.async_resolve_media(self.hass, media_id), self.hass.loop, ).result().url) if media_type == "favorite_item_id": favorite = self.speaker.favorites.lookup_by_item_id(media_id) if favorite is None: raise ValueError(f"Missing favorite for media_id: {media_id}") self._play_favorite(favorite) return soco = self.coordinator.soco if media_id and media_id.startswith(PLEX_URI_SCHEME): plex_plugin = self.speaker.plex_plugin media_id = media_id[len(PLEX_URI_SCHEME):] payload = json.loads(media_id) if isinstance(payload, dict): shuffle = payload.pop("shuffle", False) else: shuffle = False media = lookup_plex_media(self.hass, media_type, json.dumps(payload)) if not kwargs.get(ATTR_MEDIA_ENQUEUE): soco.clear_queue() if shuffle: self.set_shuffle(True) plex_plugin.play_now(media) return share_link = self.coordinator.share_link if share_link.is_share_link(media_id): if kwargs.get(ATTR_MEDIA_ENQUEUE): share_link.add_share_link_to_queue(media_id) else: soco.clear_queue() share_link.add_share_link_to_queue(media_id) soco.play_from_queue(0) elif media_type in (MEDIA_TYPE_MUSIC, MEDIA_TYPE_TRACK): # If media ID is a relative URL, we serve it from HA. media_id = async_process_play_media_url(self.hass, media_id) if kwargs.get(ATTR_MEDIA_ENQUEUE): soco.add_uri_to_queue(media_id) else: soco.play_uri(media_id, force_radio=is_radio) elif media_type == MEDIA_TYPE_PLAYLIST: if media_id.startswith("S:"): item = media_browser.get_media( self.media.library, media_id, media_type) # type: ignore[no-untyped-call] soco.play_uri(item.get_uri()) return try: playlists = soco.get_sonos_playlists() playlist = next(p for p in playlists if p.title == media_id) except StopIteration: _LOGGER.error('Could not find a Sonos playlist named "%s"', media_id) else: soco.clear_queue() soco.add_to_queue(playlist) soco.play_from_queue(0) elif media_type in PLAYABLE_MEDIA_TYPES: item = media_browser.get_media( self.media.library, media_id, media_type) # type: ignore[no-untyped-call] if not item: _LOGGER.error('Could not find "%s" in the library', media_id) return soco.play_uri(item.get_uri()) else: _LOGGER.error('Sonos does not support a media type of "%s"', media_type)