Media Events
To react to the player — a file loading, a seek completing, the title changing —
override HandleMediaEvent on ModuleBase. The host decodes the underlying
FFmpeg event stream into a curated, ABI-stable MediaEvent so plugins never touch
FFmpeg or its types.
void HandleMediaEvent(const MediaEvent& e) override
{
if (e.type == MediaEventType::FileLoaded)
{
// tracks and metadata are now available
}
}
The relevant types live in <framelift/platform/IMediaPlayer.h>, included via the
<framelift/platform.h> umbrella (and transitively by <framelift/core.h>).
Event types
MediaEvent::type is a MediaEventType:
| Type | Meaning |
|---|---|
StartFile | A new file is starting to load. |
FileLoaded | The file is loaded; tracks and metadata are ready. |
PlaybackRestart | Playback resumed — fires after a seek completes. |
Seek | A seek was initiated. |
EndFile | The current file ended. e.endReason is an EndFileReason (Eof / Error / Other). |
VideoReconfig | The video resolution/format changed. |
AudioReconfig | The audio output was reconfigured. |
PropertyChange | An observed player property changed (see below). |
Other | An event the host does not surface distinctly — safe to ignore. |
None | No event pending — stop polling. |
Property changes
When type == PropertyChange, the changed property is described by
e.property. The active value is a tagged union: e.property.type says which
member of e.property.value is live.
PropertyType | Read from |
|---|---|
Flag | e.property.value.flag (int used as bool) |
Double | e.property.value.dbl |
Int64 | e.property.value.i64 |
String | e.property.value.str (NUL-terminated, copied, up to 256 bytes) |
e.property.prop is a PlayerProperty identifying which property changed
(e.g. Path, MediaTitle, HwDecCurrent, TimePos, Pause).
void HandleMediaEvent(const MediaEvent& e) override
{
if (e.type == MediaEventType::PropertyChange &&
e.property.prop == PlayerProperty::MediaTitle &&
e.property.type == PropertyType::String)
{
Log::Info("[MyPlugin] now playing: {}", e.property.value.str);
}
}
String payloads (and any const char* in an event) are valid only for the
duration of the HandleMediaEvent call. If you need to keep the value, copy it
into your own storage — do not stash the pointer. (The str union member is a
fixed-size buffer copied into the event, so reading it during the call is always
safe.)
Driving the player
HandleMediaEvent is for reacting. To command the player — load a file,
pause, seek, switch tracks — discover the media interface family with
ctx.GetService<T>():
IMediaPlayback—LoadFile,SetPause/TogglePause,Seek/SeekAbsolute, playback options.IAudioControl— mute/volume, audio track selection, output devices.ISubtitleControl— subtitle tracks, visibility, delay, styling.IMediaProperties— async property queries (GetDoubleAsync, …).
See Services.
Media events vs app events
There are two distinct event channels, and they are easy to mix up:
HandleMediaEvent(const MediaEvent&)— the player's state (this page).HandleKeyDownEvent(const AppEvent&)— platform/window input: key presses, mouse, window exposure, file drops. See Keybinds andAppEvent.
For player actions (open a file, react to a file opening across plugins) you
usually want the pub/sub events like
FileOpenedEvent, which are higher-level than the raw media stream.