jurialmunkey / plugin.video.themoviedb.helper

GNU General Public License v3.0
203 stars 96 forks source link

Option to only add variables to player string when available #126

Closed juanma-cvega closed 4 years ago

juanma-cvega commented 4 years ago

Would it be possible to provide a way to only add a variable to a player when it's available? For instance, when no TVDB id is available I would like to not include neither the variable nor the parameter that uses it in a url passed to the player. Again the EmbyCon player as an example. If the tvdb id is not present, I would like the parameter 'AnyProviderIdEquals' to not be included. So an option could to be to pass from {server}/emby/Users/{userid}/Items?IncludeItemTypes=movie&Recursive=true&ImageTypeLimit=1& AnyProviderIdEquals=tvdb.{tvdbid}&Limit=16&searchTerm={title} to this {server}/emby/Users/{userid}/Items?IncludeItemTypes=movie&Recursive=true&ImageTypeLimit=1[**& AnyProviderIdEquals=tvdb.{tvdbid}]**&Limit=16&searchTerm={title}

For this player, the searchTerm parameter interferes with the AnyProviderIdEquals one (if there is a match using the provider id but for some reason the names are different, which could happen as I've seen in the Emby server when someone messes up the TVDB database, there are no results being returned), so another possible feature could be to add a condition on one element being added based on another one not being there but that would be quite a lot of work I think.

jurialmunkey commented 4 years ago

Hmm. It's possible but not simple. Basically the {tags} are filled from a dictionary using built-in python string formatting - e.g. when the string formatter sees {title} it just substitutes it with whatever value matches the title key in the item details.

I think maybe a better approach would be to have separate player files for each method that you want to use. Then maybe I can add something like an "assert" value which says that those key values must exist otherwise the player fails and is removed from the list (just like if it failed to find an item).

Using Netflix player as an example:

{
    "name"              : "Netflix",
    "plugin"            : "plugin.video.netflix",
    "priority"          : 500,
    "assert"            : {
                            "play_movie": ["title", "year"],
                            "play_episode": ["showname", "season", "episode"],
                            "search_movie": ["title"],
                            "search_episode": ["showname"]
                          },
    "play_movie"        : [
                            "plugin://plugin.video.netflix/directory/search/search/{title}/",
                            {"title": "{title}", "year": "{year}"}
                          ],
    "play_episode"      : [
                            "plugin://plugin.video.netflix/directory/search/search/{showname}/",
                            {"title": "{showname}"},
                            {"season": "{season}"},
                            {"season": "{season}", "episode": "{episode}"}
                          ],
    "search_movie"      : "plugin://plugin.video.netflix/directory/search/search/{title}/",
    "search_episode"    : "plugin://plugin.video.netflix/directory/search/search/{showname}/"
}

So here for the play movie action to display as an option in the dialog there would need to be values for title and year. For the play episode option to display there would need to be showname, season, and episode. However, the search movie/episode options will display even if only the title/showname is available.

Do you think that would work for your needs?

jurialmunkey commented 4 years ago

Okay I've added the assert value (was relatively easy to do).

Can you test and see if this works for you? See above comment for usage.


Relevant Commit: https://github.com/jurialmunkey/plugin.video.themoviedb.helper/commit/9a0cee25b723eb4dcf83f86293e3ff09921a5a9d

juanma-cvega commented 4 years ago

I'm not sure I understand the usage.

So here for the play movie action to display as an option in the dialog there would need to be values for title and year.

When is that dialog showing? I think I'm missing some basics about your addon. Is each action supposed to be an option you can select to play a video? Like the list you see in the option to select a default action for a type of video?

jurialmunkey commented 4 years ago

So this section:

"assert"            : {
                            "play_movie": ["title", "year"],
                            "play_episode": ["showname", "season", "episode"],
                            "search_movie": ["title"],
                            "search_episode": ["showname"]
                          },

Tells the addon to not bother showing that player as an option if those infos are not available. e.g. the "Play with Netflix" player will only show if there is title and year info available.

So you could do something like

"assert"            : {
                            "play_episode": ["tvdbid"],
                          },

And the "Play with EmbyCon" player will only show as an option if the tvdbid is available. In that player you would have your approach which uses the tvdbid. Then you have a second player which uses the fallback approach without the tvdbid.

So then if tvdbid is available you would be able to select either approach. If tvdbid isn't available then you would only be able to select the second approach.

jurialmunkey commented 4 years ago

By dialog I mean the player select dialog

juanma-cvega commented 4 years ago

Ok, so that's what I was thinking. With this, the user would need to make the choice, it wouldn't be an automatic fallback to the second option. So the option to just select a video and let the default player kick in wouldn't work. Any chance the implementation could be done as a fallback inside a player? So the player would have a sorted list of things to try and it would stop at the first one the assert was for. Something like this:

"play_movie" : [ { "assert" : ["title", "year"], "action: [ "plugin://plugin.video.netflix/directory/search/search/{title}/", {"title": "{title}", "year": "{year}"} ] }, { "assert" : ["title"], "action: [ "plugin://plugin.video.netflix/directory/search/search/{title}/" ] } ] ]

Would that make sense?

jurialmunkey commented 4 years ago

No the user doesn't need to make a choice. The player is not available to select if the assert condition is not met.

jurialmunkey commented 4 years ago

Also, I just added the ability to invert the condition (i.e. show player if value does not exist) which will be useful for the fallback. You can do this by adding a ! to the key. e.g.


"assert"  : {"play_episode": ["!tvdbid"]},
juanma-cvega commented 4 years ago

It doesn't seem to work, I still see the url with the AnyProviderIdEqualsparameter being used in the logs. This is player I'm using.

{
    "name" : "EmbyCon",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert"            : {
                            "play_episode": ["epid"],
                            "search_episode": ["title_url"]
                          },
    "play_movie" : [
                    "plugin://plugin.video.embycon/?content_type=video&media_type=movies&mode=GET_CONTENT&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Dmovie%26Recursive%3Dtrue%26fields%3DMediaStreams%26ImageTypeLimit%3D1%26AnyProviderIdEquals%3Dimdb.{imdb}%26Limit%3D16%26searchTerm%3D{title_url}",
                    {"dialog": "auto"}
                   ],
    "play_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26AnyProviderIdEquals%3Dtvdb.{epid}%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ],
     "search_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ]
}
juanma-cvega commented 4 years ago

I just realised with this configuration I cannot select EmbyCon as a default player so it seems this breaks something there.

jurialmunkey commented 4 years ago

Okay I think both issues should be fixed now (select default player and assert value)

I guess another useful feature to add on the back of this would be the option to specify a "fallback" player if a player fails. That way you can setup a chain of players to attempt.


Relevant Commit: https://github.com/jurialmunkey/plugin.video.themoviedb.helper/commit/37f98eba6e97513fa33f447267fa8b4597c6731a

juanma-cvega commented 4 years ago

I guess another useful feature to add on the back of this would be the option to specify a "fallback" player if a player fails. That way you can setup a chain of players to attempt.

Are you talking about a fallback in the list of actions inside a player or a fallback to a completely different player? For instance from EmbyCon to Venom if it doesn't find anything.

juanma-cvega commented 4 years ago

I think it's still not working but I'm not sure. There is a problem now somewhere because I get tons of logs like this ones


                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.990 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for dbid
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Searching KodiDb for Title: Dragon Ball
                                            Indices: []
2020-03-06 23:44:54.991 T:15212  NOTICE: [plugin.video.themoviedb.helper]
                                            KodiLibrary -- Failed to Find Match for dbid

And it goes on and on.

jurialmunkey commented 4 years ago

You have debug logging turned on in TMDbHelper settings - those are normal messages if you have debug logging turned on.

jurialmunkey commented 4 years ago

Can you post your player files? I'm fairly certain assert is working correctly for me now (tested specifically with DragonBall). Perhaps there is something wrong with the syntax that you're using.

juanma-cvega commented 4 years ago

You have the full player in a previous comment. Do you need other information apart from that?

jurialmunkey commented 4 years ago

What is not working exactly?

jurialmunkey commented 4 years ago

To test I created a Youtube player like so

{
    "name"              : "YouTube",
    "plugin"            : "plugin.video.youtube",
    "priority"          : 200,
    "assert"            : {
                           "play_episode": ["epid"],
                           "search_episode": ["title_url"]
                         },
    "play_movie"        : [
                            "plugin://plugin.video.youtube/search/?q={name}&search_type=notvalid",
                            {"dialog": "auto"}],
    "play_episode"      : [
                            "plugin://plugin.video.youtube/search/?q={name}&search_type=notvalid",
                            {"dialog": "auto"}],
    "search_movie"      : [
                            "plugin://plugin.video.youtube/search/?q={name}&search_type=notvalid",
                            {"dialog": "auto"}],
    "search_episode"    : [
                            "plugin://plugin.video.youtube/search/?q={name}&search_type=notvalid",
                            {"dialog": "auto"}]
}

Expected behaviour is that "Play with Youtube" will show as a player option only if the episode has {epid} and "Search with Youtube" will only show if the episode has {title_url}

We know that early episodes of Dragon Ball will have {epid} and {title_url} since the TMDb data matches with Trakt data.

Here I attempt to play the first episode and get both options as expected (I disabled my other players to demonstrate)

Honeyview_screenshot604

We know that later episodes like Pilaf's Tactics don't have {epid} since the TMDb data doesn't match with Trakt. However, it will still have {title_url} so we should only see "Search Youtube" as shown in this screenshot:

Honeyview_screenshot603

If I only want to show "Search Youtube" when {epid} is not available, I instead can use: "assert": {"search_episode": ["!epid"]}

And now I only get "Play with Youtube" when playing the first episode (because epid is available) Honeyview_screenshot605

juanma-cvega commented 4 years ago

I don't know why but I cannot make it work. I removed all players and only left the embycon one. I re downloaded the latest code just in case. This is the current player.

{
    "name" : "EmbyCon",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert"            : {"search_episode": ["!epid"]},
    "play_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26AnyProviderIdEquals%3Dtvdb.{epid}",
                      {"dialog":"auto"}
                     ],
     "search_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ]
}

It seems it's not using the asserts, it passes always the tvdb id. When it finds episodes using it, it returns the list in the dialog, otherwise it just shows the list of players (in this case only 'Search Youtube'). Here you can find the logs. https://pastebin.com/J9ezP72x

jurialmunkey commented 4 years ago

Wait are you using this player as the default player? I think maybe the default player setting is overriding the assert - originally I only tested without a default.

jurialmunkey commented 4 years ago

@juanma-cvega - Okay, hopefully the latest version will finally fix this issue! Tested extensively with a default player set and I believe it is working correctly now. Can you test and confirm?


Relevant Commit: https://github.com/jurialmunkey/plugin.video.themoviedb.helper/commit/a0cee2a601bbb289db9077bd4aa43a4e5bf293ac

juanma-cvega commented 4 years ago

I just tested it but I'm not sure of what's going on exactly. Here are the steps I took:

So I would expect, for the episodes that don't have an IMDB, for the 'search episode' player configured in the EmbyCon player to kick in automatically without me having to select it first. And then, if there are no results found, to see the other players in a dialog to choose from. Am I correct? What I understand is that right now is not using the assert, it's just using the default player and then letting you select another player-

juanma-cvega commented 4 years ago

I just realised there is something that was different in my head from this approach. With the current configuration, the file actually creates two players, 'play episode' and 'search episode'. Those 2 appear independent one from the other in the list of players available. To me they are the same player that can adapt to 2 different situations based on heuristics (the id is there or not) so to the end user it's transparent. Does that make sense?

jurialmunkey commented 4 years ago

With the current configuration, the file actually creates two players, 'play episode' and 'search episode'.

That's how it's always been. You should use play_ for approaches that end up with a playable file and search_ for approaches that end with a container of results.

There's no limit on the number of player files you can use. If you want to have two different play_episode approaches, you should create two different player files.

For example: embycon_epid.json

{
    "name" : "EmbyCon (by Episode ID)",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert" : {"play_episode": ["epid"]},
    "play_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26AnyProviderIdEquals%3Dtvdb.{epid}",
                      {"dialog":"auto"}
                     ]
}

