def library_payload(*, can_play_artist: bool) -> BrowseMedia: """ Create response payload to describe contents of a specific library. Used by async_browse_media. """ browse_media = BrowseMedia( can_expand=True, can_play=False, children_media_class=MEDIA_CLASS_DIRECTORY, media_class=MEDIA_CLASS_DIRECTORY, media_content_id="library", media_content_type=f"{MEDIA_PLAYER_PREFIX}library", title="Media Library", ) browse_media.children = [] for item in [{"name": n, "type": t} for t, n in LIBRARY_MAP.items()]: browse_media.children.append( item_payload( { "name": item["name"], "type": item["type"], "uri": item["type"] }, can_play_artist=can_play_artist, )) return browse_media
async def async_browse_media_channels(self, expanded): """Return channel media objects.""" if expanded: children = [ BrowseMedia( title=channel.get("name", f"Channel: {channel_id}"), media_class=MEDIA_CLASS_CHANNEL, media_content_id=f"alltv/{channel_id}", media_content_type=MEDIA_TYPE_CHANNEL, can_play=True, can_expand=False, ) for channel_id, channel in self._tv.channels.items() ] else: children = None return BrowseMedia( title="Channels", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="channels", media_content_type=MEDIA_TYPE_CHANNELS, children_media_class=MEDIA_CLASS_CHANNEL, can_play=False, can_expand=True, children=children, )
def favorites_folder_payload(favorites, media_content_id): """Create response payload to describe all items of a type of favorite. Used by async_browse_media. """ children = [] content_type = SONOS_TYPES_MAPPING[media_content_id] for favorite in favorites: if favorite.reference.item_class != media_content_id: continue children.append( BrowseMedia( title=favorite.title, media_class=SONOS_TO_MEDIA_CLASSES[favorite.reference.item_class], media_content_id=favorite.item_id, media_content_type="favorite_item_id", can_play=True, can_expand=False, thumbnail=getattr(favorite, "album_art_uri", None), ) ) return BrowseMedia( title=content_type.title(), media_class=MEDIA_CLASS_DIRECTORY, media_content_id="", media_content_type="favorites", can_play=False, can_expand=True, children=children, )
async def library_payload(player): """Create response payload to describe contents of library.""" library_info = { "title": "Music Library", "media_class": MEDIA_CLASS_DIRECTORY, "media_content_id": "library", "media_content_type": "library", "can_play": False, "can_expand": True, "children": [], } for item in LIBRARY: media_class = CONTENT_TYPE_MEDIA_CLASS[item] result = await player.async_browse( MEDIA_TYPE_TO_SQUEEZEBOX[item], limit=1, ) if result is not None and result.get("items") is not None: library_info["children"].append( BrowseMedia( title=item, media_class=media_class["children"], media_content_id=item, media_content_type=item, can_play=True, can_expand=True, )) response = BrowseMedia(**library_info) return response
async def async_browse_media(self, hass, channel_list, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" if media_content_id not in (None, "root", "channels"): raise BrowseError( f"Media not found: {media_content_type} / {media_content_id}") channellist = await self._async_prepareChannels(hass, channel_list) channels = [ BrowseMedia( title=channel["title"], media_class=MEDIA_CLASS_TV_SHOW, media_content_id=channel["channelName"], media_content_type=DOMAINBROWSER, can_play=True, can_expand=False, thumbnail=channel["thumbnail"], ) for channel in channellist ] library_info = BrowseMedia( title=self._config.name, media_content_id="root", media_content_type="library", media_class=MEDIA_CLASS_DIRECTORY, can_play=False, can_expand=True, children=channels, ) return library_info
def library_payload(*, can_play_artist): """ Create response payload to describe contents of a specific library. Used by async_browse_media. """ library_info = { "title": "Media Library", "media_class": MEDIA_CLASS_DIRECTORY, "media_content_id": "library", "media_content_type": MEDIA_PLAYER_PREFIX + "library", "can_play": False, "can_expand": True, "children": [], } for item in [{"name": n, "type": t} for t, n in LIBRARY_MAP.items()]: library_info["children"].append( item_payload( { "name": item["name"], "type": item["type"], "uri": item["type"] }, can_play_artist=can_play_artist, )) response = BrowseMedia(**library_info) response.children_media_class = MEDIA_CLASS_DIRECTORY return response
async def async_browse_media(self, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" if media_content_id not in (None, "root"): raise BrowseError( f"Media not found: {media_content_type} / {media_content_id}" ) presets = self._state.get_preset_details() radio = [ BrowseMedia( title=preset.name, media_class=MEDIA_CLASS_MUSIC, media_content_id=f"preset:{preset.index}", media_content_type=MEDIA_TYPE_MUSIC, can_play=True, can_expand=False, ) for preset in presets.values() ] root = BrowseMedia( title="Root", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="root", media_content_type="library", can_play=False, can_expand=True, children=radio, ) return root
async def _async_browse_media_root(self): sources = [] for entity_id in _all_entities(self._mapping): state = self.hass.states.get(entity_id) if (self._get_attribute(state, ATTR_SUPPORTED_FEATURES) & SUPPORT_BROWSE_MEDIA): sources.append( BrowseMedia( title=state.name, media_class=MEDIA_CLASS_DIRECTORY, media_content_id=entity_id, media_content_type="library", can_play=False, can_expand=True, children=[], )) root = BrowseMedia( title=self.name, media_class=MEDIA_CLASS_DIRECTORY, media_content_id=self.entity_id, media_content_type="library", can_play=False, can_expand=True, children=sources, ) return root
def favorites_payload(favorites): """ Create response payload to describe contents of a specific library. Used by async_browse_media. """ children = [] group_types = {fav.reference.item_class for fav in favorites} for group_type in sorted(group_types): media_content_type = SONOS_TYPES_MAPPING[group_type] children.append( BrowseMedia( title=media_content_type.title(), media_class=SONOS_TO_MEDIA_CLASSES[group_type], media_content_id=group_type, media_content_type="favorites_folder", can_play=False, can_expand=True, ) ) return BrowseMedia( title="Favorites", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="", media_content_type="favorites", can_play=False, can_expand=True, children=children, )
async def async_browse_media(self, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" if media_content_id not in (None, ""): raise BrowseError( f"Media not found: {media_content_type} / {media_content_id}") return BrowseMedia( title="Channels", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="", media_content_type=MEDIA_TYPE_CHANNELS, can_play=False, can_expand=True, children=[ BrowseMedia( title=channel, media_class=MEDIA_CLASS_CHANNEL, media_content_id=channel, media_content_type=MEDIA_TYPE_CHANNEL, can_play=True, can_expand=False, ) for channel in self._channels.values() ], )
def _browse_media_bouquet(self, media_content_type, media_content_id) -> "BrowseMedia": bouquet = None for b in self._dreambox.bouquets: if b.ref == media_content_id: bouquet = b if not bouquet: return None self._bouquet = bouquet bouquet_info = { "title": bouquet.name, "media_class": MEDIA_CLASS_PLAYLIST, "children_media_class": MEDIA_CLASS_VIDEO, "media_content_id": bouquet.ref, "media_content_type": "bouquet", "can_play": False, "can_expand": True, "children": [], } for service in bouquet.services: service_info = { "title": service.name, "media_class": MEDIA_CLASS_VIDEO, "media_content_id": service.ref, "media_content_type": MEDIA_TYPE_TVSHOW, "can_play": True, "thumbnail": self._dreambox.picon(service), "can_expand": False, } bouquet_info["children"].append(BrowseMedia(**service_info)) response = BrowseMedia(**bouquet_info) return response
def _browse_media_library(self, media_content_type, media_content_id) -> "BrowseMedia": self._bouquet = None library_info = { "title": "Favorites", "media_class": MEDIA_CLASS_DIRECTORY, "children_media_class": MEDIA_CLASS_PLAYLIST, "media_content_id": "library", "media_content_type": "library", "can_play": False, "can_expand": True, "children": [], } for bouquet in self._dreambox.bouquets: bouquet_info = { "title": bouquet.name, "media_class": MEDIA_CLASS_PLAYLIST, "children_media_class": MEDIA_CLASS_CHANNEL, "media_content_id": bouquet.ref, "media_content_type": "bouquet", "can_play": False, "can_expand": True, "children": [], } library_info["children"].append(BrowseMedia(**bouquet_info)) return BrowseMedia(**library_info)
async def library_payload(): """ Create response payload to describe contents of a specific library. Used by async_browse_media. """ library_info = BrowseMedia( media_class=MEDIA_CLASS_DIRECTORY, media_content_id="library", media_content_type="library", title="Media Library", can_play=False, can_expand=True, children=[], ) library = { "library_music": "Music", MEDIA_TYPE_MOVIE: "Movies", MEDIA_TYPE_TVSHOW: "TV shows", MEDIA_TYPE_CHANNEL: "Channels", } library_info.children = await asyncio.gather(*(item_payload( { "label": item["label"], "type": item["type"], "uri": item["type"], }, ) for item in [{ "label": name, "type": type_ } for type_, name in library.items()])) return library_info
async def async_browse_media_applications(self, expanded): """Return application media objects.""" if expanded: children = [ BrowseMedia( title=application["label"], media_class=MEDIA_CLASS_APP, media_content_id=application_id, media_content_type=MEDIA_TYPE_APP, can_play=True, can_expand=False, thumbnail=self.get_browse_image_url(MEDIA_TYPE_APP, application_id, media_image_id=None), ) for application_id, application in self._tv.applications.items() ] else: children = None return BrowseMedia( title="Applications", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="applications", media_content_type=MEDIA_TYPE_APPS, children_media_class=MEDIA_CLASS_APP, can_play=False, can_expand=True, children=children, )
def playlists_payload(): """Create response payload for all available playlists.""" playlists_info = {**PLAYLISTS_BROWSE_PAYLOAD, "children": []} for playlist in entity.plex_server.playlists(): try: playlists_info["children"].append(item_payload(playlist)) except UnknownMediaType: continue response = BrowseMedia(**playlists_info) response.children_media_class = MEDIA_CLASS_PLAYLIST return response
async def build_item_response(media_library, payload): """Create response payload for the provided media query.""" # print(payload) search_id = payload["search_id"] search_type = payload["search_type"] hass = media_library._hass thumbnail = None title = None media = None media_class = MEDIA_CLASS_DIRECTORY can_play = False can_expand = True children = [] base_url = get_url(hass) is_library = 'library_' in search_type properties = ["thumbnail"] if is_library: # 读取配置目录 path = hass.config.path("media/ha_cloud_music") # 获取所有文件 music_list = media_library.api_music.get_local_media_list(search_type) for item in music_list: children.append( item_payload( { "label": item['name'], "type": 'music', "songid": item['url'] }, media_library)) title = search_type.replace('library_', '') media_class = MEDIA_CLASS_MUSIC can_play = True can_expand = False response = BrowseMedia( media_class=media_class, media_content_id=search_id, media_content_type=search_type, title=title, can_play=can_play, can_expand=can_expand, children=children, thumbnail=thumbnail, ) if is_library: response.children_media_class = MEDIA_CLASS_MUSIC else: response.calculate_children_class() return response
def library_payload(player): """Create response payload to describe contents of library.""" library_info = { "title": "Zidoo Library", "media_class": MEDIA_CLASS_DIRECTORY, "media_content_id": "library", "media_content_type": "library", "can_play": False, "can_expand": True, "children": [], } # add favorite shortcuts = entity._config_entry.options.get(CONF_SHORTCUT, ZDEFAULT_SHORTCUTS) for item in ZSHORTCUTS: if item["path"] in shortcuts: library_info["children"].append( BrowseMedia( title=item["name"], media_class=ITEM_TYPE_MEDIA_CLASS[item["type"]], media_content_id=item["path"], media_content_type=item["type"], can_play=False, can_expand=True, )) # add zidoo file devices result = player.get_device_list() if result is not None: for item in result: content_type = item["type"] item_type = None if content_type is not None and content_type in ZCONTENT_ITEM_TYPE: item_type = ZCONTENT_ITEM_TYPE[content_type] if item_type is not None: child_media_class = ITEM_TYPE_MEDIA_CLASS[item_type] item_thumbnail = None library_info["children"].append( BrowseMedia( title=item["name"], media_class=child_media_class, media_content_id=item["path"], media_content_type=item_type, can_play=False, can_expand=True, thumbnail=item_thumbnail, )) response = BrowseMedia(**library_info) return response
async def build_item_response(player, payload): """Create response payload for search described by payload.""" search_id = payload["search_id"] search_type = payload["search_type"] media_class = CONTENT_TYPE_MEDIA_CLASS[search_type] if search_id and search_id != search_type: browse_id = (SQUEEZEBOX_ID_BY_TYPE[search_type], search_id) else: browse_id = None result = await player.async_browse( MEDIA_TYPE_TO_SQUEEZEBOX[search_type], limit=BROWSE_LIMIT, browse_id=browse_id, ) children = None if result is not None and result.get("items"): item_type = CONTENT_TYPE_TO_CHILD_TYPE[search_type] child_media_class = CONTENT_TYPE_MEDIA_CLASS[item_type] children = [] for item in result["items"]: children.append( BrowseMedia( title=item["title"], media_class=child_media_class["item"], media_content_id=str(item["id"]), media_content_type=item_type, can_play=True, can_expand=child_media_class["children"] is not None, thumbnail=item.get("image_url"), )) if children is None: raise BrowseError(f"Media not found: {search_type} / {search_id}") return BrowseMedia( title=result.get("title"), media_class=media_class["item"], children_media_class=media_class["children"], media_content_id=search_id, media_content_type=search_type, can_play=True, children=children, can_expand=True, )
async def async_ais_radio_library(media_content_id, ais_gate) -> BrowseMedia: """Create response payload to describe contents of a radio library.""" if media_content_id == "ais_radio": json_ws_resp = await ais_gate.get_audio_type(media_content_id) ais_radio_types = [] for item in json_ws_resp["data"]: ais_radio_types.append( BrowseMedia( title=item, media_class=MEDIA_CLASS_DIRECTORY, media_content_id="ais_radio/" + item, media_content_type=MEDIA_TYPE_APP, can_play=False, can_expand=True, )) root = BrowseMedia( title="Radio", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="ais_radio", media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, children=ais_radio_types, ) else: # get radio station for type json_ws_resp = await ais_gate.get_audio_name(media_content_id) ais_radio_stations = [] for item in json_ws_resp["data"]: ais_radio_stations.append( BrowseMedia( title=item["NAME"], media_class=MEDIA_CLASS_DIRECTORY, media_content_id=item["STREAM_URL"], media_content_type=MEDIA_TYPE_APP, can_play=True, can_expand=False, thumbnail=item["IMAGE_URL"], )) root = BrowseMedia( title=media_content_id.replace("ais_radio/", ""), media_class=MEDIA_CLASS_DIRECTORY, media_content_id=media_content_id, media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, children=ais_radio_stations, ) return root
async def async_ais_media_library() -> BrowseMedia: """Create response payload to describe contents of a specific library.""" ais_library_info = BrowseMedia( title="AI-Speaker", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="library", media_content_type="library", can_play=False, can_expand=True, children=[], ) ais_library_info.children.append( BrowseMedia( title="AIS Radio", media_class=MEDIA_CLASS_MUSIC, media_content_id="ais_radio", media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, )) ais_library_info.children.append( BrowseMedia( title="AIS Podcast", media_class=MEDIA_CLASS_PODCAST, media_content_id="ais_podcast", media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, )) ais_library_info.children.append( BrowseMedia( title="AIS Audiobooks", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="ais_audio_books", media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, )) ais_library_info.children.append( BrowseMedia( title="TuneIn", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="ais_tunein", media_content_type=MEDIA_TYPE_APP, can_expand=True, can_play=False, )) return ais_library_info
def library_payload(coordinator): """ Create response payload to describe contents of a specific library. Used by async_browse_media. """ library_info = BrowseMedia( media_class=MEDIA_CLASS_DIRECTORY, media_content_id="library", media_content_type="library", title="Media Library", can_play=False, can_expand=True, children=[], ) library = { MEDIA_TYPE_APPS: "Apps", MEDIA_TYPE_CHANNELS: "Channels", } for item in [{"title": name, "type": type_} for type_, name in library.items()]: if ( item["type"] == MEDIA_TYPE_CHANNELS and coordinator.data.info.device_type != "tv" ): continue library_info.children.append( item_payload( {"title": item["title"], "type": item["type"]}, coordinator, ) ) if all( child.media_content_type == MEDIA_TYPE_APPS for child in library_info.children ): library_info.children_media_class = MEDIA_CLASS_APP elif all( child.media_content_type == MEDIA_TYPE_CHANNELS for child in library_info.children ): library_info.children_media_class = MEDIA_CLASS_CHANNEL else: library_info.children_media_class = MEDIA_CLASS_DIRECTORY return library_info
def item_payload(item, get_thumbnail_url=None): """ Create response payload for a single media item. Used by async_browse_media. """ media_type = get_media_type(item) try: media_class = SONOS_TO_MEDIA_CLASSES[media_type] except KeyError as err: _LOGGER.debug("Unknown media type received %s", media_type) raise UnknownMediaType from err content_id = get_content_id(item) thumbnail = None if getattr(item, "album_art_uri", None): thumbnail = get_thumbnail_url(media_class, content_id) return BrowseMedia( title=item.title, thumbnail=thumbnail, media_class=media_class, media_content_id=content_id, media_content_type=SONOS_TO_MEDIA_TYPES[media_type], can_play=can_play(item.item_class), can_expand=can_expand(item), )
def server_payload(): """Create response payload to describe libraries of the Plex server.""" server_info = BrowseMedia( title=plex_server.friendly_name, media_class=MEDIA_CLASS_DIRECTORY, media_content_id=generate_plex_uri(server_id, "server"), media_content_type="server", can_play=False, can_expand=True, children=[], children_media_class=MEDIA_CLASS_DIRECTORY, thumbnail="https://brands.home-assistant.io/_/plex/logo.png", ) if platform != "sonos": server_info.children.append( special_library_payload(server_info, "Recommended") ) for library in plex_server.library.sections(): if library.type == "photo": continue if library.type != "artist" and platform == "sonos": continue server_info.children.append(library_section_payload(library)) server_info.children.append(playlists_payload()) return server_info
def item_payload(item, short_name=False, extra_params=None): """Create response payload for a single media item.""" try: media_class = ITEM_TYPE_MEDIA_CLASS[item.type] except KeyError as err: raise UnknownMediaType("Unknown type received: {item.type}") from err payload = { "title": pretty_title(item, short_name), "media_class": media_class, "media_content_id": generate_plex_uri( server_id, item.ratingKey, params=extra_params ), "media_content_type": item.type, "can_play": True, "can_expand": item.type in EXPANDABLES, } if hasattr(item, "thumbUrl"): plex_server.thumbnail_cache.setdefault(str(item.ratingKey), item.thumbUrl) if is_internal: thumbnail = item.thumbUrl else: thumbnail = get_proxy_image_url( server_id, item.ratingKey, ) payload["thumbnail"] = thumbnail return BrowseMedia(**payload)
def root_payload(hass, is_internal, platform=None): """Return root payload for Plex.""" children = [] for server_id in hass.data[DOMAIN][SERVERS]: children.append( browse_media( hass, is_internal, "server", generate_plex_uri(server_id, ""), platform=platform, ) ) if len(children) == 1: return children[0] return BrowseMedia( title="Plex", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="", media_content_type="plex_root", can_play=False, can_expand=True, children=children, )
async def browse_node(media_library, media_content_type, media_content_id): """Browse a node of a Volumio media hierarchy.""" json_item = json.loads(media_content_id) navigation = await media_library.browse(json_item["uri"]) if "lists" not in navigation: raise BrowseError( f"Media not found: {media_content_type} / {media_content_id}") # we only use the first list since the second one could include all tracks first_list = navigation["lists"][0] children = [ _item_payload(media_library, item, parent_item=json_item) for item in first_list["items"] ] info = navigation.get("info") title = first_list.get("title") if not title: if info: title = f"{info.get('album')} ({info.get('artist')})" else: title = "Media Library" payload = _raw_item_payload(media_library, json_item, title=title, info=info) return BrowseMedia(**payload, children=children)
async def _async_root_payload(self, content_filter): """Generate root node.""" children = [] # Add media browsers for platform in self.hass.data[CAST_DOMAIN].values(): children.extend(await platform.async_get_media_browser_root_object( self.hass, self._chromecast.cast_type)) # Add media sources try: result = await media_source.async_browse_media( self.hass, None, content_filter=content_filter) children.append(result) except BrowseError: if not children: raise # If there's only one media source, resolve it if len(children) == 1: return await self.async_browse_media( children[0].media_content_type, children[0].media_content_id, ) return BrowseMedia( title="Cast", media_class=MEDIA_CLASS_DIRECTORY, media_content_id="", media_content_type="", can_play=False, can_expand=True, children=children, )
def item_payload(item, coordinator): """ Create response payload for a single media item. Used by async_browse_media. """ thumbnail = None if "app_id" in item: media_content_type = MEDIA_TYPE_APP media_content_id = item["app_id"] thumbnail = coordinator.roku.app_icon_url(item["app_id"]) elif "channel_number" in item: media_content_type = MEDIA_TYPE_CHANNEL media_content_id = item["channel_number"] else: media_content_type = item["type"] media_content_id = "" title = item["title"] can_play = media_content_type in PLAYABLE_MEDIA_TYPES and media_content_id can_expand = media_content_type in EXPANDABLE_MEDIA_TYPES return BrowseMedia( title=title, media_class=CONTENT_TYPE_MEDIA_CLASS[media_content_type], media_content_type=media_content_type, media_content_id=media_content_id, can_play=can_play, can_expand=can_expand, thumbnail=thumbnail, )
def item_payload(item): """Create response payload for a single media item.""" try: media_class = ITEM_TYPE_MEDIA_CLASS[item.type] except KeyError as err: _LOGGER.debug("Unknown type received: %s", item.type) raise UnknownMediaType from err payload = { "title": item.title, "media_class": media_class, "media_content_id": str(item.ratingKey), "media_content_type": item.type, "can_play": True, "can_expand": item.type in EXPANDABLES, } if hasattr(item, "thumbUrl"): entity.plex_server.thumbnail_cache.setdefault( str(item.ratingKey), item.thumbUrl ) if is_internal: thumbnail = item.thumbUrl else: thumbnail = entity.get_browse_image_url(item.type, item.ratingKey) payload["thumbnail"] = thumbnail return BrowseMedia(**payload)
async def players_payload(media_content_id, players, host, port): media_content_id_url = f'http://{host}:{port}/api/home' print(media_content_id_url) players_info = BrowseMedia( media_class=MEDIA_CLASS_DIRECTORY, media_content_id=media_content_id_url, media_content_type="library", title="Available Media Players", can_play=False, can_expand=True, children=[], ) #async with aiohttp.ClientSession() as session: # r = await fetch(session, media_content_id) # for x in r: # players_info.children.append(menu_item_payload(title=x["short"], media_content_type="library", media_content_id=x["full"])) for player in players: playerurl = f'http://{host}:{port}/api/defaultplayer/{player}' players_info.children.append( menu_item_payload(title=player, media_content_type="library", media_content_id=playerurl)) return players_info