Complete reference for all engine events via the onEvent prop.
Overview
MP4E Player uses a single onEvent prop to deliver all engine events. This provides a clean, unified API for integrating with analytics, syncing external UI, or building custom behaviors.
playback:timeUpdate fires frequently during playback (~60fps). For performance-sensitive operations, consider debouncing or filtering by event name early.
Use the variable:changed event to sync video state with your application. For example, update a cart UI when a "cartTotal" variable changes. Each payload includes an initiator describing what caused the change — see Event Provenance below.
Action events use the action: prefix followed by the action type (e.g. action:seek, action:setVariable). Listen for specific action types or use event.startsWith('action:') to catch all actions. Every executed action also emits after:{actionType} with the fully resolved action payload and its initiator — see Event Provenance below.
Error Events
Prop
Type
Default
Description
state:error
string | null
-
General engine error occurred.
metadata:error
{ message: string }
-
Metadata-specific error.
plugin:error
{ pluginId: string; error: string }
-
Plugin error (non-fatal).
Error events
1<MP4EPlayer
2 src="/video.mp4"
3 onEvent={(event, data) => {
4 switch (event) {
5 case 'state:error':
6 if (data) {
7 console.error('Engine error:', data);
8 errorReporter.capture({ code: 'ENGINE_ERROR', message: data });
Displays are dynamic UI elements (tooltips, product cards) that appear in response to object interactions. They differ from overlays, which are positioned on the video. A single overlay can trigger different displays based on hover vs click events.
Dialog Events
Dialog events fire when the engine presents or dismisses a dialog (alert, confirm, prompt, or custom modal).
The blob cache transitions through states: idle → downloading (with progress 0-1) → swapping → cached. If the file exceeds the size limit, the state will be skipped. Errors are reported as error.
Tracking Events
Tracking events fire when tracking visualizations (polygons, bounding boxes, mesh, corners) are shown or hidden at runtime.
Available tracking modes include polygon, bbox, corners, mesh, meshUV, amodal, and all. Tracking can target a specific object, a group, or all objects.
Event Provenance
Action and state events carry an initiator object describing what caused them — the viewer, a metadata rule (and which one), a plugin, your host application, or engine automation. It is present on after:* and action:* payloads, on variable:changed, and on scene transition events. This turns a bare “paused” into “paused by rule quiz_gate when the viewer clicked the quiz overlay” — the difference between playback logging and behavioral analytics.
What caused the action or change. user = direct viewer input (controls, key bindings, menu). rule = a metadata rule fired. plugin = a plugin API call. host = your application called a player method. init = metadata load / variable defaults. system = engine automation (timers, sequences, scene transitions).
id
string
-
The specific source when one exists: the rule ID, plugin ID, or input-binding ID.
event
string
-
For rule initiators, the event that fired the rule (e.g. overlay:click:btn-buy, control:pause).
via
string
-
Qualifier for how it happened: controls, inputBinding, menu, timer, sequence, sceneTransition, gateTimeout, emitEvent, setMetadata.
Attributing playback and state changes
1<MP4EPlayer
2 src="/video.mp4"
3 onEvent={(event, data) => {
4 // Playback attribution: was this pause the viewer, a rule, or a plugin?
5 if (event === 'after:pause') {
6 switch (data.initiator?.type) {
7 case 'user': console.log('Viewer paused'); break;
8 case 'rule': console.log('Paused by rule', data.initiator.id,
9 'on', data.initiator.event); break;
10 case 'plugin': console.log('Paused by plugin', data.initiator.id); break;
11 case 'host': console.log('Paused by your app'); break;
12 }
13 }
14 // Variable provenance: ignore initialization, keep real viewer choices
15 if (event === 'variable:changed' && data.initiator?.type !== 'init') {
16 analytics.track('choice', {
17 variable: data.variableName,
18 value: data.newValue,
19 causedBy: data.initiator?.type,
20 });
21 }
22 }}
23/>
Closed vocabulary
The initiator type is a closed enum — safe to group by in analytics dashboards. Fields that do not apply are omitted rather than null, so check with optional chaining.
Advanced
Wildcard Subscription
The onEvent prop acts as a wildcard subscriber — it receives every event emitted by the engine. The first parameter (event) contains the event name as a string, and the second parameter (data) contains the event payload. This makes it easy to forward all events to an analytics or logging system without listing individual event types.
Wildcard event subscription
1import { MP4EPlayer } from '@mp4e/react';
2
3// Subscribe to ALL events using onEvent
4<MP4EPlayer
5 src="/video.mp4"
6 onEvent={(event, data) => {
7 // 'event' contains the event name (e.g. 'playback:ready')
8 // 'data' contains the event payload
9 console.log(`[${event}]`, data);
10
11 // Forward all events to your analytics or logging system
12 analytics.track('mp4e_event', {
13 eventName: event,
14 payload: data,
15 timestamp: Date.now()
16 });
17 }}
18/>
Event Filtering
Since onEvent fires for every event, use event.startsWith() or a switch statement to filter for the categories you care about. For high-frequency events like playback:timeUpdate, consider early returns to avoid unnecessary processing.