0
# Event Handling
1
2
Comprehensive event system for monitoring player state changes, handling errors, responding to user interactions, and implementing custom event-driven logic.
3
4
## Capabilities
5
6
### Event Registration
7
8
Register callbacks to handle specific types of events from the mpv player.
9
10
```python { .api }
11
def register_event_callback(self, callback):
12
"""
13
Register a callback for all mpv events.
14
15
Parameters:
16
- callback: Function that accepts MpvEvent objects
17
"""
18
19
def event_callback(self, *event_types):
20
"""
21
Decorator for registering event callbacks for specific event types.
22
23
Parameters:
24
- event_types: Event types to listen for (MpvEventID constants)
25
26
Returns:
27
Decorator function for callback registration
28
"""
29
30
def unregister_event_callback(self, callback):
31
"""
32
Remove an event callback.
33
34
Parameters:
35
- callback: Callback function to remove
36
"""
37
```
38
39
### Event Waiting
40
41
Wait for specific events with optional conditions and timeouts.
42
43
```python { .api }
44
def wait_for_event(self, *event_types, cond=lambda evt: True, timeout=None, catch_errors=True):
45
"""
46
Wait for specific event types with optional condition.
47
48
Parameters:
49
- event_types: Event types to wait for
50
- cond: Condition function that must return True for the event
51
- timeout: Maximum wait time in seconds
52
- catch_errors: Whether to catch and ignore errors
53
54
Returns:
55
The matching event object
56
"""
57
58
def prepare_and_wait_for_event(self, *event_types, cond=lambda evt: True, timeout=None, catch_errors=True):
59
"""
60
Context manager for waiting on events with preparation.
61
62
Parameters:
63
- event_types: Event types to wait for
64
- cond: Condition function for event matching
65
- timeout: Maximum wait time in seconds
66
- catch_errors: Whether to catch and ignore errors
67
68
Returns:
69
Context manager yielding Future object
70
"""
71
```
72
73
### Playback State Waiting
74
75
Convenience methods for waiting on common playback state changes.
76
77
```python { .api }
78
def wait_until_paused(self, timeout=None, catch_errors=True):
79
"""
80
Wait until playback is paused.
81
82
Parameters:
83
- timeout: Maximum wait time in seconds
84
- catch_errors: Whether to catch and ignore errors
85
"""
86
87
def wait_until_playing(self, timeout=None, catch_errors=True):
88
"""
89
Wait until playback starts.
90
91
Parameters:
92
- timeout: Maximum wait time in seconds
93
- catch_errors: Whether to catch and ignore errors
94
"""
95
96
def wait_for_playback(self, timeout=None, catch_errors=True):
97
"""
98
Wait until playback completes.
99
100
Parameters:
101
- timeout: Maximum wait time in seconds
102
- catch_errors: Whether to catch and ignore errors
103
"""
104
105
def wait_for_shutdown(self, timeout=None, catch_errors=True):
106
"""
107
Wait until mpv core shuts down.
108
109
Parameters:
110
- timeout: Maximum wait time in seconds
111
- catch_errors: Whether to catch and ignore errors
112
"""
113
```
114
115
## Event Classes
116
117
### Base Event Class
118
119
```python { .api }
120
class MpvEvent:
121
"""Base class for all mpv events."""
122
123
@property
124
def data(self):
125
"""Event-specific data payload."""
126
127
def as_dict(self, decoder=identity_decoder) -> dict:
128
"""
129
Convert event to dictionary representation.
130
131
Parameters:
132
- decoder: Function to decode byte strings
133
134
Returns:
135
Dictionary representation of event
136
"""
137
138
def __str__(self) -> str:
139
"""String representation of the event."""
140
```
141
142
### Property Change Events
143
144
```python { .api }
145
class MpvEventProperty:
146
"""Event fired when an observed property changes."""
147
148
@property
149
def name(self) -> str:
150
"""Name of the property that changed."""
151
152
@property
153
def value(self):
154
"""New value of the property (None if unavailable)."""
155
```
156
157
### Log Message Events
158
159
```python { .api }
160
class MpvEventLogMessage:
161
"""Event containing log messages from mpv."""
162
163
@property
164
def prefix(self) -> str:
165
"""Log message prefix/module name."""
166
167
@property
168
def level(self) -> str:
169
"""Log level ('fatal', 'error', 'warn', 'info', 'debug', 'trace')."""
170
171
@property
172
def text(self) -> str:
173
"""Log message text."""
174
```
175
176
### File Events
177
178
```python { .api }
179
class MpvEventStartFile:
180
"""Event fired when file loading starts."""
181
182
@property
183
def playlist_entry_id(self) -> int:
184
"""Playlist entry ID of the file being loaded."""
185
186
class MpvEventEndFile:
187
"""Event fired when file playback ends."""
188
189
@property
190
def reason(self) -> int:
191
"""Reason for file ending (see constants below)."""
192
193
@property
194
def playlist_entry_id(self) -> int:
195
"""Playlist entry ID of the file that ended."""
196
197
@property
198
def playlist_insert_id(self) -> int:
199
"""Playlist insertion ID."""
200
201
@property
202
def playlist_insert_num_entries(self) -> int:
203
"""Number of entries inserted."""
204
205
# End file reasons
206
EOF = 0 # End of file reached
207
RESTARTED = 1 # File restarted (looping)
208
ABORTED = 2 # Playback aborted
209
QUIT = 3 # Player quit
210
ERROR = 4 # Error occurred
211
REDIRECT = 5 # Redirected to different URL
212
```
213
214
### Command Events
215
216
```python { .api }
217
class MpvEventCommand:
218
"""Event containing results of asynchronous commands."""
219
220
def unpack(self, decoder=identity_decoder):
221
"""
222
Unpack command result data.
223
224
Parameters:
225
- decoder: Function to decode byte strings
226
227
Returns:
228
Command result data
229
"""
230
231
@property
232
def result(self):
233
"""Command result value."""
234
```
235
236
### Client Message Events
237
238
```python { .api }
239
class MpvEventClientMessage:
240
"""Event for script messages and IPC communication."""
241
242
@property
243
def args(self) -> list:
244
"""List of message arguments."""
245
```
246
247
### Hook Events
248
249
```python { .api }
250
class MpvEventHook:
251
"""Event for mpv hook mechanism."""
252
253
@property
254
def name(self) -> str:
255
"""Name of the hook."""
256
```
257
258
## Message Handling
259
260
Handle script messages and inter-process communication with mpv scripts and external applications.
261
262
### Message Registration
263
264
```python { .api }
265
def register_message_handler(self, target: str, handler=None):
266
"""
267
Register a message handler for specific target.
268
269
Parameters:
270
- target: Target name/identifier for message routing
271
- handler: Handler function (optional if using as decorator)
272
273
Returns:
274
Decorator function if handler not provided
275
"""
276
277
def unregister_message_handler(self, target_or_handler):
278
"""
279
Remove a message handler.
280
281
Parameters:
282
- target_or_handler: Target name or handler function to remove
283
"""
284
285
def message_handler(self, target: str):
286
"""
287
Decorator for registering message handlers.
288
289
Parameters:
290
- target: Target name for message routing
291
292
Returns:
293
Decorator function for handler registration
294
"""
295
```
296
297
### Script Messaging
298
299
Send messages to mpv scripts and external applications.
300
301
```python { .api }
302
def script_message(self, *args):
303
"""
304
Send a message to all scripts.
305
306
Parameters:
307
- args: Message arguments to broadcast to all scripts
308
"""
309
310
def script_message_to(self, target: str, *args):
311
"""
312
Send a message to a specific script or target.
313
314
Parameters:
315
- target: Target script name or identifier
316
- args: Message arguments to send to the target
317
"""
318
```
319
320
## Event Types
321
322
```python { .api }
323
class MpvEventID:
324
"""Event ID constants for different event types."""
325
326
NONE = 0
327
SHUTDOWN = 1 # Player shutdown
328
LOG_MESSAGE = 2 # Log message
329
GET_PROPERTY_REPLY = 3 # Property query response
330
SET_PROPERTY_REPLY = 4 # Property set response
331
COMMAND_REPLY = 5 # Command execution response
332
START_FILE = 6 # File loading started
333
END_FILE = 7 # File playback ended
334
FILE_LOADED = 8 # File successfully loaded
335
CLIENT_MESSAGE = 16 # Script/client message
336
VIDEO_RECONFIG = 17 # Video output reconfigured
337
AUDIO_RECONFIG = 18 # Audio output reconfigured
338
SEEK = 20 # Seek operation completed
339
PLAYBACK_RESTART = 21 # Playback restarted
340
PROPERTY_CHANGE = 22 # Property value changed
341
QUEUE_OVERFLOW = 24 # Event queue overflow
342
HOOK = 25 # Hook event
343
```
344
345
## Usage Examples
346
347
### Basic Event Handling
348
349
```python
350
import mpv
351
352
player = mpv.MPV()
353
354
# Register event callback for all events
355
def handle_all_events(event):
356
print(f"Event: {event}")
357
358
player.register_event_callback(handle_all_events)
359
360
# Register specific event callbacks using decorator
361
@player.event_callback('end-file')
362
def handle_end_file(event):
363
print(f"File ended: {event.data}")
364
365
@player.event_callback('property-change')
366
def handle_property_change(event):
367
print(f"Property {event.data.name} changed to {event.data.value}")
368
369
player.play('/path/to/video.mp4')
370
```
371
372
### Monitoring Playback State
373
374
```python
375
# Monitor playback progress
376
@player.event_callback('playback-restart')
377
def playback_started(event):
378
print("Playback started/restarted")
379
380
@player.event_callback('seek')
381
def seek_completed(event):
382
print("Seek operation completed")
383
384
# Monitor errors
385
@player.event_callback('end-file')
386
def handle_end_file(event):
387
if event.data == mpv.MpvEventEndFile.ERROR:
388
print("Playback error occurred")
389
elif event.data == mpv.MpvEventEndFile.EOF:
390
print("Playback completed normally")
391
```
392
393
### Log Message Handling
394
395
```python
396
# Custom log handler
397
@player.event_callback('log-message')
398
def handle_log(event):
399
log_msg = event.data
400
print(f"[{log_msg.level}] {log_msg.prefix}: {log_msg.text}")
401
402
# Or set log handler during initialization
403
def log_handler(loglevel, component, message):
404
print(f"[{loglevel}] {component}: {message}")
405
406
player = mpv.MPV(log_handler=log_handler, loglevel='info')
407
```
408
409
### Waiting for Events
410
411
```python
412
# Wait for file to start playing
413
player.play('/path/to/video.mp4')
414
try:
415
player.wait_until_playing(timeout=10)
416
print("Playback started successfully")
417
except TimeoutError:
418
print("Playback did not start within 10 seconds")
419
420
# Wait for specific event with condition
421
def wait_for_specific_property_change():
422
event = player.wait_for_event('property-change',
423
cond=lambda e: e.data.name == 'time-pos' and e.data.value > 30)
424
print(f"Position passed 30 seconds: {event.data.value}")
425
426
# Wait for playback to complete
427
player.wait_for_playback()
428
print("Playback finished")
429
```
430
431
### Advanced Event Handling
432
433
```python
434
# Context manager for event waiting
435
with player.prepare_and_wait_for_event('end-file') as end_file_future:
436
player.play('/path/to/video.mp4')
437
# Do other work while waiting
438
end_event = end_file_future.result(timeout=60)
439
print(f"File ended: {end_event.data}")
440
441
# Multiple event types
442
@player.event_callback('start-file', 'file-loaded', 'end-file')
443
def file_state_handler(event):
444
event_names = {
445
mpv.MpvEventID.START_FILE: "loading",
446
mpv.MpvEventID.FILE_LOADED: "loaded",
447
mpv.MpvEventID.END_FILE: "ended"
448
}
449
print(f"File {event_names.get(event.event_id, 'unknown')}")
450
451
# Event filtering and processing
452
def media_info_processor(event):
453
if event.event_id == mpv.MpvEventID.FILE_LOADED:
454
# File loaded - can now access media properties
455
print(f"Loaded: {player.filename}")
456
print(f"Duration: {player.duration}")
457
print(f"Resolution: {player.width}x{player.height}")
458
459
player.register_event_callback(media_info_processor)
460
```
461
462
### Error Handling in Events
463
464
```python
465
# Robust event handling with error catching
466
@player.event_callback('property-change')
467
def safe_property_handler(event):
468
try:
469
prop_event = event.data
470
if prop_event.name == 'time-pos' and prop_event.value is not None:
471
# Update UI or perform actions
472
update_progress_bar(prop_event.value)
473
except Exception as e:
474
print(f"Error handling property change: {e}")
475
476
# Handling event queue overflow
477
@player.event_callback('queue-overflow')
478
def handle_overflow(event):
479
print("Event queue overflow - some events may have been lost")
480
# Consider reducing event frequency or processing speed
481
```
482
483
### Custom Event Processing
484
485
```python
486
class MediaPlayerController:
487
def __init__(self):
488
self.player = mpv.MPV()
489
self.setup_event_handlers()
490
491
def setup_event_handlers(self):
492
# Bind methods as event handlers
493
self.player.register_event_callback(self.process_event)
494
495
def process_event(self, event):
496
# Route events to specific handlers
497
handlers = {
498
mpv.MpvEventID.START_FILE: self.on_file_start,
499
mpv.MpvEventID.FILE_LOADED: self.on_file_loaded,
500
mpv.MpvEventID.END_FILE: self.on_file_end,
501
mpv.MpvEventID.PROPERTY_CHANGE: self.on_property_change
502
}
503
504
handler = handlers.get(event.event_id)
505
if handler:
506
handler(event)
507
508
def on_file_start(self, event):
509
print("Starting file load...")
510
511
def on_file_loaded(self, event):
512
print("File loaded successfully")
513
514
def on_file_end(self, event):
515
print("File playback ended")
516
517
def on_property_change(self, event):
518
prop = event.data
519
print(f"Property changed: {prop.name} = {prop.value}")
520
```