Proper use of xbmcplugin.setResolvedUrl
#1
I've got a Kodi 18 and prior addon which I have been helping migrate to Kodi 19.  I submitted it to the Kodi repo and got feedback on a section of code which said "Player().play() is to be used by scripts not plugins. Please adjust this to use xbmcplugin.setResolvedUrl"  Here's the section of code.  This section of the addon is called by the user clicking on a listitem which passes a URL to this section of code to parse the web page and find the real associated URL:

def GET_STREAM(name,url):
    smil = get_html(url)
    contents = BeautifulSoup(smil,'html5lib')
    stream = (re.compile('src="(.+?)"').findall(str(contents))[0])
    if mp4base not in stream:
        #stream = mp4base + stream
        stream = stream
    listitem = xbmcgui.ListItem(name)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmc.log('CBC Sports Live Schedule Playback stream: ' + str(stream), xbmc.LOGDEBUG)
    if stream.find('Unavailable') > -1:
        xbmcgui.Dialog().notification(name, translation(30013), defaultimage, 6000, False)    
    else:
        xbmc.Player().play( stream, listitem )
    sys.exit()
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

I've tried modifying the code many different ways, as suggested, but it will not play the URL in stream when using xbmcplugin.setResolvedUrl.  Here's my latest try.  Any ideas on what I am doing wrong ?

def GET_STREAM(name,url):
    smil = get_html(url)
    contents = BeautifulSoup(smil,'html5lib')
    stream = (re.compile('src="(.+?)"').findall(str(contents))[0])
    if mp4base not in stream:
        #stream = mp4base + stream
        stream = stream
    if cbclog >= 1:
        xbmc.log('CBC Sports Live Schedule Playback stream: ' + str(stream), xbmc.LOGINFO)
    listitem = xbmcgui.ListItem(name, path=stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
    listitem.setProperty('IsPlayable','true')
    #xbmc.Player().play( stream, listitem )
    sys.exit()
    xbmcplugin.endOfDirectory(int(sys.argv[1]))


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#2
you can start by removing the last few lines from that function as they are not needed:
(2021-11-22, 12:01)jbinkley60 Wrote:
python:
    listitem.setProperty('IsPlayable','true')
    #xbmc.Player().play( stream, listitem )
    sys.exit()
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

this listitem.setProperty('IsPlayable','true') needs to be done in the function that creates the video listing
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#3
(2021-11-22, 18:50)ronie Wrote: you can start by removing the last few lines from that function as they are not needed:
(2021-11-22, 12:01)jbinkley60 Wrote:
python:
    listitem.setProperty('IsPlayable','true')
    #xbmc.Player().play( stream, listitem )
    sys.exit()
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

this listitem.setProperty('IsPlayable','true') needs to be done in the function that creates the video listing

Thanks.  That was it.  I missed that there were 2 different places in the code which create the source listitems, one for live events and the other for video on demand.  One was missing the: listitem.setProperty('IsPlayable','true') line.


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#4
(2021-11-22, 18:50)ronie Wrote: you can start by removing the last few lines from that function as they are not needed:
(2021-11-22, 12:01)jbinkley60 Wrote:
python:
    listitem.setProperty('IsPlayable','true')
    #xbmc.Player().play( stream, listitem )
    sys.exit()
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

this listitem.setProperty('IsPlayable','true') needs to be done in the function that creates the video listing

Thanks again for your initial guidance.  I have one other question.  There are scenarios where the original listitem referral to the parsing code above results in the stream URL needing to be played not yet published by the source provider.  Basically they publish a schedule but the stream isn't valid yet to be played.  Since I've set the original listitem as isPlayable the code now wants to try and play the stream, which creates a Kodi message that it can't be played and displays in the GUI:

2021-11-23 02:54:12.799 T:28396   ERROR <general>: Playlist Player: skipping unplayable item: 0, path [plugin://plugin.video.cbc-sports/?url=http%3A%2F%2Fwww.cbc.ca%2Fsports&mode=2&name=11%2F25%2F2021+-+13%3A00+EST+-+International+Swimming+League%3A+Playoffs]

I've worked around the problem but having the code play a couple second error video from the website but I was wondering is with the use of  xbmcplugin.setResolvedUrl if I find through the webpage parsing a valid URL doesn't yet exist to be played, can I just drop out and return without getting the playback error or using the unavailable stream ?

Here's psuedo code for what I have working now:

if webpage parsing is good:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    stream = unavailableUrl
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)

I'd prefer something like this that doesn't throw the error:

if webpage parsing is good:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    return

I am not sure if a try / except would work (or is recommended) on the referring isPlayable directive or whether this is possible ?  The prior:

xbmc.Player().play( stream, listitem )

approach leveraged a try / except and caught invalid streams.

 
Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#5
have you tried if xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) for unplayable items does the trick?
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#6
(2021-11-23, 12:57)ronie Wrote: have you tried if xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) for unplayable items does the trick?