embycon_title.json

{
    "name" : "EmbyCon (by Title)",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert" : {"play_episode": ["!epid"]},
    "play_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ]
}

Now you will have two players for episodes: Play with EmbyCon (by Episode ID) Play with EmbyCon (by Title)

The Episode ID one will only be available if there is {epid}. The Title one will only be available if there NO {epid}

Once I have the fallback method working properly for default players, you will be able to chain the files together so that play by epid fallsback to play by title.

juanma-cvega commented 4 years ago

Ok, I understand now. I mainly use the default player as I use it through the library. That's why I didn't get how it was supposed to work. If you're developing a fallback mechanism for default players I'll then wait for that to be implemented. I'll run a test without the default player though to verify the current implementation works as expected.

On Sun, Mar 8, 2020, 13:08 jurialmunkey notifications@github.com wrote:

With the current configuration, the file actually creates two players, 'play episode' and 'search episode'.

That's how it's always been. You should use play for approaches that end up with a playable file and search for approaches that end with a container of results.

There's no limit on the number of player files you can use. If you want to have two different play_episode approaches, you should create two different player files.

For example: embycon_epid.json

{ "name" : "EmbyCon (by Episode ID)", "plugin" : "plugin.video.embycon", "priority" : 200, "assert" : {"play_episode": ["epid"]}, "play_episode" : [ "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26AnyProviderIdEquals%3Dtvdb.{epid}", {"dialog":"auto"} ],

embycon_title.json

{ "name" : "EmbyCon (by Title)", "plugin" : "plugin.video.embycon", "priority" : 200, "assert" : {"play_episode": ["!epid"]}, "play_episode" : [ "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}", {"dialog":"auto"} ],

Now you will have two players for episodes: Play with EmbyCon (by Episode ID) Play with EmbyCon (by Title)

The Episode ID one will only be available if there is {epid}. The Title one will only be available if there NO {epid}

Once I have the fallback method working properly for default players, you will be able to chain the files together so that play by epid fallsback to play by title.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jurialmunkey/plugin.video.themoviedb.helper/issues/126?email_source=notifications&email_token=ABTT2RTGI2Q4B3CLDUIFSJDRGODEBA5CNFSM4LC5CIL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOEUICI#issuecomment-596198409, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTT2RXTVEPOU2QVSM2VFXLRGODEBANCNFSM4LC5CILQ .

jurialmunkey commented 4 years ago

I've just implemented the fallback function actually.

You can specify a fallback like so:

"fallback": {"play_movie": "youtube.json play_movie",
             "search_movie": "youtube.json search_movie"}

So here if the player's play_movie fails then it will try the youtube.json player's play_movie. You can specify any player file and action to fallback to.

The fallbacks should also chain together so if one fallback fails TMDbHelper will then try to play whatever the fallback's fallback is (and then the fallback's fallback's fallback and so on until there isn't a fallback, at which point it then prompts to select a player instead).


Relevant Commit: https://github.com/jurialmunkey/plugin.video.themoviedb.helper/commit/c2747bd83a7c9af4805e2c0e1bbe4a6b0bc65527

juanma-cvega commented 4 years ago

Is this supposed to be added inside a player's file? If you can chain together players like this from different files, wouldn't it be easier to provide a single file with the list of players to try in order? Would it work if I just create a file called 'fallback_players' and I add this configuration in there? This could be added to the configuration screen, replacing the current default player configuration.

juanma-cvega commented 4 years ago

I just tested both without default players and with default players and fallback. Without default players work, I tested it with two different files as you suggested I could only see the relevant one (play or search), depending on whether the TVDB id was there. But I tried adding both to the same file and it didn't work for some reason. This was the file I used.

{
    "name" : "EmbyCon",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert"            : 
                            {"search_episode": ["!epid"],
                            "play_episode": ["epid"]},
    "play_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26AnyProviderIdEquals%3Dtvdb.{epid}",
                      {"dialog":"auto"}
                     ],
     "search_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ]
}

