Correct use of xbmc.Player in Python?
#1
Hello,

this is what I try to do with the audio player in my script:
remember current title and time
stop player
clear playlist and repopulate
start playing the playlist from the beginning
if the currently title is the same as it was, seek to the time where we left off

All works well expcept the last step. The player starts to play at the beginning but does not appear to seek. 

Part of my code:

python:

    playList = xbmc.PlayList(0)
    currentPos = playList.getposition()
    numAdded = 0
    
    playList.clear()

    for l in LinkURL:
        if not l == "":
            playList.add(url=l)
            numAdded += 1

    tm = xbmc.Player().getTime()
    fn1 = xbmc.Player().getPlayingFile()
    xbmc.log("current file: %s" % fn1, xbmc.LOGWARNING)
    xbmc.log("current time: %g" % tm, xbmc.LOGWARNING)
    xbmc.Player().stop()
    xbmc.Player().play(item = playList, startpos = 0)
    xbmc.Player().playselected(0)
    fn2 = xbmc.Player().getPlayingFile()
    # fn2 = fn1
    xbmc.log("    new file: %s" % fn2, xbmc.LOGWARNING)
    if fn1 == fn2:
        xbmc.log("before seekTime", xbmc.LOGWARNING)
        xbmc.log("Player.getTime is now: %g" % xbmc.Player().getTime(), xbmc.LOGWARNING)
        xbmc.log("seek to %g" % tm, xbmc.LOGWARNING)
        xbmc.Player().seekTime™
        xbmc.log("Player.getTime is now: %g" % xbmc.Player().getTime(), xbmc.LOGWARNING)
        xbmc.log("after seekTime", xbmc.LOGWARNING)
    else:
        xbmc.log("diferrent file - not seeking", xbmc.LOGWARNING)
        xbmc.Player().playselected(0)

    xbmcgui.Dialog().notification(__scriptname__, "%d titles were added to the playlist" % playList.size())

From the log (to illustrate, no violation of the forum rules intended):

2021-03-07 19:05:48.950 T:16348 WARNING <general>: current time: 51.119
2021-03-07 19:05:49.403 T:7120     INFO <general>: CDVDAudioCodecFFmpeg::Open() Successful opened audio decoder mp3float
2021-03-07 19:05:49.491 T:16348 WARNING <general>:     new file: d:\music\#electronica\Urbs\Toujours le même film... (2005)\Urbs - Toujours le même film... - 01 - So Weit.mp3
2021-03-07 19:05:49.492 T:16348 WARNING <general>: before seekTime
2021-03-07 19:05:49.492 T:16348 WARNING <general>: Player.getTime is now: 51.219
2021-03-07 19:05:49.492 T:16348 WARNING <general>: seek to 51.119
2021-03-07 19:05:49.492 T:16348 WARNING <general>: Player.getTime is now: 51.219
2021-03-07 19:05:49.492 T:16348 WARNING <general>: after seekTime
2021-03-07 19:05:49.492 T:16348    INFO <general>: CPythonInvoker(257, C:\Users\USER\AppData\Roaming\Kodi\addons\script.musicip\xbmcmusicip.py): script successfully run

My observation is that the player stops, then plays the new playlist from the beginning, as expected, but is not affected by seekTime. Oddly, the reported getTime() values appear to be correct!

Thx for your help.
Kodi 20.2.0
Windows 10 22H2
Intel Core i3 4160
Intel HD Graphics 4400
Reply
#2
python:

playList = xbmc.PlayList(0)
currentPos = playList.getposition()
numAdded = 0

playList.clear()
xbmc.sleep(100) #Kodi playlists usually require a moment to execute the clear call before adding (Known issue).
 
for l in LinkURL:
    if not l == "":
        playList.add(url=l)
        numAdded += 1

myPlayer = xbmc.Player() #make Player() a single call.
tm = myPlayer.getTime()
fn1 = myPlayer.getPlayingFile()
xbmc.log("current file: %s" % fn1, xbmc.LOGWARNING)
xbmc.log("current time: %g" % tm, xbmc.LOGWARNING)
myPlayer.stop()
myPlayer.play(item = playList, startpos = 0)
fn2 = myPlayer.getPlayingFile()
# fn2 = fn1
xbmc.log("    new file: %s" % fn2, xbmc.LOGWARNING)
if fn1 == fn2:
    xbmc.log("before seekTime", xbmc.LOGWARNING)
    xbmc.log("Player.getTime is now: %g" % myPlayer.getTime(), xbmc.LOGWARNING)
    xbmc.log("seek to %g" % tm, xbmc.LOGWARNING)
    myPlayer.seekTime™
    xbmc.log("Player.getTime is now: %g" % myPlayer.getTime(), xbmc.LOGWARNING)
    xbmc.log("after seekTime", xbmc.LOGWARNING)
else:
    xbmc.log("diferrent file - not seeking", xbmc.LOGWARNING)

xbmcgui.Dialog().notification(__scriptname__, "%d titles were added to the playlist" % playList.size())

https://codedocs.xyz/xbmc/xbmc/group__py...61308ebb2a

Made some minor corrections to the snippet above. frankly, this code looks more like a pseudo-code it's not really functional. You mentioned it's "part" of a greater project... perhaps you should show all work?

As is; you can only check the first position in the playlist index (0), then the script terminates. fn2 will always be Position 0...

Can you elaborate on what you are trying to achieve?
Image Lunatixz - Kodi / Beta repository
Image PseudoTV - Forum | Website | Youtube | Help?
Reply
#3
Thanks for the reply! I am doing a basic integration of MusicIP server into Kodi.

