CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mpv

A python interface to the mpv media player

Pending
Overview
Eval results
Files

event-handling.mddocs/

Event Handling

Comprehensive event system for monitoring player state changes, handling errors, responding to user interactions, and implementing custom event-driven logic.

Capabilities

Event Registration

Register callbacks to handle specific types of events from the mpv player.

def register_event_callback(self, callback):
    """
    Register a callback for all mpv events.

    Parameters:
    - callback: Function that accepts MpvEvent objects
    """

def event_callback(self, *event_types):
    """
    Decorator for registering event callbacks for specific event types.

    Parameters:
    - event_types: Event types to listen for (MpvEventID constants)

    Returns:
    Decorator function for callback registration
    """

def unregister_event_callback(self, callback):
    """
    Remove an event callback.

    Parameters:
    - callback: Callback function to remove
    """

Event Waiting

Wait for specific events with optional conditions and timeouts.

def wait_for_event(self, *event_types, cond=lambda evt: True, timeout=None, catch_errors=True):
    """
    Wait for specific event types with optional condition.

    Parameters:
    - event_types: Event types to wait for
    - cond: Condition function that must return True for the event
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors

    Returns:
    The matching event object
    """

def prepare_and_wait_for_event(self, *event_types, cond=lambda evt: True, timeout=None, catch_errors=True):
    """
    Context manager for waiting on events with preparation.

    Parameters:
    - event_types: Event types to wait for
    - cond: Condition function for event matching
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors

    Returns:
    Context manager yielding Future object
    """

Playback State Waiting

Convenience methods for waiting on common playback state changes.

def wait_until_paused(self, timeout=None, catch_errors=True):
    """
    Wait until playback is paused.

    Parameters:
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors
    """

def wait_until_playing(self, timeout=None, catch_errors=True):
    """
    Wait until playback starts.

    Parameters:
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors
    """

def wait_for_playback(self, timeout=None, catch_errors=True):
    """
    Wait until playback completes.

    Parameters:
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors
    """

def wait_for_shutdown(self, timeout=None, catch_errors=True):
    """
    Wait until mpv core shuts down.

    Parameters:
    - timeout: Maximum wait time in seconds
    - catch_errors: Whether to catch and ignore errors
    """

Event Classes

Base Event Class

class MpvEvent:
    """Base class for all mpv events."""
    
    @property
    def data(self):
        """Event-specific data payload."""
    
    def as_dict(self, decoder=identity_decoder) -> dict:
        """
        Convert event to dictionary representation.

        Parameters:
        - decoder: Function to decode byte strings

        Returns:
        Dictionary representation of event
        """
    
    def __str__(self) -> str:
        """String representation of the event."""

Property Change Events

class MpvEventProperty:
    """Event fired when an observed property changes."""
    
    @property
    def name(self) -> str:
        """Name of the property that changed."""
    
    @property
    def value(self):
        """New value of the property (None if unavailable)."""

Log Message Events

class MpvEventLogMessage:
    """Event containing log messages from mpv."""
    
    @property
    def prefix(self) -> str:
        """Log message prefix/module name."""
    
    @property
    def level(self) -> str:
        """Log level ('fatal', 'error', 'warn', 'info', 'debug', 'trace')."""
    
    @property
    def text(self) -> str:
        """Log message text."""

File Events

class MpvEventStartFile:
    """Event fired when file loading starts."""
    
    @property
    def playlist_entry_id(self) -> int:
        """Playlist entry ID of the file being loaded."""

class MpvEventEndFile:
    """Event fired when file playback ends."""
    
    @property
    def reason(self) -> int:
        """Reason for file ending (see constants below)."""
        
    @property
    def playlist_entry_id(self) -> int:
        """Playlist entry ID of the file that ended."""
        
    @property
    def playlist_insert_id(self) -> int:
        """Playlist insertion ID."""
        
    @property
    def playlist_insert_num_entries(self) -> int:
        """Number of entries inserted."""
    
    # End file reasons
    EOF = 0          # End of file reached
    RESTARTED = 1    # File restarted (looping)
    ABORTED = 2      # Playback aborted
    QUIT = 3         # Player quit
    ERROR = 4        # Error occurred
    REDIRECT = 5     # Redirected to different URL

