JurajNyiri / PlexMeetsHomeAssistant

Custom card which integrates plex into Home Assistant and makes it possible to launch movies or tv shows on TV with a simple click
Apache License 2.0
107 stars 8 forks source link

Add #66: VLC media player Telnet #67

Closed JurajNyiri closed 2 years ago

JurajNyiri commented 2 years ago

This does not support anything except tracks for now. A way to take artist/album from plex and pass it to media_player.play_media needs to be discovered in order to expand this to albums/artists.

JurajNyiri commented 2 years ago

Storing my research here for future me or anyone else.

I was looking into how https://www.home-assistant.io/integrations/plex/#music works. It uses plexapi to get artist/album/whatever. Then it uses this object to call https://python-plexapi.readthedocs.io/en/latest/modules/playqueue.html?highlight=create_playqueue#plexapi.playqueue.PlayQueue.create which creates a playlist which is then passed to a target cast device.

This can be demonstrated very simply by using this code snippet:

from plexapi.server import PlexServer

baseurl = "http://192.168.100.19:32400"
token = "token"
plex = PlexServer(baseurl, token)

media = plex.library.sectionByID(9).all()[0]

print(plex.createPlayQueue(media, shuffle=0))

This creates a playlist ID which can then be passed to Plex server to trigger playing on defined cast device. Unfortunately this method cannot be used for VLC via Telnet integration because it is not a Plex client and Plex does not generate playlist URL afaik.

JurajNyiri commented 2 years ago

This is code that gets executed on media_player.play_media in https://www.home-assistant.io/integrations/vlc_telnet/ integration

async def async_play_media(
        self, media_type: str, media_id: str, **kwargs: Any
    ) -> None:
        """Play media from a URL or file."""
        if media_type != MEDIA_TYPE_MUSIC:
            LOGGER.error(
                "Invalid media type %s. Only %s is supported",
                media_type,
                MEDIA_TYPE_MUSIC,
            )
            return

        await self._vlc.add(media_id)
        self._state = STATE_PLAYING

Where self._vlc is aiovlc.client.

Which executes following code:

async def add(self, playlist_item: str) -> None:
        """Send the add command."""
        await Add(playlist_item).send(self)
# ... 

class Add(Command[None]):
    """Represent the add command."""

    prefix = "add"
    playlist_item: str

    def build_command(self) -> str:
        """Return the full command string."""
        return f"{self.prefix} {self.playlist_item}\n"
JurajNyiri commented 2 years ago

I have came to the conclusion that there is no way to pass multiple links into https://www.home-assistant.io/integrations/vlc_telnet/ .

What we would need is a service in Home Assistant which allows us to generate playlist accessible via HTTP. We would then pass URL to this playlist into the media_content_id.

Until then, it is possible to only use track with vlcTelnet player.

JurajNyiri commented 2 years ago

Using similar technique to https://github.com/home-assistant/core/blob/dev/homeassistant/components/google_assistant/http.py#L223 and https://github.com/home-assistant/core/blob/dev/homeassistant/components/google_assistant/__init__.py#L103 this integration/service can be created. This integration could also be used for https://github.com/JurajNyiri/PlexMeetsHomeAssistant/issues/39 to solve issue 1 with the 5 minute refresh.