Events & Communication
How plugins communicate with the engine, rules, and the parent player via events and the iframe bridge.
Overview
MP4E plugins communicate in two primary ways:
- Emit events that rules can listen to (
mp4e.emit()) - Call actions to cause behavior (
mp4e.executeActions())
Plugin → Engine Events
Use mp4e.emit(eventName, data?) to send a custom event to the parent runtime. Rules can then react to it.
Event payload
| Prop | Type | Default | Description |
|---|---|---|---|
eventName* | string | - | The event key used by rules/tracking. |
data | Record<string, any> | - | Optional JSON payload (serializable). |
1// Emit a custom event that rules can listen to2mp4e.emit('checkout:started', {3 objectId: object?.id,4 sku: object?.data?.sku,5 price: object?.data?.price,6})1// Example rule trigger (conceptual)2// When event "checkout:started" is emitted, run actions3{4 "trigger": { "type": "event", "eventName": "checkout:started" },5 "conditions": { "logic": "ALL", "conditions": [] },6 "actions": [7 { "type": "showCustomModal", "pluginId": "modal_checkout" },8 { "type": "trackEvent", "event": "checkout_started", "properties": { "sku": "{{event.data.sku}}" } }9 ]10}Video Events
Plugins can listen to video playback events to build custom controls, progress indicators, or time-synced UI. These events are dispatched to the plugin's document and contain the current video state.
timeupdate for progress bars,play/pause for button states, and volumechange for volume controls.Available Video Events
| Prop | Type | Default | Description |
|---|---|---|---|
mp4e:video:timeupdate | CustomEvent | - | Fired continuously during playback with current time, duration, volume state. |
mp4e:video:play | CustomEvent | - | Fired when video playback starts or resumes. |
mp4e:video:pause | CustomEvent | - | Fired when video playback is paused. |
mp4e:video:ended | CustomEvent | - | Fired when video playback ends. |
mp4e:video:seeking | CustomEvent | - | Fired when a seek operation begins. |
mp4e:video:seeked | CustomEvent | - | Fired when a seek operation completes. |
mp4e:video:volumechange | CustomEvent | - | Fired when volume or mute state changes. |
1// Listen to video playback events inside your plugin23// Fired continuously during playback (~60fps)4document.addEventListener('mp4e:video:timeupdate', (e) => {5 const { currentTime, duration, volume, muted } = e.detail.state;6 7 // Update progress bar8 const progress = (currentTime / duration) * 100;9 progressBar.style.width = progress + '%';10 11 // Update time display12 timeDisplay.textContent = formatTime(currentTime);13});1415// Fired when video starts playing16document.addEventListener('mp4e:video:play', () => {17 playButton.textContent = 'PAUSE';18 isPlaying = true;19});2021// Fired when video is paused22document.addEventListener('mp4e:video:pause', () => {23 playButton.textContent = 'PLAY';24 isPlaying = false;25});2627// Fired when volume changes28document.addEventListener('mp4e:video:volumechange', (e) => {29 const { volume, muted } = e.detail.state;30 volumeSlider.value = muted ? 0 : volume;31});e.detail.state with: currentTime, duration, paused, ended, volume, muted.Engine → Plugin Updates
Plugins read engine state primarily via mp4e.getVariable(), mp4e.getStats(), and time getters. Because plugins run in iframes, these calls go through a message bridge.
1// Custom plugins run inside iframes.2// The mp4e API calls cross the boundary via postMessage:3// - iframe → parent: { type: 'mp4e-api-call', method, args, id, pluginId }4// - parent → iframe: { type: 'mp4e-api-response', result, error, id, pluginId }5//6// This is why many mp4e methods are async in plugins:7const score = await mp4e.getVariable('score'){{object.data.price}} so updates stay declarative. Use scripts mainly for click handlers, emitting events, and executing actions.Overlay Click Bridge (iframes)
Custom overlays render inside iframes for isolation. To ensure clicks still trigger overlay actions (likeshowCustomModal), the iframe reports clicks to the parent runtime which then executes the overlay’s configured actions.
Event Naming Conventions
Event names are part of your MP4E “public contract”. Keep them stable and descriptive.
1// Recommended event names:2// - Use a namespace and action: "checkout:started"3// - Include a domain when relevant: "shop:cart:add"4// - Keep them stable: rules depend on these keys56mp4e.emit('quiz:answer', { choice: 'A', questionId: 'q1' })7mp4e.emit('shop:cart:add', { sku: 'WATCH-001', qty: 1 })Examples
shop:cart:add from the plugin, then use rules to increment a counter variable and show a confirmation notification.quiz:answer with the selection; rules can set variables, branch scenes, and reveal overlays.Debugging
- Use
mp4e.log()from plugin scripts for readable console logs. - In Studio preview, keep the event log open to see triggers and executed actions.
- Validate payloads: event data should be JSON-serializable.