Ejemplo n.º 1
0
 async def get_inputs(self) -> List[Input]:
     """Return list of available outputs."""
     res = await self.services["avContent"][
         "getCurrentExternalTerminalsStatus"]()
     return [
         Input.make(services=self.services, **x) for x in res
         if 'meta:zone:output' not in x['meta']
     ]
Ejemplo n.º 2
0
    async def get_inputs(self) -> List[Input]:
        """Return list of available outputs."""
        if "avContent" in self.services:
            res = await self.services["avContent"][
                "getCurrentExternalTerminalsStatus"]()
            return [
                Input.make(services=self.services, **x) for x in res
                if "meta:zone:output" not in x["meta"]
            ]
        else:
            if self._upnp_discovery is None:
                raise SongpalException(
                    "avContent service not available and UPnP fallback failed")

            return await self._get_inputs_upnp()
Ejemplo n.º 3
0
    async def _get_inputs_upnp(self):
        await self._get_upnp_services()

        content_directory = self._upnp_device.service(
            next(s for s in self._upnp_discovery.upnp_services
                 if "ContentDirectory" in s))

        browse = content_directory.action("Browse")
        filter = (
            "av:BIVL,av:liveType,av:containerClass,dc:title,dc:date,"
            "res,res@duration,res@resolution,upnp:albumArtURI,"
            "upnp:albumArtURI@dlna:profileID,upnp:artist,upnp:album,upnp:genre"
        )
        result = await browse.async_call(
            ObjectID="0",
            BrowseFlag="BrowseDirectChildren",
            Filter=filter,
            StartingIndex=0,
            RequestedCount=25,
            SortCriteria="",
        )

        root_items = didl_lite.from_xml_string(result["Result"])
        input_item = next(
            (i for i in root_items
             if isinstance(i, didl_lite.Container) and i.title == "Input"),
            None,
        )

        result = await browse.async_call(
            ObjectID=input_item.id,
            BrowseFlag="BrowseDirectChildren",
            Filter=filter,
            StartingIndex=0,
            RequestedCount=25,
            SortCriteria="",
        )

        av_transport = self._upnp_renderer.service(
            next(s for s in self._upnp_renderer.services
                 if "AVTransport" in s))

        media_info = await av_transport.action("GetMediaInfo").async_call(
            InstanceID=0)
        current_uri = media_info.get("CurrentURI")

        inputs = didl_lite.from_xml_string(result["Result"])

        def is_input_active(input, current_uri):
            if not current_uri:
                return False

            # when input is switched on device, uri can have file:// format
            if current_uri.startswith("file://"):
                # UPnP 'Bluetooth AUDIO' can be file://Bluetooth
                # UPnP 'AUDIO' can be file://Audio
                return current_uri.lower() in "file://" + input.title.lower()

            if current_uri.startswith("local://"):
                # current uri can have additional query params, such as zone
                return input.resources[0].uri in current_uri

        return [
            Input.make(
                title=i.title,
                uri=i.resources[0].uri,
                active="active" if is_input_active(i, current_uri) else "",
                avTransport=av_transport,
                uriMetadata=didl_lite.to_xml_string(i).decode("utf-8"),
            ) for i in inputs
        ]