Can my addon be called back to assist in playing a particular item in the play queue?
#1
I'm trying to understand if it's possible to have play queue items that call my addon back in order for it to properly resolve e.g. the URL to a network resource just-in-time? For instance by using a custom URL scheme in the queued items that points back to my addon, like: "myaddonscheme://the.original?url&encoded=somehow"

The existing addon that I'm looking at has a performance problem where it tries to completely parse every entry of a youtube playlist in an eager way in order to make them immediately playable by Kodi. I would like to defer that work to the time that a queued item is actually due to play, thereby doing the minimal amount of work in a lazy way and spreading out the unreasonably large performance hit.
Reply
#2
Yes any plugin can be called using plugin://
See https://kodi.wiki/view/Add-on:YouTube#In...STRM_files
For an example
Reply
#3
(2020-05-29, 00:08)hungry person Wrote: I'm trying to understand if it's possible to have play queue items that call my addon back in order for it to properly resolve e.g. the URL to a network resource just-in-time? For instance by using a custom URL scheme in the queued items that points back to my addon, like: "myaddonscheme://the.original?url&encoded=somehow"

The existing addon that I'm looking at has a performance problem where it tries to completely parse every entry of a youtube playlist in an eager way in order to make them immediately playable by Kodi. I would like to defer that work to the time that a queued item is actually due to play, thereby doing the minimal amount of work in a lazy way and spreading out the unreasonably large performance hit.

Isn't that what resolvedurl is meant for? https://codedocs.xyz/xbmc/xbmc/group__py...3977acde0f
Reply
#4
(2020-05-29, 07:24)learningit Wrote: Yes any plugin can be called using plugin://
See https://kodi.wiki/view/Add-on:YouTube#In...STRM_files
For an example

Thank you! I knew I had seen it before, but couldn't seem to find it. That sounds promising.
Reply
#5
(2020-05-29, 09:32)Takezo36 Wrote:
(2020-05-29, 00:08)hungry person Wrote: I'm trying to understand if it's possible to have play queue items that call my addon back in order for it to properly resolve e.g. the URL to a network resource just-in-time? For instance by using a custom URL scheme in the queued items that points back to my addon, like: "myaddonscheme://the.original?url&encoded=somehow"

The existing addon that I'm looking at has a performance problem where it tries to completely parse every entry of a youtube playlist in an eager way in order to make them immediately playable by Kodi. I would like to defer that work to the time that a queued item is actually due to play, thereby doing the minimal amount of work in a lazy way and spreading out the unreasonably large performance hit.

Isn't that what resolvedurl is meant for? https://codedocs.xyz/xbmc/xbmc/group__py...3977acde0f 

Thanks for the suggestion. I've not really touched any Kodi API before so I'm pretty lost there to be honest. Btw, when I say "my addon" it's actually someone else's existing addon whose execution time I'm trying to get to within reason.

The description of that function reads "Callback function to tell Kodi that the file plugin has been resolved to a url" which is a little hard for me to interpret unambigiously, and its context of "ModuleXbmcplugin.h" does not offer a description at all. What makes it a bit unclear to me is:
  1. whether "file plugin" refers to a particular plugin type (that e.g. my addon needs to opt into)
  2. whether "the file plugin has been resolved to a url" actually means "the plugin has resolved a specific item [in a file list] to an URL".
  3. when and how my "file plugin" will actually be requested by Kodi to perform this resolution. I'm mainly concerned with when Kodi tries to play a new item in the play queue, so that I can give it a concrete URL at that point -- is a "file plugin" suitable for that use case?

I hope you understand my confusion!
Reply
#6
(2020-05-29, 07:24)learningit Wrote: Yes any plugin can be called using plugin://
See https://kodi.wiki/view/Add-on:YouTube#In...STRM_files
For an example

I tried doing the following, which results in a crash (!). Needless to say, my addon was never called back:


Code:
   
    pl = xbmc.PlayList(1)
    pl.clear()
    xbmc.PlayList(1).add("plugin://plugin.video.sendtokodi/?KBkWoK66fus")
    xbmc.Player().play(pl)


Last entry in the log:

2020-05-29 14:24:31.346 T:1332736736   ERROR: WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.


This doesn't make much sense to me considering I'm not interacting with any filesystem.
Reply
#7
(2020-05-29, 12:28)hungry person Wrote:
(2020-05-29, 09:32)Takezo36 Wrote:
(2020-05-29, 00:08)hungry person Wrote: I'm trying to understand if it's possible to have play queue items that call my addon back in order for it to properly resolve e.g. the URL to a network resource just-in-time? For instance by using a custom URL scheme in the queued items that points back to my addon, like: "myaddonscheme://the.original?url&encoded=somehow"

