Core: Plex broken for media_player.play_media

Created on 28 Dec 2018  路  31Comments  路  Source: home-assistant/core

Home Assistant release with the issue:

0.85.0.dev0 (Fresh pull)

Last working Home Assistant release (if known):
Not known

Operating environment (Hass.io/Docker/Windows/etc.):

(home-assistant) max@ubuntu:~/forks/home-assistant$ uname -a
Linux ubuntu 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
(home-assistant) max@ubuntu:~/forks/home-assistant$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS"

Dev environment set from the dev guide.

Component/platform:

https://www.home-assistant.io/components/media_player.plex/

Description of problem:
Cannot call service media_player.play_media on a plex client
The plexapi library seems to have changed? some attributes are prefixed with an underscore, which the current plex.py doesn't address. This seems related to #16250.
Repro:
1) Configure plex in Home assistant
2) Go to the service tool
3) call media_player.play_media with this service data:

{
  "entity_id": "media_player.chrome",
  "media_content_id": "{\"library_name\": \"Movies\", \"video_name\": \"Baby Shark\", \"shuffle\": \"0\"}",
  "media_content_type": "VIDEO"
}

I'll submit a PR that fixes that.

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):
Auto-discovered

# Discover some devices automatically
discovery:

plex.conf

{
    "192.168.1.150:32400": {
        "ssl": false,
        "token": "xxx",
        "verify": false
    }
}

Traceback (if applicable):

