Detecting video playback
#1
Hi,

I'm having trouble detecting the start and end of video playback and i've no idea what the issue is. I've tried a lot of different setups with gotham such as:

import xbmc
import sys;

class SuperPlayer(xbmc.Player):
def __init__(self, *args, **kwargs):
pass

def onPlayBackStarted(self):
sys.stdout.write("playback started \n");

def onPlayBackEnded(self):
sys.stdout.write("playback ended \n");

def onPlaybackStopped(self):
sys.stdout.write("playback stopped \n");

however none of them seem to hit the functions
Reply
#2
Are you instantiating the SuperPlayer?

Python doesnt use semi-colons at the end of the line.
Reply
#3
Yes in the classes that play files we have e.g.

myPlayer = SuperPlayer();
myplayer.play(file);

which works fine, I can override the play() function and the breakpoints for that get hit. It just never ever hits the onPlayback statements and it's driving me mental.

I know python doesn't require semicolons but it's good practice to always terminate your lines =)
Reply
#4
Your code above has no formatting, so I cant see the whitespace. But if the onPlayBackStarted method is accidentally outside the Class (not indented properly) then that would explain why it never gets hit.

Having a link to the full code would be helpful.
Reply
#5
Here's a pastebin of it: http://pastebin.com/pPyxgUk8

I don't think the formatting's wrong as eclipse normally warns if it is.

Could it be anything to do with python version (2.6.0) or platform (windows) or any other factors like that?
Reply
#6
Ok, figured it out.

Not sure why exactly cos i'm not sure how the underlying player code works but it's not called if the original scripts thread isn't kept alive.

Everything is that continues in my script lives in it's own thread and the original thread ends, the player class is also instanced and used in the new threads.

Adding this in the main service solves the issue:

while not xbmc.abortRequested:
xbmc.sleep(10000);

I'm happy it works but if anyone can explain why it works like this I would be interested to hear Smile
Reply
#7
(2014-07-01, 21:02)ianuk2005 Wrote: Ok, figured it out.

Not sure why exactly cos i'm not sure how the underlying player code works but it's not called if the original scripts thread isn't kept alive.

Everything is that continues in my script lives in it's own thread and the original thread ends, the player class is also instanced and used in the new threads.

Adding this in the main service solves the issue:

while not xbmc.abortRequested:
xbmc.sleep(10000);

I'm happy it works but if anyone can explain why it works like this I would be interested to hear Smile

Your pastebin looks like just a code fragment so understanding exactly how you are implementing threading isn't clear to me.
Since XBMC is running your script in it's own thread and if you are spawning new threads from that main thread, it is likely terminating all your spawned threads when it terminates your main thread.
Reply
#8
The threads are created using e.g.

thread = Thread(target = self.startTimer);
thread.start();

def startTimer(self):
time.sleep(self.updateInterval);

The main script ends after it's opened all it's threads and the created one's continue fine and do things like open video files etc in xbmc fine. It however doesn't do for example the onPlayBackStarted() call in the custom player but I have no idea why.
Reply
#9
Well, again, with fragments, I can't be of much help, however, it's common practice in service modules to do what you have done - call xbmc.sleep(). Sleeping more than 5 seconds in your main thread will likely generate a message in the log that your script didn't exit but that is more of an annoyance to others who have to look at lots of logs than a real problem. Unless you are checking for xbmc.abortrequested in your threads and terminating them and exiting from there.
Reply
#10
Out of curiosity, I verified that indeed, if your main thread terminates, any child threads that it's created also terminate.
Code:
import xbmc
import threading


class MyPlayer(xbmc.Player):

    def __init__(self):
        super(MyPlayer, self).__init__()

    def onPlayBackStarted(self):
        xbmc.log('#########Player started')


class MyThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self, name='mythread')
        self.mplayer = None

    def start(self):
        threading.Thread.start(self)

    def run(self):
        threading.Thread.run(self)
        self.mplayer = MyPlayer()
        while not xbmc.abortRequested:
            xbmc.log('###########Player still exists')
            xbmc.sleep(4000)
        self.stop()


def Main():
    mythread = MyThread()
    mythread.start()
    while not xbmc.abortRequested:   # Without these lines
        xbmc.sleep(4000)             # the child thread dies
    del mythread                     # when the parent dies

Main()

Without the commented lines above, the whole thing just dies. So even if you are listening for abort within the thread from which you have created your subclass of xbmc.Player, you need to keep your main thread alive...
Reply
#11
Check the AutoSubs addon, it detects when a video starts to call the subtitles service. So with some changes also can detect when the video stops.
Reply
#12
You could also just call mythread.join() after mythread.start() to hold up there as well...
Reply

Logout Mark Read Team Forum Stats Members Help
Detecting video playback0