Plex: media_content_id looks like it only supports "video" right now

Correct me if I’m wrong, but it looks like the play_media handler for the Plex component only supports a media_content_id of “video” which translates to “title” in the Plex API:

  1. When the Plex component’s media_player.play_media method is called it does a lookup_media() against the plex server object.

  2. plex_server.lookup_media() with media type MEDIA_TYPE_VIDEO calls the underlying PlexAPI library_section.get(), which only supports “title” at this time.

This causes issues when there are multiple titles / title collisions on the server; library_section.get() will return the first matching element. Since you can’t specify further element parameters we’re kind of stuck.

My first thought was to just add **kwargs to the underlying PlexAPI library_section.get() which would allow for those additional parameters to be simply passed from the HA Plex component to return the proper media element. I opened PR 554 on the PlexAPI project but it was closed on the grounds that it should be using library_section.all or the generic search to find the right element. I don’t really support that view as leaving it in the current state renders that entire function completely unreliable and useless (not to mention it narrows down the functionality of implementing the underlying Plex XML API), but I didn’t want to continue pursuing it without getting additional feedback.

My second thought would be to implement the search element in plex_server.lookup_media() with the caveat that it should only return one object, not a list or matching media. That sidesteps the entire .get() issue.

Any thoughts @jjlawren ? I could have this completely wrong as I just glanced over this stuff yesterday and today.

Yes, the assumption is that it returns a single item. That should probably be validated in the search response. The search syntax in the integration definitely isn’t ideal for complex searches.

As a workaround (or fix) there’s an undocumented feature for play_media on Plex that allows you to pass in a “ratingKey” which is a unique identifier for a Plex media item on a given server. This will let you always choose the exact item you want to play, but it also means you need to know the value in advance. It may not work for every workflow.

To use that today, try parameters like this:

media_content_type: plex
media_content_id: 2254    # ratingKey

You can find the ratingKey in Plex Web by viewing an item’s raw XML info.

1 Like

Ah I see, that makes sense now what that if isinstance(src, int): line does in play_media(). And yeah that’s a definite fix in my case as I’m finding items in the library based on an existing lookup table, so I’ve got all the attributes from the Video XML element to work with.

That works. Still the underlying .get() from the python Plex API overlay definitely irks me now.

Glad that works. I’m curious, can you share an example of movie name collisions you’ve run into? Perhaps there’s a way to solve that problem for different use cases where the key isn’t possible to know ahead of time.

Yeah, I used the same example in the closed PR linked above, but here’s the actual Video XML element for The Killers (1964):

<Video ratingKey="1562" key="/library/metadata/1562" guid="com.plexapp.agents.imdb://tt0058262?lang=en" studio="Revue Studios" type="movie" title="The Killers" titleSort="Killers" librarySectionTitle="Films" librarySectionID="5" librarySectionKey="/library/sections/5" contentRating="Not Rated" summary="A hit man and his partner try to find out why their latest victim, a former race-car driver, did not try to get away." rating="7.9" audienceRating="7.1" year="1964" tagline="There's more than one way to kill a man!" thumb="/library/metadata/1562/thumb/1564302237" art="/library/metadata/1562/art/1564302237" duration="5691706" originallyAvailableAt="1964-07-07" addedAt="1564302025" updatedAt="1564302237" audienceRatingImage="rottentomatoes://image.rating.upright" primaryExtraKey="/library/metadata/1565" ratingImage="rottentomatoes://image.rating.ripe">

And for The Killers (1946):

<Video ratingKey="1563" key="/library/metadata/1563" guid="com.plexapp.agents.imdb://tt0038669?lang=en" studio="Universal Pictures" type="movie" title="The Killers" titleSort="Killers" librarySectionTitle="Films" librarySectionID="5" librarySectionKey="/library/sections/5" contentRating="Passed" summary="Two hit men walk into a diner asking for a man called "the Swede". When the killers find the Swede, he's expecting them and doesn't put up a fight. Since the Swede had a life insurance policy, an investigator, on a hunch, decides to look into the murder. As the Swede's past is laid bare, it comes to light that he was in love with a beautiful woman who may have lured him into pulling off a bank robbery overseen by another man." rating="10.0" audienceRating="8.9" viewOffset="158714" lastViewedAt="1565674650" year="1946" tagline="She's a match for any mobster!" thumb="/library/metadata/1563/thumb/1564302529" art="/library/metadata/1563/art/1564302529" duration="6159006" originallyAvailableAt="1946-08-28" addedAt="1564302027" updatedAt="1564302529" audienceRatingImage="rottentomatoes://image.rating.upright" primaryExtraKey="/library/metadata/1612" ratingImage="rottentomatoes://image.rating.ripe">

Basically anything that’s had a remake is an easy way to spot collisions, though there are plenty of non-remakes that also collide. Even though in my use case I don’t need to know the ratingKey prior to matching, from what I can tell the only way to do a “blind” match is to match on (title AND year).

You can get pretty close with the following but it’s not 100%:

  • Correlate on (Title and Studio) or (Title and Director) or all three (Title and Studio and Director). Any of these would work on The Killers above. However something like Funny Games by Michael Haneke would fail on (Title and Director) since he remade his own film, the original in 1997 and then remade in 2007.
  • Correlate on guid; this is slightly more predictable than ratingKey but suffers from the fact that it depends on which agent was used. I haven’t investigated this much; it may work on partial matches
  • Attributes like duration or originallyAvailableAt suffer from the opposite problem: it’s probably very unique, but actually finding out what the values are outside of Plex is pretty difficult and the data for it doesn’t seem all that universal.

Been slowly automating my entire Plex library and keep running into title collisions. The latest was Insomnia (1997) for the original Norwegian version and Insomnia (2002) the US remake, as well as The Manchurian Candidate 1962 vs 2004 remake, and Sunshine (2007) vs Sunshine (1999), the latter two being hilariously opposite films to be queueing up if you expected one and not the other. The docs should probably be updated to mention the issue and the workaround.

There is another workaround as well if someone doesn’t want to use ratingKey; you rename the title manually. Not great, especially if you’re a stickler for data integrity, but it works.

I’m working on another feature at the moment but adding a year qualifier to movie searches seems like the simplest solution for now. I’ll put it on my list of things to fix.

@lidocaineus I’ve submitted a PR that allows for much more powerful searching for movies: https://github.com/home-assistant/core/pull/39584

It’s merged and in 0.115. Check the docs for details on how to use the new movie parameters: https://home-assistant.io/integrations/plex#movie