I then run a test with the fallback mechanism but I couldn't make it work. I added a fallback to the search file to run the venom player and after the search didn't find any thing the addon threw an exception. This was the file:

{
    "name" : "EmbyCon",
    "plugin" : "plugin.video.embycon",
    "priority" : 200,
    "assert"            : {
                                        "search_episode": ["!epid"]
                                    },
    "search_episode" : [
                      "plugin://plugin.video.embycon/?content_type=video&mode=GET_CONTENT&media_type=episodes&url=%7Bserver%7D%2Femby%2FUsers%2F%7Buserid%7D%2FItems%3FIncludeItemTypes%3Depisode%26filters%3DIsNotFolder%26fields%3DMediaStreams%26Recursive%3Dtrue%26ImageTypeLimit%3D1%26Limit%3D16%26searchTerm%3D{title_url}",
                      {"dialog":"auto"}
                     ],
    "fallback": {"play_episode": "direct.venom.json play_episode"}     
}

And this the exception:

2020-03-09 21:13:10.360 T:14072  NOTICE: EmbyCon.resources.lib.downloadutils|DEBUG|Content-Type: None
2020-03-09 21:13:10.360 T:14072  NOTICE: EmbyCon.resources.lib.downloadutils|DEBUG|{"Items":[],"TotalRecordCount":0}
2020-03-09 21:13:10.360 T:14072  NOTICE: EmbyCon.resources.lib.downloadutils|DEBUG|====== 200 finished ======
2020-03-09 21:13:10.360 T:14072  NOTICE: EmbyCon.resources.lib.downloadutils|DEBUG|Closing HTTP connection: <httplib.HTTPSConnection instance at 0x000002C056B82308>
2020-03-09 21:13:10.361 T:14072  NOTICE: EmbyCon.resources.lib.dir_functions|DEBUG|total_records: 0
2020-03-09 21:13:10.361 T:14072  NOTICE: EmbyCon.resources.lib.dir_functions|DEBUG|SETTING_SORT for media type: Episodes
2020-03-09 21:13:10.361 T:14072  NOTICE: EmbyCon.resources.lib.dir_functions|DEBUG|No view id for view type:view-episodes
2020-03-09 21:13:10.361 T:14072  NOTICE: EmbyCon.resources.lib.functions|DEBUG|===== EmbyCon FINISHED =====
2020-03-09 21:13:10.430 T:11700   ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                             - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                            Error Type: <type 'exceptions.ValueError'>
                                            Error Contents: too many values to unpack
                                            Traceback (most recent call last):
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\script.py", line 10, in <module>
                                                TMDbScript.router()
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\script.py", line 439, in router
                                                self.play()
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\script.py", line 328, in play
                                                force_dialog=self.params.get('force_dialog'))
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\player.py", line 204, in play
                                                return self.play_external(force_dialog=force_dialog)
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\player.py", line 148, in play_external
                                                return self.play_external(force_dialog=force_dialog, playerindex=playerindex)
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\player.py", line 86, in play_external
                                                playerindex = self.get_playerindex(force_dialog=force_dialog)
                                              File "C:\Users\juanm\AppData\Roaming\Kodi\addons\plugin.video.themoviedb.helper\resources\lib\player.py", line 74, in get_playerindex
                                                dp_file, dp_action = self.dp_episodes_id.split()
                                            ValueError: too many values to unpack
                                            -->End of Python script error report<--
