Troubleshooting
Common issues and solutions for MP4E integration.
Overview
This guide covers common issues encountered when integrating MP4E and their solutions.
Video Playback
Video won't play
Codec Compatibility
Ensure your video uses web-compatible codecs (H.264/AAC).
// Check video codec compatibility
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 video.mp4
// Convert to web-compatible format
ffmpeg -i input.mp4 -c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p -c:a aac output.mp4CORS Issues
Video hosted on a different domain needs proper CORS headers.
// Express.js CORS setup
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Range');
res.header('Access-Control-Expose-Headers', 'Content-Range, Content-Length');
next();
});
// Nginx CORS setup
location /videos/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'Range';
add_header 'Access-Control-Expose-Headers' 'Content-Range, Content-Length';
}Autoplay Blocked
Browsers block autoplay with sound. Use muted={true} for autoplay, or handle the play promise rejection gracefully.
Metadata Loading
Metadata not loading
1// Debug metadata loading2<MP4EPlayer3 src="/video.mp4"4 onEvent={(event, data) => {5 if (event === 'metadata:loaded') {6 // data is the document view (overrides already merged in)7 console.log('Schema version:', data.schemaVersion);8 console.log('Objects:', data.objectCount);9 console.log('Layers:', data.layers.length);10 console.log('Overlays:', data.layers.flatMap((layer) => layer.overlays).length);11 }12 if (event === 'metadata:error') {13 console.error('Metadata error:', data);14 }15 }}16/>1718// Verify embedded metadata19ffprobe -v error -show_entries format_tags=com.mp4e.data:payload -of default=noprint_wrappers=1 video.mp4Embedded Metadata Missing
Verify the video has embedded metadata using ffprobe. If missing, re-export from Studio or provide metadata via the metadata prop.
Metadata Prop Refused
If the engine cannot load the document you pass as metadata, init() rejects (the React player logs [MP4EPlayer] Init error) and the video plays as a plain video without interactivity or controls. Fix the document and pass it again — the player loads it as soon as the prop changes.
Schema Version Mismatch
Ensure metadata uses schema version 2.0. Older versions may not be compatible. Check metadata.schemaVersion.
Search card or chapters missing
An exported video carries a search card, and chapters from its analysis, only when the video was analysed and the card is switched on in the Studio. When a card is written, its title and description tags replace any the uploaded file had, and its chapters are added without changing any other track. If the uploaded file already has chapters of its own, those are kept and the analysis chapters are not added (the card still lists them). If the chapters themselves cannot be written (for example, malformed chapter data), the export still succeeds — with the card and tags, but without chapters. A file whose structure MP4E cannot read fails the export instead. Check the file with ffprobe; see Searching MP4E Videos for every placement.
# The search card (prints TAG:card={...}; nothing when the file has none)
ffprobe -v error -show_entries format_tags=card -of default=noprint_wrappers=1 video.mp4
# The chapters
ffprobe -v error -show_chapters -of compact=p=0 video.mp4Object Tracking
Objects not appearing
1// Debug object visibility2<MP4EPlayer3 src="/video.mp4"4 onEvent={(event, data) => {5 if (event === 'playback:timeUpdate') {6 const objects = playerRef.current?.getVisibleObjects();7 console.log(`Frame ${data.frame}: ${objects?.length} objects visible`);8 objects?.forEach(obj => {9 console.log(` - ${obj.id}: ${obj.label} at (${obj.position.x}, ${obj.position.y})`);10 });11 }12 if (event === 'object:visible') {13 console.log('Object entered:', data.objectId, data);14 }15 if (event === 'object:hidden') {16 console.log('Object exited:', data.objectId);17 }18 }}19/>Frame Number Mismatch
Check if the frame numbers in the timeline match the video's actual frame count. Use playerRef.current?.getTotalFrames() to verify.
Group Display Settings
Objects may be hidden by group settings. Check objectGroups[].displaySettings.showPolygon.
Coordinate System
Object coordinates are in pixels relative to the original video dimensions. Ensure your video element maintains the correct aspect ratio.
Overlays & Plugins
Overlays not showing
1// Debug overlay visibility2<MP4EPlayer3 src="/video.mp4"4 onEvent={(event, data) => {5 if (event === 'overlay:click') {6 console.log('Overlay clicked:', data.overlayId, data.overlayType);7 }8 if (event === 'plugin:error') {9 console.error('Plugin error:', data.pluginId, data.error);10 }11 }}12/>1314// Check visibility conditions15// In browser console:16const metadata = playerRef.current?.getMetadata();17const overlay = metadata.overlays.find(o => o.id === 'overlay_id');18console.log('Visibility config:', overlay.visibility);19console.log('Current time:', playerRef.current?.getCurrentTime());20console.log('Variables:', playerRef.current?.getVariables());Visibility Conditions
Check if visibility conditions are being met. Variable values and time ranges must match exactly for the overlay to show.
Attached Object Not Visible
Overlays attached to objects only show when the object is visible. Verify the attached object appears in the current frame.
Z-Index Conflicts
Overlays may be hidden behind other elements. Check zIndex values and layer ordering.
Performance
Sluggish performance
1// 1. Reduce timeline size for large videos2// Use sparse timeline (only keyframes with changes)3// Interpolate between keyframes in the player45// 2. Lazy load metadata for sections6const [loadedSections, setLoadedSections] = useState(['intro']);78onEvent={(event, data) => {9 if (event === 'playback:timeUpdate' && data.time > 60 && !loadedSections.includes('chapter1')) {10 loadMetadataSection('chapter1');11 setLoadedSections(prev => [...prev, 'chapter1']);12 }13}}1415// 3. Debounce variable updates16import { debounce } from 'lodash';1718const debouncedUpdate = debounce((name, value) => {19 playerRef.current?.setVariable(name, value);20}, 100);2122// 4. Use CSS transforms instead of position changes23// Good: transform: translate(10px, 20px)24// Bad: left: 10px; top: 20px;2526// 5. Minimize overlay re-renders27// Use React.memo for custom components28// Avoid inline function propsDebugging Tools
1// Enable debug mode2<MP4EPlayer3 src="/video.mp4"4 debug={true} // Enables visual debugging overlays5/>67// Debug mode shows:8// - Object bounding boxes and IDs9// - Overlay boundaries10// - Frame number and time11// - Variable values12// - Rule triggers1314// Console commands (when debug mode is enabled)15// Access player instance16window.__mp4e_player1718// Get current state19window.__mp4e_player.getState()2021// Inspect metadata22window.__mp4e_player.getMetadata()2324// Manually trigger actions25window.__mp4e_player.executeAction({ type: 'showNotification', message: 'Test' })2627// Check engine state28window.__mp4e_player.getEngineState()Still Having Issues?
If you can't find a solution, reach out for help: