Skip to main content

<Video>

<Video> from @remotion/media is the recommended component for embedding videos in Remotion.

During rendering, it extracts the exact frame from the video using Mediabunny and displays it in a <canvas> tag. This keeps the video in sync with Remotion's timeline.

This component has native buffering support enabled by default. When used in the Player, it automatically pauses playback when buffering and resumes when ready.

Example​

import {staticFile} from 'remotion';
import {Video} from '@remotion/media';

export const MyVideo = () => {
  return (
    <>
      <Video src={staticFile('video.webm')} />
    </>
  );
};

You can load a video from an URL as well:

export const MyComposition = () => {
  return (
    <>
      <Video src="https://remotion.media/BigBuckBunny.mp4" />
    </>
  );
};

You can also load HLS playlists (.m3u8):

export const MyComposition = () => {
  return (
    <>
      <Video src="https://stream.mux.com/nqGuji1CJuoPoU3iprRRhiy3HXiQN0201HLyliOg44HOU.m3u8" />
    </>
  );
};

For more information on HLS support, see the HLS documentation.

Props​

src​

The URL of the video to be rendered. Can be a remote URL or a local file referenced with staticFile().

effects?v4.0.464​

Apply effects to the video frame after it has been drawn to the canvas.

cropLeft?v4.0.500​

Crops the video from the left by a ratio between 0 and 1. See cropLeft.

cropRight?v4.0.500​

Crops the video from the right by a ratio between 0 and 1. See cropRight.

cropTop?v4.0.500​

Crops the video from the top by a ratio between 0 and 1. See cropTop.

cropBottom?v4.0.500​

Crops the video from the bottom by a ratio between 0 and 1. See cropBottom.

from?v4.0.446​

At which frame this clip should start relative to the parent timeline. Default is 0. Same meaning as from on <Sequence>.

durationInFrames?v4.0.446​

Selects this many source frames starting at trimBefore. The clip occupies durationInFrames / playbackRate frames on the parent timeline, or uses this range as its loop when loop is enabled. Same meaning as durationInFrames on <Sequence>.

note

You can still wrap <Video> in an outer <Sequence>. Timing cascades like nested sequences.

Clip starting at frame 30, lasting 90 frames
import {staticFile} from 'remotion'; import {Video} from '@remotion/media'; export const MyComposition = () => { return ( <> <Video from={30} durationInFrames={90} src={staticFile('video.webm')} /> </> ); };

premountFor?v4.0.495​

Mounts the video for the specified number of frames before its from frame. The video carries display: none and is frozen at its first frame while premounted, so it does not affect layout.

Use this prop to let the video buffer before it becomes visible. See Premounting.

postmountFor?v4.0.495​

Keeps the video mounted for the specified number of frames after its duration has ended. The video is invisible and frozen at its final frame while postmounted.

styleWhilePremounted?v4.0.495​

CSS styles applied to the video while it is premounted. These styles override the default display: none and pointer-events: none styles.

styleWhilePostmounted?v4.0.495​

CSS styles applied to the video while it is postmounted. These styles override the default display: none and pointer-events: none styles.

trimBefore?​

Will remove a portion of the video at the beginning (left side).

In the following example, we assume that the fps of the composition is 30.

By passing trimBefore={60}, the playback starts immediately, but with the first 2 seconds of the video trimmed away.
By passing durationInFrames={60}, the video plays for 60 source frames.

The video will play the range from 00:02:00 to 00:04:00, meaning the video will play for 2 seconds.

For exact behavior, see Timing and trimming.

export const MyComposition = () => {
  return (
    <>
      <Video src={staticFile('video.webm')} trimBefore={60} durationInFrames={60} />
    </>
  );
};

trimAfter?​

Deprecated

Use durationInFrames instead. See PR #11685.

Removes a portion of the video at the end (right side). If durationInFrames ends the range earlier, the shorter range is used. See trimBefore for an explanation.

volume?​

Allows you to control the volume of the audio in it's entirety or frame by frame.
Read the page on using audio to learn more.

The volume prop also accepts a (frame: number) => number callback, but this is no longer recommended. Use useCurrentFrame() and interpolate() to calculate a numeric volume instead.