Command Events

class MpvEventCommand:
    """Event containing results of asynchronous commands."""
    
    def unpack(self, decoder=identity_decoder):
        """
        Unpack command result data.

        Parameters:
        - decoder: Function to decode byte strings

        Returns:
        Command result data
        """
    
    @property
    def result(self):
        """Command result value."""

Client Message Events

class MpvEventClientMessage:
    """Event for script messages and IPC communication."""
    
    @property
    def args(self) -> list:
        """List of message arguments."""

Hook Events

class MpvEventHook:
    """Event for mpv hook mechanism."""
    
    @property
    def name(self) -> str:
        """Name of the hook."""

Message Handling

Handle script messages and inter-process communication with mpv scripts and external applications.

Message Registration

def register_message_handler(self, target: str, handler=None):
    """
    Register a message handler for specific target.

    Parameters:
    - target: Target name/identifier for message routing
    - handler: Handler function (optional if using as decorator)

    Returns:
    Decorator function if handler not provided
    """

def unregister_message_handler(self, target_or_handler):
    """
    Remove a message handler.

    Parameters:
    - target_or_handler: Target name or handler function to remove
    """

def message_handler(self, target: str):
    """
    Decorator for registering message handlers.

    Parameters:
    - target: Target name for message routing

    Returns:
    Decorator function for handler registration
    """

Script Messaging

Send messages to mpv scripts and external applications.

def script_message(self, *args):
    """
    Send a message to all scripts.

    Parameters:
    - args: Message arguments to broadcast to all scripts
    """

def script_message_to(self, target: str, *args):
    """
    Send a message to a specific script or target.

    Parameters:
    - target: Target script name or identifier
    - args: Message arguments to send to the target
    """

Event Types

class MpvEventID:
    """Event ID constants for different event types."""
    
    NONE = 0
    SHUTDOWN = 1              # Player shutdown
    LOG_MESSAGE = 2           # Log message
    GET_PROPERTY_REPLY = 3    # Property query response
    SET_PROPERTY_REPLY = 4    # Property set response
    COMMAND_REPLY = 5         # Command execution response
    START_FILE = 6            # File loading started
    END_FILE = 7              # File playback ended
    FILE_LOADED = 8           # File successfully loaded
    CLIENT_MESSAGE = 16       # Script/client message
    VIDEO_RECONFIG = 17       # Video output reconfigured
    AUDIO_RECONFIG = 18       # Audio output reconfigured
    SEEK = 20                 # Seek operation completed
    PLAYBACK_RESTART = 21     # Playback restarted
    PROPERTY_CHANGE = 22      # Property value changed
    QUEUE_OVERFLOW = 24       # Event queue overflow
    HOOK = 25                 # Hook event

Usage Examples

Basic Event Handling

import mpv

player = mpv.MPV()

# Register event callback for all events
def handle_all_events(event):
    print(f"Event: {event}")

player.register_event_callback(handle_all_events)

# Register specific event callbacks using decorator
@player.event_callback('end-file')
def handle_end_file(event):
    print(f"File ended: {event.data}")

@player.event_callback('property-change')
def handle_property_change(event):
    print(f"Property {event.data.name} changed to {event.data.value}")

player.play('/path/to/video.mp4')

Monitoring Playback State

# Monitor playback progress
@player.event_callback('playback-restart')
def playback_started(event):
    print("Playback started/restarted")

@player.event_callback('seek')
def seek_completed(event):
    print("Seek operation completed")

# Monitor errors
@player.event_callback('end-file')
def handle_end_file(event):
    if event.data == mpv.MpvEventEndFile.ERROR:
        print("Playback error occurred")
    elif event.data == mpv.MpvEventEndFile.EOF:
        print("Playback completed normally")