I saw that after I posted my initial question and gave it a try but it still wants to play something.  Here's a code snippet:

    if cbclog >= 1:
        xbmc.log('CBC Sports Live Schedule valid stream: ' + str(valid), xbmc.LOGINFO)
        xbmc.log('CBC Sports Live Schedule Playback stream: ' + str(stream), xbmc.LOGINFO)

    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})

    if valid == 0:
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
    else:
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)

The valid flag denotes whether parsing was successful.  0 means parsing was good.  Anything else means it failed.  

2021-11-23 06:06:36.060 T:38020    INFO <general>: CBC Sports Live Schedule valid stream: 1
2021-11-23 06:06:36.060 T:38020    INFO <general>: CBC Sports Live Schedule Playback stream: Not found
2021-11-23 06:06:36.113 T:38020    INFO <general>: CPythonInvoker(235, C:\Users\Audio1\AppData\Roaming\Kodi\addons\plugin.video.cbc-sports\addon.py): script successfully run
2021-11-23 06:06:36.147 T:28396    INFO <general>: VideoPlayer::OpenFile: plugin://plugin.video.cbc-sports/?url=http%3A%2F%2Fwww.cbc.ca%2Fsports&mode=2&name=11%2F25%2F2021+-+13%3A00+EST+-+International+Swimming+League%3A+Playoffs
2021-11-23 06:06:36.148 T:39564    INFO <general>: Creating InputStream
2021-11-23 06:06:36.148 T:39564   ERROR <general>: CVideoPlayer::OpenInputStream - error opening [plugin://plugin.video.cbc-sports/?url=http%3A%2F%2Fwww.cbc.ca%2Fsports&mode=2&name=11%2F25%2F2021+-+13%3A00+EST+-+International+Swimming+League%3A+Playoffs]

It still tried to play the stream.


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#7
hmm... too bad that didn't work
perhaps it will work if you don't set the path for unplayable items, like so:

python:
    if valid == 0:
        listitem = xbmcgui.ListItem(name, path = stream)
        listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
    else:
        listitem = xbmcgui.ListItem(name)
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#8
try using the below instead of resolveurl
python:
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)
Reply
#9
(2021-11-23, 19:16)matthuisman Wrote: I use below for playback that I know failed.
Can't remember exactly why but after a bit of trial and error, it seemed to work the best.
Pretty sure it suppresses the Kodi playback error.

python:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, Item(path='http').get_li())
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=True, updateListing=False, cacheToDisc=False)

If that doesn't work, try using the below instead of resolveurl

python:
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)

Thanks for the suggestions.  Oddly, I can get a few of these options to work and not play when the parsing fails but with all of them it tries to play every third time.  I even tried refreshing the item listing between tries and navigating away to another listing and coming back.  On every third listitem I click on which doesn't parse it tries to play it and gives the error.  This feels like it might be some type of Kodi bug.


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#10
hmm, I use playable=True, and then in the playback path, I sometimes ask to resume.
if they press back, it cancels out without any kodi playback error.
just tried 4 times and still no playback error