The MusicIP server is able to generate a mix of similar tracks based on a seed track, returned as a delimited list. What I want is to have a "more like this" menu item. The current music playlist should then be replaced with the new tracks.

The first track returned can be the seed track, based on settings, and if so I was thinking of resuming playback kind of seamlessly. All works well, except for this part. 

Here's the full script!

python:


import xbmc
import xbmcgui
import urllib.request
import urllib.parse
import re
import os

__scriptname__ = "Music IP"

if xbmc.Player().isPlayingAudio() == False:
    xbmcgui.Dialog().notification(__scriptname__, "Not currently playing audio")
else:
    currentlyPlaying = xbmc.Player().getMusicInfoTag().getURL()

    size=str(25)
    apiPath = 'http://localhost:10002/api/mix?song='
    options = '&size='+size+'&sizeType=tracks&content=text'

    # The url in which to use
    Base_URL = apiPath + urllib.parse.quote(currentlyPlaying.encode('iso-8859-1')) + options
    #Pre-define global Lists
    LinkURL = []

    WebSock = urllib.request.urlopen(Base_URL)  # Opens a 'Socket' to URL
    WebHTML = WebSock.read()            # Reads Contents of URL and saves to Variable
    WebSock.close()                     # Closes connection to url

    LinkURL = WebHTML.split(b'\n')
    playList = xbmc.PlayList(0)
    currentPos = playList.getposition()
    numAdded = 0

    playList.clear()

    for l in LinkURL:
        if not l == "":
            playList.add(url=l)
            numAdded += 1

    tm = xbmc.Player().getTime()
    fn1 = xbmc.Player().getPlayingFile().lower()
    xbmc.log("current file: %s" % fn1, xbmc.LOGWARNING)
    xbmc.log("current time: %g" % tm, xbmc.LOGWARNING)
    xbmc.Player().stop()
    xbmc.Player().play(item = playList, startpos = 0)
    xbmc.Player().playselected(0)
    fn2 = xbmc.Player().getPlayingFile().lower()

    xbmc.log("    new file: %s" % fn2, xbmc.LOGWARNING)
    if fn1 == fn2:
        xbmc.log("before seekTime", xbmc.LOGWARNING)
        xbmc.log("Player.getTime is now: %g" % xbmc.Player().getTime(), xbmc.LOGWARNING)
        xbmc.log("seek to %g" % tm, xbmc.LOGWARNING)
        xbmc.Player().seekTime™
        xbmc.log("Player.getTime is now: %g" % xbmc.Player().getTime(), xbmc.LOGWARNING)
        xbmc.log("after seekTime", xbmc.LOGWARNING)
    else:
        xbmc.log("diferrent file - not seeking", xbmc.LOGWARNING)

    xbmcgui.Dialog().notification(__scriptname__, "%d titles were added to the playlist" % playList.size())

Reply
#4
(2021-03-07, 21:46)Lunatixz Wrote:
python:

playList = xbmc.PlayList(0)
currentPos = playList.getposition()
numAdded = 0

playList.clear()
xbmc.sleep(100) #Kodi playlists usually require a moment to execute the clear call before adding (Known issue).
 
for l in LinkURL:
    if not l == "":
        playList.add(url=l)
        numAdded += 1

myPlayer = xbmc.Player() #make Player() a single call.
tm = myPlayer.getTime()
fn1 = myPlayer.getPlayingFile()
xbmc.log("current file: %s" % fn1, xbmc.LOGWARNING)
xbmc.log("current time: %g" % tm, xbmc.LOGWARNING)
myPlayer.stop()
myPlayer.play(item = playList, startpos = 0)
fn2 = myPlayer.getPlayingFile()
# fn2 = fn1
xbmc.log("    new file: %s" % fn2, xbmc.LOGWARNING)
if fn1 == fn2:
    xbmc.log("before seekTime", xbmc.LOGWARNING)
    xbmc.log("Player.getTime is now: %g" % myPlayer.getTime(), xbmc.LOGWARNING)
    xbmc.log("seek to %g" % tm, xbmc.LOGWARNING)
    myPlayer.seekTime™
    xbmc.log("Player.getTime is now: %g" % myPlayer.getTime(), xbmc.LOGWARNING)
    xbmc.log("after seekTime", xbmc.LOGWARNING)
else:
    xbmc.log("diferrent file - not seeking", xbmc.LOGWARNING)

xbmcgui.Dialog().notification(__scriptname__, "%d titles were added to the playlist" % playList.size())

https://codedocs.xyz/xbmc/xbmc/group__py...61308ebb2a

Made some minor corrections to the snippet above. frankly, this code looks more like a pseudo-code it's not really functional. You mentioned it's "part" of a greater project... perhaps you should show all work?

As is; you can only check the first position in the playlist index (0), then the script terminates. fn2 will always be Position 0...

Can you elaborate on what you are trying to achieve?
(edit)
I missed it at first... sleep(100) fixed the problem with the player not starting!

In fn2 I am checking the new head of the playlist. If this track and the seed track are the same, I attempt to skip to the last known position, this is still problematic!
Reply
#5
(2021-03-08, 22:20)splatterpop Wrote: In fn2 I am checking the new head of the playlist. If this track and the seed track are the same, I attempt to skip to the last known position, this is still problematic!

It's a matter of function, it makes the comparison once... If this is by design, so be it Smile
Image Lunatixz - Kodi / Beta repository
Image PseudoTV - Forum | Website | Youtube | Help?
Reply
#6
Hi, to let you know. I had to add another sleep(100) before the seek command in line 54 to make it work fully.
Reply

Logout Mark Read Team Forum Stats Members Help
Correct use of xbmc.Player in Python?0