2020-03-09 21:13:10.495 T:15372  NOTICE: [plugin.video.themoviedb.helper]
                                            TMDb Get Details: No Item Type or TMDb ID!
                                            tv None
2020-03-09 21:13:10.879 T:15372  NOTICE: [plugin.video.themoviedb.helper]
                                            HTTP Error Code: 404
                                            Request: https://api.trakt.tv//shows/tt0088509/seasons/1/episodes/150/ratings?
jurialmunkey commented 4 years ago

Is this supposed to be added inside a player's file? If you can chain together players like this from different files, wouldn't it be easier to provide a single file with the list of players to try in order? Would it work if I just create a file called 'fallback_players' and I add this configuration in there? This could be added to the configuration screen, replacing the current default player configuration.

Yes inside the player file.

I did think about having one central fallback file but I think it is more extensible the way I have it now.

With this approach you can make several different chains of players that all show in the players dialog. Netflix -> Youtube Netflix -> Amazon Embycon -> Netflix -> Youtube Embycon -> Netflix -> Amazon Embycon -> Youtube etc.

jurialmunkey commented 4 years ago

Your Search/Play in one file works properly for me when I tested using DragonBall -- (I copied your code and replaced the references to Emby with Youtube).

I also can't recreate your error with your second player file. How are you attempting to play these items? Widget or in TMDbHelper? Context menu, Click, or Info Dialog?

