VLC Python EventManager callback type?
Asked Answered
C

2

16

I'm having trouble attaching an event handler to tell when a song has finished playing when using the VLC Python bindings. The event_attach function is complaining about the callback type.

def __init__(self):
    self.vlc = vlc.Instance()
    self.vlc_playlist = self.vlc.media_list_new()
    self.vlc_player = self.vlc.media_list_player_new()
    self.vlc_player.set_media_list(self.vlc_playlist)
    self.vlc_events = self.vlc_player.event_manager()
    self.vlc_events.event_attach(vlc.EventType.MediaPlayerEndReached, self.SongFinished, 1)
    ....
def SongFinished(self, *args, **kwargs):
    pass

Errors:

self.vlc_events.event_attach(vlc.EventType.MediaPlayerEndReached, self.SongFinished, 1)
return libvlc_event_attach(self, i_event_type, f_callback, user_data)
    ArgumentError: argument 3: <type 'exceptions.TypeError'>: wrong type
Cynar answered 29/8, 2010 at 16:51 Comment(1)
unfortunately I looked once and didn't see many good tutorials on the python event stuff. google.com/… might helpCompanionate
C
10

Found it, VLC.py includes a small decorator ctypes function for wrapping callbacks:

callbackmethod=ctypes.CFUNCTYPE(None, Event, ctypes.c_void_p)

To use:

@callbackmethod
def SongFinished(self, data):
    print data

.event_attach(vlc.EventType.MediaPlayerEndReached, SongFinished, 1)

Cynar answered 30/8, 2010 at 19:45 Comment(1)
Latest version of vlc.py uses a wrapper so that such decorator is not necessary anymoreMick
A
16

Here is basic code for the more recent vlc.py using the event_manager:

import vlc
import time
import sys

finish = 0

def SongFinished(event):
    global finish
    print("\nEvent reports - finished")
    finish = 1

def pos_callback(event, player):
    sec = player.get_time() / 1000
    m, s = divmod(sec, 60)
    npos = event.u.new_position * 100
    sys.stdout.write('\r%s %02d:%02d (%.2f%%)' % ('Position', m, s, npos))
    sys.stdout.flush()

instance = vlc.Instance()
player = instance.media_player_new()
media = instance.media_new_path('vp1.mp3') #Your audio file here
player.set_media(media)
events = player.event_manager()
events.event_attach(vlc.EventType.MediaPlayerEndReached, SongFinished)
events.event_attach(vlc.EventType.MediaPlayerPositionChanged, pos_callback, player)

player.play()
while finish == 0:
    time.sleep(0.5)

Note: there are quite a few events for the media player that can be monitored in this way.

MediaPlayerMediaChanged
MediaPlayerNothingSpecial
MediaPlayerOpening
MediaPlayerBuffering
MediaPlayerPlaying
MediaPlayerPaused
MediaPlayerStopped
MediaPlayerForward
MediaPlayerBackward
MediaPlayerEndReached
MediaPlayerEncounteredError
MediaPlayerTimeChanged
MediaPlayerPositionChanged
MediaPlayerSeekableChanged
MediaPlayerPausableChanged
MediaPlayerTitleChanged
MediaPlayerSnapshotTaken
MediaPlayerLengthChanged
MediaPlayerVout
MediaPlayerScrambledChanged
MediaPlayerESAdded
MediaPlayerESDeleted
MediaPlayerESSelected
MediaPlayerCorked
MediaPlayerUncorked
MediaPlayerMuted
MediaPlayerUnmuted
MediaPlayerAudioVolume
MediaPlayerAudioDevice    

For the full current list, search for class EventType in the code at
https://github.com/oaubert/python-vlc/blob/master/generated/3.0/vlc.py

Arborization answered 23/4, 2016 at 14:49 Comment(0)
C
10

Found it, VLC.py includes a small decorator ctypes function for wrapping callbacks:

callbackmethod=ctypes.CFUNCTYPE(None, Event, ctypes.c_void_p)

To use:

@callbackmethod
def SongFinished(self, data):
    print data

.event_attach(vlc.EventType.MediaPlayerEndReached, SongFinished, 1)

Cynar answered 30/8, 2010 at 19:45 Comment(1)
Latest version of vlc.py uses a wrapper so that such decorator is not necessary anymoreMick

© 2022 - 2024 — McMap. All rights reserved.