remotion-dev/remotion · error · TypeError
Expected Player event emitter context
Error message
Expected Player event emitter context
What it means
usePlayerMethods retrieves the Player event emitter from PlayerEventEmitterContext; this context is only provided inside @remotion/player's <Player>. If the hook runs without a provider, emitter is undefined and a TypeError is thrown telling you the Player event emitter context is missing.
Source
Thrown at packages/player/src/use-player-methods.ts:43
const {
setPlaying,
frameRef,
audioAndVideoTags,
isPlaying: readIsPlaying,
isBuffering,
} = useContext(Internals.SetTimelineContext);
const audioContext = useContext(Internals.SharedAudioContext);
const audioTagsContext = useContext(Internals.SharedAudioTagsContext);
const environment = useRemotionEnvironment();
const video = Internals.useVideo();
const config = Internals.useUnsafeVideoConfig();
const emitter = useContext(PlayerEventEmitterContext);
const playStart = useRef(0);
const fallbackFrame = useRef<number | null>(null);
const nextPlayIsAutoPlayAttempt = useRef(false);
if (!emitter) {
throw new TypeError('Expected Player event emitter context');
}
const getCurrentFrame = useCallback(() => {
if (!video) {
return (
fallbackFrame.current ??
(typeof window === 'undefined'
? 0
: (window.remotion_initialFrame ?? 0))
);
}
const unclamped =
frameRef.current[video.id] ??
(environment.isPlayer
? 0
: Internals.Timeline.getFrameForComposition(video.id));
View on GitHub (pinned to a6a7485a9a)
Solutions
- Render the component inside a <Player> from @remotion/player
- Move play/pause/seek logic into components within the Player's React tree
- Use useVideoPlayerContext only under Player; for studio/CLI rendering, gate player hooks behind an is-player check
- Align @remotion/player and @remotion/core versions so context modules match
Example fix
// before
const controls = usePlayer(); // rendered outside <Player>
// after
<Player component={MyVideo} ...>
<PlayerControls/> {/* inside Player tree, context provided */}
</Player> Defensive patterns
Strategy: type-guard
Validate before calling
// Only mount player-control components under <Player> if (!insidePlayerTree) return <StaticControls/>;
Type guard
const hasPlayerEmitter = (e: PlayerEventEmitter | undefined): e is PlayerEventEmitter => e !== undefined && typeof e.addEventListener === 'function';
Try / catch
try {
const controls = usePlayerMethods(video);
} catch (e) {
if (e instanceof TypeError && e.message.includes('Player event emitter context')) {
// render non-player fallback controls
} else throw e;
} Prevention
- Call usePlayerMethods/usePlayer only in components inside <Player>
- Keep @remotion/player and @remotion/core versions aligned
- Do not share player-control components between Player and studio/CLI renders without gating
- Structure the tree so controls are children of Player
When it happens
Trigger: Calling usePlayerMethods (or hooks building on it, like usePlayer) in a component rendered outside a <Player> from @remotion/player — e.g. inside a plain Remotion composition render, a Storybook story, or a test without the provider.
Common situations: Using player-only hooks (play/pause/seek) inside compositions rendered by the Remotion CLI/studio renderer instead of inside a <Player>; missing @remotion/player version alignment so the context object differs; rendering controls outside the Player tree.
Related errors
- useLogLevel must be used within a LogLevelProvider
- useMountTime must be used within a LogLevelProvider
- useCurrentFrame can only be called inside a component that w
- useCurrentScale() was called outside of a Remotion context.
- TimelineContext is not available. This hook must be used ins
AI-assisted analysis of remotion-dev/remotion@a6a7485a9a (2026-09-02).
Data as JSON: /api/errors/9adfe149af735c91.
Report an issue: GitHub.