I do that with the below in the playback
Just don't resolve the url - how can it try to playback anything if there is no resolveurl?
python:
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)

eg.
python:
if valid == 0:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)
Reply
#11
(2021-11-23, 22:52)matthuisman Wrote: hmm, I use playable=True, and then in the playback path, I sometimes ask to resume.
if they press back, it cancels out without any kodi playback error.
just tried 4 times and still no playback error

I do that with the below in the playback
Just don't resolve the url - how can it try to playback anything if there is no resolveurl?
python:
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)

eg.
python:
if valid == 0:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)


Playable is true in the referring list item.  Based upon the Kodi logs:

2021-11-23 16:41:50.944 T:39652   ERROR <general>: Playlist Player: skipping unplayable item: 0, path [plugin://plugin.video.cbc-sports/?url=http%3A%2F%2Fwww.cbc.ca%2Fsports&mode=2&name=11%2F26%2F2021+-+05%3A45+EST+-+IBSF+World+Cup+Bobsleigh+%26+Skeleton%3A+Men%27s+Skeleton+%28Heat+2%29+-+Innsbruck]
2021-11-23 16:41:50.944 T:39652   DEBUG <general>: Playlist Player: one or more items failed to play... aborting playback

It sees the referring URL as unplayable but only every third one does it give out the GUI error if I don't set it to the unavailable URL like below.  What is interesting in the Kodi logs is that when I set the resolved URL to the 3 second clip the logs still show it playing the referring URL:

2021-11-23 19:09:22.870 T:39652    INFO <general>: VideoPlayer::OpenFile: plugin://plugin.video.cbc-sports/?url=http%3A%2F%2Fwww.cbc.ca%2Fsports&mode=2&name=11%2F25%2F2021+-+13%3A00+EST+-+International+Swimming+League%3A+Playoffs

vs. the actual URL which is: 

unavailableurl = 'http://link.theplatform.com/s/errorFiles/Unavailable.mp4'

    listitem = xbmcgui.ListItem(name, path=unavailableurl)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)

Out of curiosity what version of Kodi are you running and on what platform ?  I am testing Kodi 18.1 on Windows 10. 


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#12
(2021-11-23, 22:52)matthuisman Wrote: hmm, I use playable=True, and then in the playback path, I sometimes ask to resume.
if they press back, it cancels out without any kodi playback error.
just tried 4 times and still no playback error

I do that with the below in the playback
Just don't resolve the url - how can it try to playback anything if there is no resolveurl?
python:
xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)

eg.
python:
if valid == 0:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    xbmcplugin.endOfDirectory(int(sys.argv[1]), succeeded=False, updateListing=False, cacheToDisc=False)

After some more testing I found something interesting.  In the parsing code which sets the valid flag (to denote whether it was successful in parsing our the real URL) I have a notification message which lets the user know why parsing failed (i.e. Blacked out in their region, source website hasn't posted the valid URL stream yet etc.).

It looks like this:

Real URL parsing fails for whatever reason so notify the user why:
xbmcgui.Dialog().notification(name, translation(30320), defaultimage, notetime, False)
valid = 1

if valid == 0:
    listitem = xbmcgui.ListItem(name, path = stream)
    listitem.setArt({'thumb': defaultimage, 'icon': defaultimage})
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
else:
    listitem = xbmcgui.ListItem(name)
    xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)

If I comment out the xbmcgui.Dialog().notification line or place it after the xbmcplugin.setResolvedUrl line I rarely get the failed playback message.   I am curious if you want to try adding a notification message to your code and see if you see the same results ?  I like the notification so the user knows why as opposed to clicking on the listitem and nothing happens.


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply

Logout Mark Read Team Forum Stats Members Help
Proper use of xbmcplugin.setResolvedUrl0