The existing addon that I'm looking at has a performance problem where it tries to completely parse every entry of a youtube playlist in an eager way in order to make them immediately playable by Kodi. I would like to defer that work to the time that a queued item is actually due to play, thereby doing the minimal amount of work in a lazy way and spreading out the unreasonably large performance hit.

Isn't that what resolvedurl is meant for? https://codedocs.xyz/xbmc/xbmc/group__py...3977acde0f  

Thanks for the suggestion. I've not really touched any Kodi API before so I'm pretty lost there to be honest. Btw, when I say "my addon" it's actually someone else's existing addon whose execution time I'm trying to get to within reason.

The description of that function reads "Callback function to tell Kodi that the file plugin has been resolved to a url" which is a little hard for me to interpret unambigiously, and its context of "ModuleXbmcplugin.h" does not offer a description at all. What makes it a bit unclear to me is:
  1. whether "file plugin" refers to a particular plugin type (that e.g. my addon needs to opt into)
  2. whether "the file plugin has been resolved to a url" actually means "the plugin has resolved a specific item [in a file list] to an URL".
  3. when and how my "file plugin" will actually be requested by Kodi to perform this resolution. I'm mainly concerned with when Kodi tries to play a new item in the play queue, so that I can give it a concrete URL at that point -- is a "file plugin" suitable for that use case?

I hope you understand my confusion! 

Hi, oh yes i understand your confusion... have spent a lot of time myself searching forums wiki and codedoc trying to make sense out of things.
This is the best explenation i've seen
https://forum.kodi.tv/showthread.php?tid=173986
second post describes both workflows, with and without resolvedurl, for a video plugin.
Reply
#8
Thanks for the link! I've looked through it and what I have gathered so far is:
 
  • that setResolvedUrl() isn't a callback I'm supposed to implement, but is instead something I call as part of some abstract global context that is only hinted at by having to pass the parameter `handle` ("handle the plugin was started with") to that function
  • My addon is expected to call setResolvedUrl() at some time after having been launched with a URL path that starts with "/play/"
  • I need to enqueue ListItems, not just plain URL strings, so that I can set isFolder=False and item.setProperty("IsPlayable", "true"), according to: "I found out the setResolvedUrl() is useless without settings the item.setProperty("IsPlayable", "true")"
  • Here it gets tricky, because I should also not set isPlayable=true according to: "setResolvedUrl simply sets up that processing for playing a directory item that isn't directly marked as playable when added to the directory"
  • An addon script (as opposed to an addon plugin) does not reasonably call setResolvedUrl() because -- according to that forum thread -- "An addon script loads and remains resident", which means there is no longer an implicit global context in which to call it such that Kodi knows which item I'm resolving.

I suppose my next step is to investigate what semantics these official looking URL paths (like "/play/") have, and what responsibility the plugin has after receiving it.

I really hope Kodi stops crashing if I start enqueuing ListItems again, instead of plain 'plugin://urls', because that was just too much to handle... Eek
Reply
#9
I can't follow the 2 conversations going on here, they're in different directions. I have no idea why setResolvedUrl is being discussed. The plugin:// prefix calls a plugin, not a script. The code using xbmc.player() appears to be a script, not a plugin (add-on).

There are other functions to execute a script. The script code given for the playlist will not work correctly in an add-on.

You need to decide whether you are making a script or a plugin. The approaches are different.
Reply
#10
Thanks for the reply
(2020-05-30, 20:15)learningit Wrote: I can't follow the 2 conversations going on here, they're in different directions. I have no idea why setResolvedUrl is being discussed.

Well, so far you've given me a suggestion, which I looked at. I tried it with a minimal change to the existing plugin, which made Kodi crash. That's the extent of our conversation so far, and the rest is about setResolvedUrl.

If you think setResolvedUrl should not be discussed, then by all means give us a reason to give up that path. I'm still orienting myself, so I'm happy to know about every path until I know for sure why it's a dead end.
 
Quote:The code using xbmc.player() appears to be a script, not a plugin (add-on).

I see. That is more than I can tell from that excerpt Smile

Initially I treated "addon" and "plugin" as synonymous, but I have since understood that there are "addon scripts" and "addon plugins". I am assuming that I'm working on a plugin since its ID is "plugin.video.sendtokodi", and that it imports xbmcplugin. It also appears to already make use of setResolvedUrl() in one code path.

