Page 1 of 1

libvlc python bindings and event manager

Posted: 13 Sep 2010 16:38
by raoulg
Hi every one,

I'm using libVLC for playing RTSP stream (from IP cameras) embeded in a GTK Socket.
I have one class for the libVLC

Code: Select all

class Player(gtk.Socket): def __init__(self, id): gtk.Socket.__init__(self) def loadfile(self, filename, wid): filename=filename.replace("\"","") p=vlc.MediaPlayer(filename.strip()) p.set_xwindow(wid) p.play()
And another class to embed the video in a GTK DrawingArea:

Code: Select all

class View(gtk.DrawingArea): def __init__(self, id): gtk.DrawingArea.__init__(self) self.Screen = Player(id)
It works fin, thanks =)
Now I would like to know how to force the libVLC to re-start the stream if the network has disconnect. I've seek for a "loop" option but for what I understood, it's only avaiable on the GUI.
I've found the "Event Manager" class but I don't understand how to implement it on my program.It works fine, thanks =)
Now I would like to know how to force the libVLC for re-starting the stream if the network has disconnect. I've seek for a "loop" option but for what I understood, it's only on the GUI.
I've found the "Event Manager" class but I don't understand how to implement it on my program.
Can anyone show me some example or help me?
I'm a newbie in python and moreover in VLC :-(

Re: libvlc python bindings and event manager

Posted: 13 Sep 2010 17:04
by raoulg
So I don't know If the way I use event_attach is okay or not but with this simple code I get a Segmentation Fault:

Code: Select all

import vlc i=vlc.Instance() m=i.media_new('rtsp://root:pass@192.168.0.127/axis-media/media.amp') p=i.media_player_new() p.set_media(m) e=p.event_manager() e.event_attach(vlc.EventType.MediaPlayerEndReached, p.play(), '') p.play()
zsh: segmentation fault python

What am I doing wrong ? :=(

Thanks in advance for anyhelp!

Re: libvlc python bindings and event manager

Posted: 13 Sep 2010 21:00
by OlivierAubert
You can find an example at the end of the vlc.py module itself. The methods used as callbacks in the EventManager must be decorated with @vlc.callbackmethod. So you should define a wrapper to replay the stream:

Code: Select all

import vlc import time i=vlc.Instance() m=i.media_new('/usr/share/xine/visuals/default.avi') p=i.media_player_new() p.set_media(m) e=p.event_manager() @vlc.callbackmethod def replay(event, data): print "End callback" #p.play() will not work, see below. e.event_attach(vlc.EventType.MediaPlayerEndReached, replay, None) p.play() time.sleep(120)

Now that your callback method is properly setup, your quest is not over: the libvlc API is not reentrant within its callbacks (cf viewtopic.php?f=32&t=80305 ). You should typically have a mainloop in your application (gobject.mainloop(), or Qt mainloop), so you should instead register a method to restart the player from there, i.e. something like

Code: Select all

def restart_player(): p.play() return False # In you callback: gobject.idle_add(restart_player) # And your main app runs with gtk.main()

Re: libvlc python bindings and event manager

Posted: 14 Sep 2010 13:39
by raoulg
Hi,
Thanks for your answer.
I understand your first piece of code and that I can't callback p.play() directly inside the event_attach function.
But I'm new a PyGTK and I don't understand how to implement the gobject.idle_add() to my code.

In my case, I've got a class called "Menu" wich contains all my graphics GTK elements like GtkWindows, VBox, etc...
I have a second class wich create a GtkDrawingArea to embed the VLC stream.
And of course a "Player" for VLC.

Code: Select all

# GTK display objects like GtkWindow, VBox, etc... class Menu: def __init__(self): [...] # Simple class to create a GtkDrawingArea for embeding VLC stream class View(gtk.DrawingArea): def __init__(self, id): gtk.DrawingArea.__init__(self) self.Screen = Player(id) # My VLC class for using GTKSocket class Player(gtk.Socket): def __init__(self, id): gtk.Socket.__init__(self) def loadfile(self, filename, wid): print "name=%s|"%filename i=vlc.Instance() m=i.media_new(filename) p=i.media_player_new() p.set_media(m) e=p.event_manager() e.event_attach(vlc.EventType.MediaPlayerEndReached, restart_player, None) p.set_xwindow(wid) p.play() time.sleep(60) if __name__ == "__main__": vu = Menu() @vlc.callbackmethod def restart_player(event, data): print "end reached" print "event=%s"%event print "data=%s"%data gobject.idle_add(restart_player, None, None) gtk.main()
But with this code, the restart_player() function is call a the launch of my program and it's stuck. I don't know how I can pass my p object to my restart_player.

Re: libvlc python bindings and event manager

Posted: 15 Sep 2010 16:55
by OlivierAubert
Define restart as a method of your Player class (by having the player as an attribute of it too), and invoke it appropriately in your callback:

Code: Select all

class Player(gtk.Socket): def __init__(self): self.player = vlc.MediaPlayer() def restart(self): self.player.play() @vlc.callbackmethod def media_end(self, event, data): gobject.idle_add(self.restart) ...

Re: libvlc python bindings and event manager

Posted: 20 Sep 2010 11:22
by raoulg
Hi and thanks for your help!

I've done your modifications in my code but It still doesn't work :-(

Here my implementation of my Player class:

Code: Select all

class Player(gtk.Socket): def __init__(self, id): gtk.Socket.__init__(self) self.player = vlc.MediaPlayer() def restart(self): self.player.play() @vlc.callbackmethod def media_end(self, event, data): gobject.idle_add(self.restart()) def loadfile(self, filename, wid): print "name=%s|"%filename self.player.set_mrl(filename) self.player.set_xwindow(wid) e=self.player.event_manager() e.event_attach(vlc.EventType.MediaPlayerEndReached, media_end, None) self.player.play() #time.sleep(60) #------------------------------------------------------------------------------ #VU_Autonome = Menu() #VU_Autonome.loop() if __name__ == "__main__": vu = Menu() gtk.main()
The problem is, there is no stream playing at all!But if I remove the two lines regarding event_manager the stream plays fine. So I assume I've made a mistake again with this event_manager!
In fact it seems stuck in the e.event_attach method and never reach the play method.

Re: libvlc python bindings and event manager

Posted: 20 Sep 2010 16:39
by OlivierAubert
You have a spurious () in gobject.idle_add(self.restart()), it should be
gobject.idle_add(self.restart)
(else you try to idle_add the return value of restart).

Re: libvlc python bindings and event manager

Posted: 20 Sep 2010 17:16
by raoulg
Hi,

Thanks you, I've seen that after posted my reply.

Anyway it's still stuck at the event_attach call :(

Re: libvlc python bindings and event manager

Posted: 24 Sep 2010 11:41
by OlivierAubert
There could be a strange interaction btw VLC and gtk. The EventManager itself works, since when using the vlc.py module as an application (python vlc.py foo.avi), it correctly exits at the end of the media.