I think maybe you should attempt with a fresh install of TMDbHelper. Delete its addon_data folder and test with no extra players installed except the embycon one. I think you have a player file that is conflicting because I'm unable to reproduce these errors with the players you posted above.

Also, your fallback is wrong. You need to change the {"play_episode": part to {"search_episode": i.e. "fallback": {"search_episode": "direct.venom.json play_episode"}

You want the "search_episode" action in the EmbyCon player to fallback to the "play_episode" action of the venom player. (I tested both incorrect/correct and couldn't recreate your error either way though).

juanma-cvega commented 4 years ago

I was able to make it work after a fresh install. I don't know why it didn't work before. I tested it both from the addon and from the library and in both cases it works. Regarding the single file vs fallback in each file, I think it's going to make many people miss the feature. I only know about it because I asked for the feature but for any other person that doesn't see the option in the configuration of the addon it will be invisible. Besides, it's going to force people to have their own list of configuration files which is going to be a bit of a pain for fresh installs. Right now, there is a link to the tmdbplayers that only needs to be added to the configuration in the addon and it will automatically download the list. Players are independent of each other which allows for having a single repository with them. But mixing them with other players via fallbacks is going to force people to keep their own copies and make them available to avoid dealing with copying files once the addon is installed. That's why IMHO is better user wise to have a single file so it can be edited via the addon directly. What do you think?

jurialmunkey commented 4 years ago

I don't maintain any players for this addon other than the ones that are shipped by default i.e. Youtube and Netflix. TMDbHelper has always had a focus on users writing their own player files. If other people want to ship links of folders of players for third party addons, that's their business - but it is definitely not part of TMDbHelper and it has nothing to do with me.

The whole idea is that you should only put the player files that you're using in that folder - otherwise you're just making TMDbHelper do extra work because it has to go to the folder and iterate over every file, read it, check whether the addon exists in kodi and then build the players. It's not meant to be a dumping ground for every addon in existence - it is meant to be a way to configure TMDbHelper's interaction with other addons in a way that makes sense for your setup and needs.

Now that the fallback and assert params are confirmed to work correctly, I'll be adding details about them to the wiki and users will be able to discover how they work if they bother to read the docs.