Setting a static volume
import {staticFile} from 'remotion'; import {Video} from '@remotion/media'; export const MyVideo = () => { return ( <> <Video volume={0.5} src={staticFile('video.webm')} /> </> ); };
Changing the volume over time
import {interpolate, staticFile, useCurrentFrame} from 'remotion'; import {Video} from '@remotion/media'; export const MyVideo = () => { const frame = useCurrentFrame(); return ( <> <Video volume={interpolate(frame, [0, 30], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'})} src={'https://remotion.media/video.mp4'} /> </> ); };

name?​

A name and that will be shown as the label of the sequence in the timeline of the Remotion Studio. This property is purely for helping you keep track of items in the timeline.

onError?v4.0.404​

Handle errors that occur during video processing. The callback receives an Error property and should return either 'fallback' or 'fail'.

  • Return 'fallback' to fall back to <OffthreadVideo> (default behavior)
  • Return 'fail' to fail the render immediately
import {staticFile} from 'remotion';
import {Video} from '@remotion/media';

export const MyVideo = () => {
  return (
    <Video
      src={'https://remotion.media/video.mp4'}
      onError={(error) => {
        console.log('Video error:', error.message);

        // Return 'fail' to fail the render, or 'fallback' to use <OffthreadVideo>
        return 'fallback';
      }}
    />
  );
};
note

playbackRate?v4.0.354​

Controls the speed of the video. 1 is the default and means regular speed, 0.5 slows down the video so it's twice as long and 2 speeds up the video so it's twice as fast.

Example of a video playing twice as fast
export const MyComposition = () => { return ( <> <Video playbackRate={2} src={'https://remotion.media/video.mp4'} /> </> ); };
note

Playing a video in reverse is not supported.

Changing playbackRate also changes the pitch of the video's audio. Pitch-preserving speed changes are not supported by the Mediabunny and WebCodecs path. If the video falls back to <OffthreadVideo> during preview or server-side rendering, audio pitch is preserved by default.

muted?​

You can drop the audio of the video by adding a muted prop:

Example of a muted video
export const MyComposition = () => { return ( <> <Video muted src="https://remotion.media/BigBuckBunny.mp4" /> </> ); };

style?​

You can pass any style you can pass to a native HTML <canvas> element.

export const MyComposition = () => {
  return (
    <>
      <Video src={staticFile('video.webm')} style={{height: 720, width: 1280}} />
    </>
  );
};

objectFit?v4.0.442​

Controls how the video content is resized to fit the canvas element, similar to the CSS object-fit property on <img> elements.

Accepts 'contain' (default), 'cover', 'fill', 'none', or 'scale-down'.

  • 'contain': The video is scaled to maintain its aspect ratio while fitting within the element's content box. Letterboxing is applied if the aspect ratios don't match.
  • 'cover': The video is sized to maintain its aspect ratio while filling the element's entire content box. The video will be clipped to fit.
  • 'fill': The video is stretched to fill the element's content box. The video's aspect ratio is not preserved.
  • 'none': The video is not resized. It is centered within the element.
  • 'scale-down': The video is sized as if none or contain were specified, whichever would result in a smaller size.
export const MyComposition = () => {
  return (
    <>
      <Video src={staticFile('video.webm')} style={{width: '100%', height: '100%'}} objectFit="cover" />
    </>
  );
};
note

The CSS property object-fit is not supported.

maxCanvasSinkFrameSize?v4.0.530​

Sets the maximum size of frames output by Mediabunny in Studio and Player previews. Pass a width, a height, or both, in pixels. Mediabunny keeps the video's aspect ratio and does not upscale it, so the actual frame size can be smaller than these limits.

For example, {width: 960} produces 960 × 540 frames from a 1920 × 1080 video. A 640 × 360 video stays at 640 × 360. Without this prop, Mediabunny outputs frames at the video's original size.

The <canvas> keeps its original dimensions and scales the frames up when drawing them. effects run at the canvas dimensions, while onVideoFrame receives the frames output by Mediabunny.

Smaller frames use less memory when a large video is shown small. The video is still decoded at full size, and rendering is not affected.

For example, use useCurrentScale() to pick a size:

Smaller frames when the preview is zoomed out
export const MyComposition = () => { const scale = useCurrentScale(); const width = scale > 0.5 ? 1920 : scale > 0.25 ? 960 : 480; return <Video src="https://remotion.media/video.mp4" maxCanvasSinkFrameSize={{width}} />; };

Changing either limit recreates the preview player, so prefer a few fixed sizes over a value that changes on every resize. Passing a new object with the same limits does not recreate it.

loop?​

Makes the video loop indefinitely.

Example of a looped video
export const MyComposition = () => { return ( <> <Video loop src="https://remotion.media/BigBuckBunny.mp4" /> </> ); };
note

When a video ends (and loop is not set), the last frame of the video remains visible by default.
This matches the behavior of <Html5Video>.

loopVolumeCurveBehavior?v4.0.354​

This prop only applies to volume callbacks, which are no longer recommended.

When loop is enabled, "repeat" (default) resets the callback frame to 0 on each iteration, while "extend" keeps it increasing across iterations.

It has no effect on numeric volume values, including volume={interpolate(frame, ...)}.

showInTimeline?​

If set to false, no layer will be shown in the timeline of the Remotion Studio. The default is true.

delayRenderTimeoutInMilliseconds?​

Customize the timeout of the delayRender() call that this component makes.

delayRenderRetries?​

Customize the number of retries of the delayRender() call that this component makes.

onVideoFrame?​

A callback function that gets called when a frame is extracted from the video.
Useful for video manipulation. The callback is called with a CanvasImageSource object, more specifically, either an ImageBitmap or a VideoFrame.

audioStreamIndex?​

Select the audio stream to use. The default is 0.

export const MyComposition = () => {
  return (
    <>
      <Video audioStreamIndex={1} src={'https://remotion.media/multiple-audio-streams.mov'} />
    </>
  );
};

credentials?v4.0.437​

Deprecated

Use requestInit instead.

Controls the credentials option of the fetch() requests made to retrieve the video data.

Accepts "omit", "same-origin" (default behavior of fetch()) or "include". Set to "include" if you need to send cookies or authentication headers to a cross-origin video URL.

export const MyComposition = () => {
  return (
    <>
      <Video requestInit={{credentials: 'include'}} src="https://example.com/protected-video.mp4" />
    </>
  );
};

requestInit?v4.0.465​

Passes RequestInit options to the fetch() requests made to retrieve the video data.

Set cache to "no-store" if a CDN or browser cache returns invalid range request responses. The value is captured when the component mounts; later updates to the prop are ignored, so passing an inline object is safe.

export const MyComposition = () => {
  return (
    <>
      <Video requestInit={{cache: 'no-store'}} src="https://remotion.media/video.mp4" />
    </>
  );
};

toneFrequency?​

Accepts a number between 0.01 and 2, where 1 represents the original pitch. Values less than 1 will decrease the pitch, while values greater than 1 will increase it.

A toneFrequency of 0.5 would lower the pitch by half, and a toneFrequency of 1.5 would increase the pitch by 50%.

The value must stay constant for each audio or video asset. Animating or keyframing toneFrequency is not supported.

Works during preview and server-side rendering. Client-side rendering is supported from v4.0.523.

If the component falls back to <OffthreadVideo> during preview, pitch shifting is not applied.

headless?v4.0.387​

Does not mount a <canvas>, but still allows you to use the onVideoFrame prop.
This is useful for embedding a video as a texture in Three.js.

fallbackOffthreadVideoProps?​

When a fallback to <OffthreadVideo> happens, this prop allows you to pass props to the fallback <OffthreadVideo> component.
Only props that are not supported by <Video> from @remotion/media need to be specified here - props that apply for both tags will automatically be forwarded and do not need to be specified here.

note

This prop has no effect when using @remotion/web-renderer for client-side rendering, as fallback is not possible. See Fallback is not possible in client-side rendering.

acceptableTimeShiftInSeconds?​

Maps to <OffthreadVideo /> -> acceptableTimeShiftInSeconds

transparent?​

Maps to <OffthreadVideo /> -> transparent

toneMapped?​

Maps to <OffthreadVideo /> -> toneMapped

onError?​

Maps to <OffthreadVideo /> -> onError

crossOrigin?​

Maps to <OffthreadVideo /> -> crossOrigin

useWebAudioApi?​

Maps to <OffthreadVideo /> -> useWebAudioApi

pauseWhenBuffering?​

Maps to <OffthreadVideo /> -> pauseWhenBuffering

onAutoPlayError?​

Maps to <OffthreadVideo /> -> onAutoPlayError

preservePitch?v4.0.463​

Maps to <OffthreadVideo /> -> preservePitch.
Only affects preview playback when falling back to <Html5Video> or <OffthreadVideo>.

disallowFallbackToOffthreadVideo?​

By default, if the video cannot be embedded using this tag, a fallback to <OffthreadVideo> will be attempted.

Pass this prop to disable the fallback and fail the render instead.

note

When using @remotion/web-renderer for client-side rendering, fallback is not possible and the render will always fail if the video cannot be embedded. See Fallback is not possible in client-side rendering.

debugOverlay?​

Shows a debug overlay on the video. This is useful for debugging the video playback.

Compatibility​

BrowsersEnvironments
Chrome
Firefox
Safari
Supported codecs

See supported media. Unsupported codecs may use a fallback during preview and server-side rendering; client-side rendering requires a decodable source and cannot fall back.

See also​