Log Message Handling

# Custom log handler
@player.event_callback('log-message')
def handle_log(event):
    log_msg = event.data
    print(f"[{log_msg.level}] {log_msg.prefix}: {log_msg.text}")

# Or set log handler during initialization
def log_handler(loglevel, component, message):
    print(f"[{loglevel}] {component}: {message}")

player = mpv.MPV(log_handler=log_handler, loglevel='info')

Waiting for Events

# Wait for file to start playing
player.play('/path/to/video.mp4')
try:
    player.wait_until_playing(timeout=10)
    print("Playback started successfully")
except TimeoutError:
    print("Playback did not start within 10 seconds")

# Wait for specific event with condition
def wait_for_specific_property_change():
    event = player.wait_for_event('property-change', 
                                  cond=lambda e: e.data.name == 'time-pos' and e.data.value > 30)
    print(f"Position passed 30 seconds: {event.data.value}")

# Wait for playback to complete
player.wait_for_playback()
print("Playback finished")

Advanced Event Handling

# Context manager for event waiting
with player.prepare_and_wait_for_event('end-file') as end_file_future:
    player.play('/path/to/video.mp4')
    # Do other work while waiting
    end_event = end_file_future.result(timeout=60)
    print(f"File ended: {end_event.data}")

# Multiple event types
@player.event_callback('start-file', 'file-loaded', 'end-file')
def file_state_handler(event):
    event_names = {
        mpv.MpvEventID.START_FILE: "loading",
        mpv.MpvEventID.FILE_LOADED: "loaded", 
        mpv.MpvEventID.END_FILE: "ended"
    }
    print(f"File {event_names.get(event.event_id, 'unknown')}")

# Event filtering and processing
def media_info_processor(event):
    if event.event_id == mpv.MpvEventID.FILE_LOADED:
        # File loaded - can now access media properties
        print(f"Loaded: {player.filename}")
        print(f"Duration: {player.duration}")
        print(f"Resolution: {player.width}x{player.height}")

player.register_event_callback(media_info_processor)

Error Handling in Events

# Robust event handling with error catching
@player.event_callback('property-change')
def safe_property_handler(event):
    try:
        prop_event = event.data
        if prop_event.name == 'time-pos' and prop_event.value is not None:
            # Update UI or perform actions
            update_progress_bar(prop_event.value)
    except Exception as e:
        print(f"Error handling property change: {e}")

# Handling event queue overflow
@player.event_callback('queue-overflow') 
def handle_overflow(event):
    print("Event queue overflow - some events may have been lost")
    # Consider reducing event frequency or processing speed

Custom Event Processing

class MediaPlayerController:
    def __init__(self):
        self.player = mpv.MPV()
        self.setup_event_handlers()
    
    def setup_event_handlers(self):
        # Bind methods as event handlers
        self.player.register_event_callback(self.process_event)
    
    def process_event(self, event):
        # Route events to specific handlers
        handlers = {
            mpv.MpvEventID.START_FILE: self.on_file_start,
            mpv.MpvEventID.FILE_LOADED: self.on_file_loaded,
            mpv.MpvEventID.END_FILE: self.on_file_end,
            mpv.MpvEventID.PROPERTY_CHANGE: self.on_property_change
        }
        
        handler = handlers.get(event.event_id)
        if handler:
            handler(event)
    
    def on_file_start(self, event):
        print("Starting file load...")
    
    def on_file_loaded(self, event):
        print("File loaded successfully")
    
    def on_file_end(self, event):
        print("File playback ended")
    
    def on_property_change(self, event):
        prop = event.data
        print(f"Property changed: {prop.name} = {prop.value}")

Install with Tessl CLI

npx tessl i tessl/pypi-mpv

docs

advanced-rendering.md

core-playback.md

event-handling.md

index.md

input-keybinding.md

playlist-media.md

property-management.md

screenshots-overlays.md

streaming.md

tile.json