2018-12-28 10:24:46 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/home/max/forks/home-assistant/homeassistant/helpers/service.py", line 288, in _handle_service_platform_call
    await func(entity, data)
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/max/forks/home-assistant/homeassistant/components/media_player/plex.py", line 763, in play_media
    media = self.device.server.library.section(
AttributeError: 'PlexClient' object has no attribute 'server'

Once Fixed:

2018-12-28 10:37:06 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/home/max/forks/home-assistant/homeassistant/helpers/service.py", line 288, in _handle_service_platform_call
    await func(entity, data)
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/max/forks/home-assistant/homeassistant/components/media_player/plex.py", line 773, in play_media
    self._client_play_media(media=media, shuffle=src['shuffle'])
  File "/home/max/forks/home-assistant/homeassistant/components/media_player/plex.py", line 835, in _client_play_media
    server_url = self.device._server.baseurl.split(':')
AttributeError: 'PlexServer' object has no attribute 'baseurl'

Additional information:

in progress plex

Most helpful comment

Still totally broken HA v. 0.97.2

All 31 comments

"_" indicate they are internal. So shouldn't really be used by hass. Look like one should get the server object differently.

I'm with you on _ indicating private variables. Looking at the library plex.py uses, it looks like the "server" attribute should be exposed:
https://python-plexapi.readthedocs.io/en/latest/modules/client.html#plexapi.client.PlexClient

Looking at the implementation, it seems like the author's methodology prepends a "_" for static values. Normal attributes trigger a refresh of the status to ensure fresh data is returned:
https://github.com/pkkid/python-plexapi/blob/master/plexapi/base.py#L281

I have not done extensive research on this issue, its history and when exactly it broke and in what manner. I'm assuming it worked when implemented and "server" became "_server" and broke existing implementations.

Ok. Just seamed it was possible to do without the usage of the _ variable. But didn't test.

Any update on this issue? The issue is still present in 0.86.1

Yes, just checked with a fresh pull and the issue is present. My patch also fixes the problem in 0.86.1

Ran into this myself today on 0.89, hope this gets fixed soon.

Kind of a bummer this didn't get merged. Plex media player is not functional at all now. I can resubmit the PR if signing the CLA was an issue

@Villhellm I can understand why this is annoying. @MaxRenaud you are of course welcome to open a new PR.

I'm not in a position to sign the CLA until at least mid-May. I'm more than happy for someone else to submit this fix under their name. The PR is at #19624

@MaxRenaud thanks for the update. Just confirming it's for legal reasons right? Because signing the CLA takes maybe 30 seconds and can be done from even your phone. You just need to be able to login to GitHub, fill the form and hit submit.

Legal reasons. I personally am fine with the CLA but need approval from my employer and I'm out of the country for a month. I'll seek approval as I have a few other patches in mind but I don't want this to hold up progress on this issue. Especially since the fix is so trivial.

I can work on it today. I just have to verify that it works before I resubmit. Shouldn't take more than a couple hours

Any progress on this?

I tried the suggested fix and it didn't work for me. It seems as though there is a lot of work on the upstream package that needs to be done to make this usable with HA again.

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 馃憤
This issue now has been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.

Still totally broken HA v. 0.97.2

Still totally broken HA v. 0.98.4

Still totally broken in HA v. 0.99.2

I opened a new issue here: https://github.com/home-assistant/home-assistant/issues/26914. I was unsure if this ticket was still being considered as it is in the closed state. Please close the new ticket if this issue can be re-opened instead. Thank you!

Preface: I haven't used the play_media service before as it has never worked for me. I've found this has been for several reasons, and possibly more that I haven't encountered yet:

  1. The API calls have been broken for some time.
  2. The target player must be both discoverable by GDM and directly reachable from the Plex server. Normally this will require both server & client to be in the same subnet, but there are ways around this if you know what you're doing on your network (e.g., UDP repeaters).
  3. The media_player platform didn't seem to apply the PLAY_MEDIA capability anywhere, so I'm not sure how anyone was able to call this service in the first place.
  4. The player had to be actively playing or paused to play new media via the service call. Being found and connected was not enough.

Anyway, I'm starting to put together a PR to address this. However, my own testing has been very spotty and I'm not sure of the cause(s) yet.

If there's anyone willing to test and give feedback, here are the changes that I have so far using 0.99 as a base: https://github.com/home-assistant/home-assistant/compare/dev...jjlawren:plex_playmedia_on_0.99.3

@jjlawren

freshly updated to 0.99.3...

2019-10-04 14:33:49 WARNING (MainThread) [homeassistant.loader] You are using a custom integration for plex which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2019-10-04 14:33:50 ERROR (MainThread) [homeassistant.config] Platform error: media_player
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config.py", line 757, in async_process_component_config
    platform = p_integration.get_platform(domain)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 232, in get_platform
    f"{self.pkg_path}.{platform_name}"
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/config/custom_components/plex/__init__.py", line 35, in <module>
    from .server import PlexServer
ImportError: cannot import name 'PlexServer' from 'custom_components.plex.server' (/config/custom_components/plex/server.py)

Did you add all the files from the plex component into /custom_components/plex/?

Did you add all the files from the plex component into /custom_components/plex/?

yes.

2019-10-04 at 2 51 PM

@jjlawren NM Sorry! - I had the wrong content in server.py. Rebooting now.

@jjlawren

K, got the integration loaded finally and tried to call the play_media service using json that was working for me back in the day when this all used to work.

Here's a traceback:

'PlexClient' object has no attribute 'plex_server'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 130, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1234, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/usr/src/homeassistant/homeassistant/core.py", line 1259, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 213, in handle_service
    self._platforms.values(), func, call, service_name, required_features
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 349, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 373, in _handle_service_platform_call
    await func(entity, data)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/plex/media_player.py", line 673, in play_media
    self.plex_server.library.section(src["library_name"])
AttributeError: 'PlexClient' object has no attribute 'plex_server'

I think I dimly remember that being similar or the same error that renaming variables or parameters with a preceding underscore fixed for me at one point.

Ah, there have been other improvements since 0.99.3 which this change depends on. Let me look a little closer and see if there's an easy way to make it work properly on 0.99.3.

Ok, workaround for that is available here: media_player.py. The rest of the files remain the same in this branch.

@jjlawren

I'm going to be away from the box for a while now, but will try more later if you post additional updates.

(musicpi is the name of the plex client i am trying to play to)

2019-10-04 15:42:17 ERROR (SyncWorker_19) [plexapi] musicpi failed to subscribe 
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 451, in playMedia
    self.sendCommand('timeline/subscribe', port=server_url[1].strip('/'), protocol='http')
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 195, in sendCommand
    return self.query(key, headers=headers)
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 167, in query
    return ElementTree.fromstring(data) if data.strip() else None
  File "/usr/local/lib/python3.7/xml/etree/ElementTree.py", line 1316, in XML
    return parser.close()
  File "<string>", line None
xml.etree.ElementTree.ParseError: syntax error: line 1, column 0
2019-10-04 15:42:17 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.1900104656] syntax error: line 1, column 0
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 130, in handle_call_service
    connection.context(msg),
  File "/usr/src/homeassistant/homeassistant/core.py", line 1234, in async_call
    await asyncio.shield(self._execute_service(handler, service_call))
  File "/usr/src/homeassistant/homeassistant/core.py", line 1259, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 213, in handle_service
    self._platforms.values(), func, call, service_name, required_features
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 349, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 373, in _handle_service_platform_call
    await func(entity, data)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/plex/media_player.py", line 705, in play_media
    self._client_play_media(media=media, shuffle=src.get("shuffle", False))
  File "/config/custom_components/plex/media_player.py", line 762, in _client_play_media
    self.device.playMedia(media)
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 467, in playMedia
    }, **params))
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 195, in sendCommand
    return self.query(key, headers=headers)
  File "/usr/local/lib/python3.7/site-packages/plexapi/client.py", line 167, in query
    return ElementTree.fromstring(data) if data.strip() else None
  File "/usr/local/lib/python3.7/xml/etree/ElementTree.py", line 1316, in XML
    return parser.close()
  File "<string>", line None
xml.etree.ElementTree.ParseError: syntax error: line 1, column 0

@pjv What type of client are you trying to play the media on? What type of media are you attempting to play? Can you share the JSON payload?

{
  "entity_id": "media_player.plex_musicpi",
  "media_content_id": "{\"library_name\" : \"Music\",\"artist_name\":\"Hass.io\",\"album_name\":\"Alerts\",\"track_name\":\"car-coming\",\"shuffle\":\"0\"}",
  "media_content_type": "MUSIC"
}

It's a rpi running headless plexamp.

trying to stream a short .mp3 sound file that hopes to tell me and my family when a vehicle is coming down the driveway...

in case you are wondering, I can cast music to that client from that PMS via other (non-HA) plex clients with no difficulty. And as mentioned before, that json above previously successfully streamed that same .mp3 to that same client reliably before the play_media service got broken.

So I've tested casting some music to a freshly installed Plexamp client and I get a similar error. However, it _does_ play the file on the client. Can you confirm if it's actually playing on the client?

sunny beaches. It's working. Cool.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

flsabourin picture flsabourin  路  3Comments

moskovskiy82 picture moskovskiy82  路  3Comments

neonandu picture neonandu  路  3Comments

piitaya picture piitaya  路  3Comments

kirichkov picture kirichkov  路  3Comments