I just kind of assumed it used things correctly when I jumped into this. I understand now that's not the case.
Quote:There are other functions to execute a script. The script code given for the playlist will not work correctly in an add-on.

I assume you mean "will not work correctly in a plugin" in which case I understand. I only made a minimal change to it though, so it basically worked before that, somehow. It already called all those methods successfully before I touched anything.
Quote:You need to decide whether you are making a script or a plugin. The approaches are different. 

Sounds reasonable. Unfortunately I'm not experienced enough to know which is appropritae from the usecase. The usecase is simply:
  1. send url to a (youtube) playlist from other device to kodi
  2. receive request in addon, parse page (with youtube-dl), enqueue unresolved "urls" (i.e. video identifiers)
  3. resolve each play queue entry just in time when it's about to play
Would you say it's a plugin or a script?
Reply
#11
(2020-05-30, 20:15)learningit Wrote: I can't follow the 2 conversations going on here, they're in different directions. I have no idea why setResolvedUrl is being discussed. The plugin:// prefix calls a plugin, not a script. The code using xbmc.player() appears to be a script, not a plugin (add-on).
Because i thought this
(2020-05-29, 00:08)hungry person Wrote: The existing addon that I'm looking at has a performance problem where it tries to completely parse every entry of a youtube playlist in an eager way in order to make them immediately playable by Kodi. I would like to defer that work to the time that a queued item is actually due to play, thereby doing the minimal amount of work in a lazy way and spreading out the unreasonably large performance hit.
is one of the use cases of setResolvedUrl. So pass on listitems quick and resolve the actual file later on. 
Maybe i misread the youtube playlist part. In my mind this meant this plugin talks to youtubes api and generates its own listitems, not getting them from the youtube plugin. 
...which now reading it again maybe doesn't make the most sense...
In the later case dismiss everything i said.
Reply
#12
xbmc.player() should not be used in a plugin any longer. setResolvedUrl should be. That is why it appears to be a script.
Reply
#13
(2020-05-30, 21:05)Takezo36 Wrote: generates its own listitems, not getting them from the youtube plugin. 

That is correct. It vendors its own youtube-dl library.

Quote:xbmc.player() should not be used in a plugin any longer. setResolvedUrl should be. That is why it appears to be a script.

Ok, I don't know which one it should be though.

Can I easily enqueue a list of items with setResolvedUrl then? I'm having a hard time understandig how I'd mimic the current behavior with setResolvedUrl, but I'll have another look...
Reply
#14
(2020-05-29, 14:31)hungry person Wrote:
(2020-05-29, 07:24)learningit Wrote: Yes any plugin can be called using plugin://
See https://kodi.wiki/view/Add-on:YouTube#In...STRM_files
For an example

I tried doing the following, which results in a crash (!). Needless to say, my addon was never called back:


Code:
   
    pl = xbmc.PlayList(1)
    pl.clear()
    xbmc.PlayList(1).add("plugin://plugin.video.sendtokodi/?KBkWoK66fus")
    xbmc.Player().play(pl)


Last entry in the log:

2020-05-29 14:24:31.346 T:1332736736   ERROR: WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.


This doesn't make much sense to me considering I'm not interacting with any filesystem.

Most likely a well known error because of the existence of two concurrent busydialogs at the same time. Play action activates the busyloader while plugin resolution also does the same. If the first happens while the first is running -> crash.
At the moment we don't have yet any fix for the issue, it's there since leia.
Reply
#15
(2020-05-31, 14:14)enen92 Wrote: Most likely a well known error because of the existence of two concurrent busydialogs at the same time. Play action activates the busyloader while plugin resolution also does the same. If the first happens while the first is running -> crash.
At the moment we don't have yet any fix for the issue, it's there since leia.

 Yes, you're probably right about that. I suspected that the Play() call was synchronous and that my plugin had not yet exited before getting called again.

I worked around this by making sure that the first entry in the playlist has a resolved url, thereby avoiding recursion. I also tried using what the Youtube plugin basically appeared to be doing, which was:

Code:
xbmc.executebuiltin('Playlist.PlayOffset(%s,%d)' % ('video', 0))]

but I suspect everything would have worked just as well with the original Play() code.


I now have a new problem in that the play queue gets emptied if I try to select an entry using the GUI. It works well if I just use the "play next" buttons though. Weird... I'm asking about that problem in another thread.
Reply

Logout Mark Read Team Forum Stats Members Help
Can my addon be called back to assist in playing a particular item in the play queue?0