PlexDevices - Custom Media Player Component

Thank you very much for your work @JesseWebDotCom. This is a huge improvement from the official Plex component. I hope this will become the official component for Plex.

I have tested to play a playlist on 2 players. 1 is Android app and another one is Plex Media Player installed on RPi. Only the Android app is working.

I don’t have a pi plex player so you’ll have to debug and send me the errors you see. Also send me a screenshot

New update coming: I figured out how to do dynamic group membership - so I’ll have this component auto create and populate an “all plex devices” group. If I get fancy I’ll even add an “all active plex devices” and “all inactive plex devices”. This gives your more flexibility in the gui and in automations plus you might even be able to use it with a template sensor to get rid of the plex activity monitor sensor.

I guess I’ll wait to update then. Will this be an optional thing and how would this work with the Universal Media Player?

I’ll make the auto grouping optional. I don’t know anything about the universal thing.

Universal Media Player allows you to group all of your media players together. Then there’s only one instance on the page and whatever media player is running at the time appears in that player and is controlled by it.

EDIT: I’ll test this and let you know what I find out.

Sounds cool but I’m not sure it will meet my need - le me know your thoughts:

When your run ha without any groups, it basically throws every detected device on the home page. This is great for getting started or troubleshooting but not for everyday use. So let’s say I want to see every player connected to my plex sever on a tab/view. I’d have to know their names and add them manually to a group. But anything can connect to plex if you have credentials, so I’d miss out on seeing those devices or would be in a constant miss and then add manually chase just to get a ha page of everyone streaming from my plex server.

This dynamic grouping feature I’m adding takes this headache away - I’ll have an active players group and an inactive players group with memberships automatically updated in realtime (and reset when you restart ha). I should then be able to do things like:

  • show all connected devices in an ha view (like the now playing view within plex)
  • control any of those devices
  • set automations like - alert me when connected count is high, alert me when a new device connects, alert me when an unknown device connects (i.e. One not in my manual plex group), stop any device streaming for more than a day, etc
  • create a plex activity monitor like sensor just by displaying the group count
  • show the inactive group as a “previously connected” group in an ha view
  • create an automation to clear the inactive devices (maybe I’ll add this as a service)
  • endless possibilities (ok, I went too far there)

I don’t have a problem with this - I can always just exclude plexdevices from my universal. I’ll end up with two, but that’s still better than what I started with.

I just started using universal because having all the player enumerated on a view page when most of them weren’t actually doing anything at the time (idle or off) just cluttered up the page. Setting up universal allowed me to have one player instance that only became active when a particular media player client became active and took focus.

It’s sort of the same approach.

Well, oddly enough now I’m not seeing any activity on any of the plex media players. Not plexdevices or the original plex since installing plexdevices.

I guess I’ll have to look at this later on in the day. Bummer. At least the old version was showing something, even if I couldn’t control it. Now nothing.

UPDATE POSTED - Now includes dynamic grouping

2 Likes

OK. This is what I have in the log…

17-02-12 00:00:00 INFO (MainThread) [homeassistant.helpers.script] Script Plex Demo 3 - Playlist: Executing step call service
17-02-12 00:00:00 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: service_data=media_content_type=PLAYLIST, entity_id=['media_player.pmp1'], media_content_id={"playlist_name":"Good Morning","shuffle":1}, service_call_id=1978811152-66, domain=media_player, service=play_media>
17-02-12 00:00:00 INFO (MainThread) [plexapi] GET http://[SERVER_IP]:32400/playlists?X-Plex-Token=[PLEX_TOKEN]
17-02-12 00:00:00 INFO (MainThread) [plexapi] POST http://[SERVER_IP]:32400/playQueues?includeChapters=1&includeRelated=1&playlistID=360771&repeat=0&shuffle=1&type=audio&X-Plex-Token=[PLEX_TOKEN]
17-02-12 00:00:00 INFO (MainThread) [plexapi] GET http://[PLAYER_IP]:32433/player/playback/playMedia?address=[SERVER_IP]&commandID=1&containerKey=/playQueues/10985%3Fwindow%3D100%26own%3D1&key=/playlists/360771&machineIdentifier=[ID]&port=32400&shuffle=1
17-02-12 00:00:00 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 237, in _step
    result = next(coro)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/core.py", line 1018, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/media_player/__init__.py", line 364, in async_service_handler
    yield from getattr(player, method['method'])(**params)
  File "/usr/lib/python3.4/asyncio/coroutines.py", line 141, in coro
    res = func(*args, **kw)
  File "/home/pi/.homeassistant/custom_components/media_player/plexdevices.py", line 836, in async_play_media
    self.playMedia(media,shuffle=src['shuffle'])
  File "/home/pi/.homeassistant/custom_components/media_player/plexdevices.py", line 853, in playMedia
    }, **params))
  File "/home/pi/.homeassistant/deps/plexapi/client.py", line 85, in sendCommand
    return self.query(path, headers=headers)
  File "/home/pi/.homeassistant/deps/plexapi/client.py", line 69, in query
    raise BadRequest('(%s) %s' % (response.status_code, codename))
plexapi.exceptions.BadRequest: (406) not_acceptable

See the last URL it tried to connect to? Your best bet is to figure out a url that works (i.e. paste it in your web browser, research and try different modifications), send back to me, and I’ll see if I can incorporate.

Actually, don’t you already have this working with your old script? If so, compare the two and try to pinpoint the offending difference.

Actually, I only tried it on the android app. I just tested the old script on Plex Media Player in the RPi and it also failed. I guess the issue is specific to PMP.

I have tried both URL in the browser: http://[PLAYER_IP]:[PORT]/player/playback/playMedia?address=[SERVER_IP]&commandID=1&containerKey=/playQueues/10985%3Fwindow%3D100%26own%3D1&key=/playlists/360771&machineIdentifier=[ID]&port=32400&shuffle=1

The one that works shows this message “Failure: 200 OK” and the one that doesn’t only shows a blank screen.

The only differences in the 2 URLs are the [PLAYER_IP] and [PORT]

Sounds like that’s it then.

On a separate note, did that pi plex ever show up in the original media_player.plex component?

Yes. The players appear in both the original Plex component and your custom component.

Well there goes that theory. 2 more things to try

  1. if you are using rasplex, it says to ensure you are on the latest version for api compatibility:

One of the most popular ways to control RasPlex is with the official Plex Inc iOS and Android apps. Please note that the API has recently been changed by Plex Inc, so you need to use the most recent version of the app and RasPlex.

  1. Can you test with authentication off for local connections? You can set that on the plex server: settings | server | network | List of IP addresses and networks that are allowed without auth

For example, mine is set to: 192.168.1.1/255.255.255.0

I am using Plex Media Player. Anyway, I am downloading the latest version now and will try it out and share the result later.

OK. Will try it out later.

Thanks.

I figured out how to substantially simplify this code and component. Turns out the original plex component lists clients and ties them to sessions. The problem is that not everything that streams from plex is a client. So if I just reverse the code (list sessions and tie to clients), I can see all things that stream. Now I’ll just add my enhancements and we’ll have simpler, more efficient code but with the benefits/features I added.

Unfortunately that means a rewrite and more time but its the right thing to do. Be back soon.