VLC bindings for Python providing comprehensive multimedia functionality through LibVLC API.
—
Comprehensive event handling system for responding to media state changes, playback events, and user interactions. The event system enables building responsive media applications that react to VLC's internal state changes.
The EventManager class provides the core event handling mechanism for attaching and detaching event callbacks.
class EventManager:
def event_attach(self, event_type, callback, user_data=None):
"""Attach an event callback.
Args:
event_type (EventType): Type of event to listen for
callback (function): Function to call when event occurs
user_data: Optional user data passed to callback
"""
...
def event_detach(self, event_type):
"""Detach an event callback.
Args:
event_type (EventType): Type of event to stop listening for
"""
...Event types related to media player state and playback changes.
class EventType:
# Media Player Events
MediaPlayerMediaChanged = 0x100
MediaPlayerNothingSpecial = 0x101
MediaPlayerOpening = 0x102
MediaPlayerBuffering = 0x103
MediaPlayerPlaying = 0x104
MediaPlayerPaused = 0x105
MediaPlayerStopped = 0x106
MediaPlayerForward = 0x107
MediaPlayerBackward = 0x108
MediaPlayerEndReached = 0x109
MediaPlayerEncounteredError = 0x10a
MediaPlayerTimeChanged = 0x10b
MediaPlayerPositionChanged = 0x10c
MediaPlayerSeekableChanged = 0x10d
MediaPlayerPausableChanged = 0x10e
MediaPlayerTitleChanged = 0x10f
MediaPlayerSnapshotTaken = 0x110
MediaPlayerLengthChanged = 0x111
MediaPlayerVout = 0x112
MediaPlayerScrambledChanged = 0x113
MediaPlayerESAdded = 0x114
MediaPlayerESDeleted = 0x115
MediaPlayerESSelected = 0x116
MediaPlayerCorked = 0x117
MediaPlayerUncorked = 0x118
MediaPlayerMuted = 0x119
MediaPlayerUnmuted = 0x11a
MediaPlayerAudioVolume = 0x11b
MediaPlayerAudioDevice = 0x11c
MediaPlayerChapterChanged = 0x11dEvent types related to media object changes and parsing.
class EventType:
# Media Events
MediaMetaChanged = 0x000
MediaSubItemAdded = 0x001
MediaDurationChanged = 0x002
MediaParsedChanged = 0x003
MediaFreed = 0x004
MediaStateChanged = 0x005
MediaSubItemTreeAdded = 0x006
MediaThumbnailGenerated = 0x007
MediaAttachedThumbnailsFound = 0x008Event types for media list operations and changes.
class EventType:
# Media List Events
MediaListItemAdded = 0x200
MediaListWillAddItem = 0x201
MediaListItemDeleted = 0x202
MediaListWillDeleteItem = 0x203
MediaListEndReached = 0x204Event types for media list player operations.
class EventType:
# Media List Player Events
MediaListPlayerPlayed = 0x400
MediaListPlayerNextItemSet = 0x401
MediaListPlayerStopped = 0x402Event types for media discovery operations.
class EventType:
# Media Discoverer Events
MediaDiscovererStarted = 0x500
MediaDiscovererEnded = 0x501Event types for VLC instance-level operations.
class EventType:
# VLC Instance Events
VlmMediaAdded = 0x600
VlmMediaRemoved = 0x601
VlmMediaChanged = 0x602
VlmMediaInstanceStarted = 0x603
VlmMediaInstanceStopped = 0x604
VlmMediaInstanceStatusInit = 0x605
VlmMediaInstanceStatusOpening = 0x606
VlmMediaInstanceStatusPlaying = 0x607
VlmMediaInstanceStatusPause = 0x608
VlmMediaInstanceStatusEnd = 0x609
VlmMediaInstanceStatusError = 0x60aEvent types for renderer discovery operations.
class EventType:
# Renderer Discoverer Events
RendererDiscovererItemAdded = 0x700
RendererDiscovererItemDeleted = 0x701Data structures that provide event-specific information in callbacks.
class Event:
"""Base event structure."""
def __init__(self):
self.type = None
self.obj = None
self.u = None # Union of event-specific data
class MediaEvent:
"""Media-specific event data."""
def __init__(self):
self.meta_type = None
self.new_child = None
self.new_duration = None
self.new_status = None
self.new_state = None
class MediaPlayerEvent:
"""Media player-specific event data."""
def __init__(self):
self.new_media = None
self.new_cache = None
self.new_position = None
self.new_time = None
self.new_title = None
self.new_seekable = None
self.new_pausable = None
self.new_scrambled = None
self.new_count = None
self.volume = None
self.device = None
self.new_chapter = None
class MediaListEvent:
"""Media list-specific event data."""
def __init__(self):
self.item = None
self.index = None
class MediaDiscovererEvent:
"""Media discoverer-specific event data."""
def __init__(self):
self.media = None
class RendererDiscovererEvent:
"""Renderer discoverer-specific event data."""
def __init__(self):
self.item = Noneimport vlc
import time
def on_media_state_changed(event):
"""Callback for media state changes."""
print(f"Media state changed to: {event.u.new_state}")
def on_player_time_changed(event):
"""Callback for playback time changes."""
print(f"Playback time: {event.u.new_time}ms")
def on_player_position_changed(event):
"""Callback for playback position changes."""
print(f"Playback position: {event.u.new_position:.2%}")
# Create player and media
player = vlc.MediaPlayer('/path/to/video.mp4')
media = player.get_media()
# Attach media events
if media:
media_em = media.event_manager()
media_em.event_attach(vlc.EventType.MediaStateChanged, on_media_state_changed)
# Attach player events
player_em = player.event_manager()
player_em.event_attach(vlc.EventType.MediaPlayerTimeChanged, on_player_time_changed)
player_em.event_attach(vlc.EventType.MediaPlayerPositionChanged, on_player_position_changed)
# Start playback and let events fire
player.play()
time.sleep(10)
player.stop()import vlc
import time
class PlayerEventHandler:
def on_nothing_special(self, event):
print("Player state: Nothing special")
def on_opening(self, event):
print("Player state: Opening media")
def on_buffering(self, event):
cache = event.u.new_cache
print(f"Player state: Buffering ({cache}%)")
def on_playing(self, event):
print("Player state: Playing")
def on_paused(self, event):
print("Player state: Paused")
def on_stopped(self, event):
print("Player state: Stopped")
def on_end_reached(self, event):
print("Player state: End reached")
def on_error(self, event):
print("Player state: Error encountered")
def on_media_changed(self, event):
print("Media changed")
def on_length_changed(self, event):
length = event.u.new_length
print(f"Media length: {length}ms")
def on_seekable_changed(self, event):
seekable = event.u.new_seekable
print(f"Seekable: {seekable}")
def on_pausable_changed(self, event):
pausable = event.u.new_pausable
print(f"Pausable: {pausable}")
# Create handler and player
handler = PlayerEventHandler()
player = vlc.MediaPlayer('/path/to/video.mp4')
em = player.event_manager()
# Attach all events
event_handlers = {
vlc.EventType.MediaPlayerNothingSpecial: handler.on_nothing_special,
vlc.EventType.MediaPlayerOpening: handler.on_opening,
vlc.EventType.MediaPlayerBuffering: handler.on_buffering,
vlc.EventType.MediaPlayerPlaying: handler.on_playing,
vlc.EventType.MediaPlayerPaused: handler.on_paused,
vlc.EventType.MediaPlayerStopped: handler.on_stopped,
vlc.EventType.MediaPlayerEndReached: handler.on_end_reached,
vlc.EventType.MediaPlayerEncounteredError: handler.on_error,
vlc.EventType.MediaPlayerMediaChanged: handler.on_media_changed,
vlc.EventType.MediaPlayerLengthChanged: handler.on_length_changed,
vlc.EventType.MediaPlayerSeekableChanged: handler.on_seekable_changed,
vlc.EventType.MediaPlayerPausableChanged: handler.on_pausable_changed,
}
for event_type, callback in event_handlers.items():
em.event_attach(event_type, callback)
# Test playback with events
player.play()
time.sleep(5)
player.pause()
time.sleep(2)
player.play()
time.sleep(5)
player.stop()import vlc
import time
def on_meta_changed(event):
"""Handle metadata changes."""
meta_type = event.u.meta_type
print(f"Metadata changed: type {meta_type}")
def on_parsed_changed(event):
"""Handle parsing status changes."""
status = event.u.new_status
print(f"Parse status changed: {status}")
def on_duration_changed(event):
"""Handle duration changes."""
duration = event.u.new_duration
print(f"Duration changed: {duration}ms")
# Create media and attach events
media = vlc.Media('/path/to/video.mp4')
em = media.event_manager()
em.event_attach(vlc.EventType.MediaMetaChanged, on_meta_changed)
em.event_attach(vlc.EventType.MediaParsedChanged, on_parsed_changed)
em.event_attach(vlc.EventType.MediaDurationChanged, on_duration_changed)
# Start parsing (triggers events)
print("Starting media parsing...")
media.parse_async()
# Wait for parsing to complete
time.sleep(3)
# Get parsed metadata
title = media.get_meta(vlc.Meta.Title)
duration = media.get_duration()
print(f"Title: {title}")
print(f"Duration: {duration}ms")import vlc
import time
def on_es_added(event):
"""Handle elementary stream (track) added."""
print("New elementary stream added")
def on_es_deleted(event):
"""Handle elementary stream (track) deleted."""
print("Elementary stream deleted")
def on_es_selected(event):
"""Handle elementary stream (track) selected."""
print("Elementary stream selected")
def on_audio_volume(event):
"""Handle audio volume changes."""
volume = event.u.volume
print(f"Audio volume changed: {volume}")
def on_audio_device(event):
"""Handle audio device changes."""
device = event.u.device
print(f"Audio device changed: {device}")
# Create player with track events
player = vlc.MediaPlayer('/path/to/multilingual_video.mkv')
em = player.event_manager()
# Attach track and audio events
em.event_attach(vlc.EventType.MediaPlayerESAdded, on_es_added)
em.event_attach(vlc.EventType.MediaPlayerESDeleted, on_es_deleted)
em.event_attach(vlc.EventType.MediaPlayerESSelected, on_es_selected)
em.event_attach(vlc.EventType.MediaPlayerAudioVolume, on_audio_volume)
em.event_attach(vlc.EventType.MediaPlayerAudioDevice, on_audio_device)
# Start playbook and test track changes
player.play()
time.sleep(2)
# Change volume (triggers event)
player.audio_set_volume(75)
# Change audio track if available (triggers events)
track_count = player.audio_get_track_count()
if track_count > 1:
player.audio_set_track(1)
time.sleep(5)
player.stop()import vlc
import time
def on_item_added(event):
"""Handle media list item added."""
item = event.u.item
index = event.u.index
print(f"Item added at index {index}: {item.get_mrl()}")
def on_will_add_item(event):
"""Handle media list will add item."""
item = event.u.item
index = event.u.index
print(f"Will add item at index {index}")
def on_item_deleted(event):
"""Handle media list item deleted."""
item = event.u.item
index = event.u.index
print(f"Item deleted from index {index}")
def on_end_reached(event):
"""Handle media list end reached."""
print("End of media list reached")
# Create media list with events
instance = vlc.Instance()
media_list = instance.media_list_new()
em = media_list.event_manager()
# Attach media list events
em.event_attach(vlc.EventType.MediaListItemAdded, on_item_added)
em.event_attach(vlc.EventType.MediaListWillAddItem, on_will_add_item)
em.event_attach(vlc.EventType.MediaListItemDeleted, on_item_deleted)
em.event_attach(vlc.EventType.MediaListEndReached, on_end_reached)
# Add items (triggers events)
media1 = instance.media_new('/path/to/song1.mp3')
media2 = instance.media_new('/path/to/song2.mp3')
print("Adding media items...")
media_list.add_media(media1)
media_list.add_media(media2)
time.sleep(1)
# Remove item (triggers events)
print("Removing media item...")
media_list.remove_index(0)
time.sleep(1)import vlc
import time
def temp_callback(event):
print("Temporary callback triggered")
# Create player and attach event
player = vlc.MediaPlayer('/path/to/video.mp4')
em = player.event_manager()
# Attach event
em.event_attach(vlc.EventType.MediaPlayerPlaying, temp_callback)
# Start playback (triggers event)
player.play()
time.sleep(2)
# Detach event
print("Detaching event...")
em.event_detach(vlc.EventType.MediaPlayerPlaying)
# Pause and resume (no longer triggers callback)
player.pause()
time.sleep(1)
player.play() # Won't trigger temp_callback anymore
time.sleep(2)
player.stop()import vlc
import time
class MediaPlayerMonitor:
def __init__(self, player):
self.player = player
self.event_manager = player.event_manager()
self.setup_events()
def setup_events(self):
"""Setup all event handlers."""
events = {
vlc.EventType.MediaPlayerPlaying: self.on_playing,
vlc.EventType.MediaPlayerPaused: self.on_paused,
vlc.EventType.MediaPlayerStopped: self.on_stopped,
vlc.EventType.MediaPlayerEndReached: self.on_ended,
vlc.EventType.MediaPlayerTimeChanged: self.on_time_changed,
vlc.EventType.MediaPlayerPositionChanged: self.on_position_changed,
vlc.EventType.MediaPlayerEncounteredError: self.on_error,
vlc.EventType.MediaPlayerBuffering: self.on_buffering,
}
for event_type, handler in events.items():
self.event_manager.event_attach(event_type, handler)
def on_playing(self, event):
print("▶️ Playing")
def on_paused(self, event):
print("⏸️ Paused")
def on_stopped(self, event):
print("⏹️ Stopped")
def on_ended(self, event):
print("🏁 Playback ended")
def on_time_changed(self, event):
time_ms = event.u.new_time
minutes = time_ms // 60000
seconds = (time_ms % 60000) // 1000
print(f"⏰ Time: {minutes:02d}:{seconds:02d}")
def on_position_changed(self, event):
position = event.u.new_position
print(f"📍 Position: {position:.1%}")
def on_error(self, event):
print("❌ Playback error occurred")
def on_buffering(self, event):
cache = event.u.new_cache
print(f"📶 Buffering: {cache}%")
def cleanup(self):
"""Detach all events."""
events = [
vlc.EventType.MediaPlayerPlaying,
vlc.EventType.MediaPlayerPaused,
vlc.EventType.MediaPlayerStopped,
vlc.EventType.MediaPlayerEndReached,
vlc.EventType.MediaPlayerTimeChanged,
vlc.EventType.MediaPlayerPositionChanged,
vlc.EventType.MediaPlayerEncounteredError,
vlc.EventType.MediaPlayerBuffering,
]
for event_type in events:
self.event_manager.event_detach(event_type)
# Usage
player = vlc.MediaPlayer('/path/to/video.mp4')
monitor = MediaPlayerMonitor(player)
# Test playback with comprehensive monitoring
player.play()
time.sleep(10)
player.pause()
time.sleep(2)
player.play()
time.sleep(5)
player.stop()
# Cleanup when done
monitor.cleanup()Install with Tessl CLI
npx tessl i tessl/pypi-python-vlc