Claude Academy
Sign in

Vault / wiki/401/remotion-player.md

updated 2026-07-16

The Remotion Player

@remotion/player embeds a Remotion composition as a real-time, in-browser playback surface inside any React app. The defining property: it renders nothing to a file — frames are evaluated live in the visitor's browser, so playback has zero render cost, zero encode latency, and zero storage. That makes it the right primitive for personalized and interactive explainers — which is exactly what this site uses it for (see how-this-site-works).

Minimal usage

import { Player } from "@remotion/player";
import { Explainer } from "./Explainer";

<Player
  component={Explainer}          // or lazyComponent for code-splitting
  durationInFrames={300}
  compositionWidth={1920}
  compositionHeight={1080}
  fps={30}
  // optional:
  controls
  autoPlay
  loop
  inputProps={{ topic: "prompt caching", userName: "Chris" }}
  style={{ width: "100%" }}
/>

Required props: component (or lazyComponent), durationInFrames, compositionWidth, compositionHeight, fps. Note the Player takes sizing/timing metadata directly — there's no <Composition> registration in the browser; the Player is the composition host.

Common optional props: controls (playback UI), autoPlay, loop, inputProps (data into the component), style (the player scales the composition to fit its styled box).

Imperative control with PlayerRef

import type { PlayerRef } from "@remotion/player";

const ref = useRef<PlayerRef>(null);

ref.current?.play();
ref.current?.pause();
ref.current?.toggle();
ref.current?.seekTo(120);              // jump to frame 120
const f = ref.current?.getCurrentFrame();

This API is what makes explainers interactive: sync the video to scroll position, build chaptered lessons (seekTo on section click), pause at a quiz checkpoint and resume on a correct answer (quiz-me loop meets video).

Player vs render — the canonical architecture

<Player>renderMedia / Lambda
Outputlive DOM playbackMP4/WebM file
Cost per viewzero (client CPU)compute per render
Personalizationfree — pass new inputPropsnew render per variant
Shareable filenoyes

The canonical product shape: the same component is previewed in the Player and rendered to MP4 on Lambda when a file is actually needed (download, social share). inputProps flow identically through the Player, the CLI, and the SSR rendering APIs — one component, one props contract, three delivery modes. Personalization becomes a data problem, not a video-production problem: inputProps={{ userName, weakestTopics }} gives every learner a different video with no render farm.

When the Player is the wrong tool

  • You need a file (email attachment, social upload) → server render (remotion-fundamentals).
  • The composition is too heavy to evaluate at 30/60 fps on client devices — the Player evaluates React in real time, so janky components mean janky playback. Pre-render those.

Key terms

  • @remotion/player — the package providing <Player>, real-time in-browser playback of a Remotion composition inside any React app, with no file output and zero render cost.
  • Required Player props — component (or lazyComponent), durationInFrames, compositionWidth, compositionHeight, fps; the Player hosts the composition directly instead of a <Composition> registration.
  • inputProps — the data payload passed into the composition component; flows identically through Player, CLI, and SSR render APIs, making personalization a props problem.
  • PlayerRef — the imperative handle exposing play(), pause(), toggle(), seekTo(frame), and getCurrentFrame() for app-driven control.
  • lazyComponent — code-splitting alternative to component, loading the composition bundle on demand.
  • Preview/render duality — the canonical architecture where one component serves both live Player playback and Lambda MP4 rendering.
  • Zero render cost — the Player's economic property: playback consumes only the viewer's client CPU, no server rendering or storage.

See also