Skip to main content

Fallback from @remotion/media to <OffthreadVideo> or <Html5Audio>

Sometimes, a media file cannot be embedded using @remotion/media's <Video> and <Audio> tags.
In such cases, a fallback to <OffthreadVideo> or <Html5Audio> from the remotion package is attempted.

When a fallback is attempted

Here are some cases where @remotion/media may fall back to <OffthreadVideo> or <Html5Audio> from remotion:

  • The resource fails to load due to CORS restrictions
  • The container format is not supported by Mediabunny
  • The codec cannot be decoded by WebCodecs (e.g. a H.265 stream during rendering)
  • The video has an alpha channel and the browser does not support WebGL which is required to decode the alpha channel. The default configuration of the headless browser does not have WebGL enabled.

Observing when a fallback happens

If @remotion/media falls back to another tag, then a warning message will be logged in the render:

Cannot decode /public/video-h265.mp4, falling back to <OffthreadVideo>

If you are rendering on an environment where the logs are not immediately visible (e.g. Lambda), observe whether a fallback has happened by visiting the logs (e.g. CloudWatch).

Preventing a fallback from happening

To prevent <Video> from falling back to <OffthreadVideo>, set the disallowFallbackToOffthreadVideo prop:

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

export const MyComp: React.FC = () => {
  return <Video src="https://remotion.media/video.mp4" disallowFallbackToOffthreadVideo />;
};

To prevent <Audio> from falling back to <Html5Audio> from remotion, set the disallowFallbackToHtml5Audio prop:

import {Audio} from '@remotion/media';

export const MyComp: React.FC = () => {
  return <Audio src="https://remotion.media/audio.mp3" disallowFallbackToHtml5Audio />;
};

If a fallback is prevented, the render will be cancelled instead.

Behavior of the loop prop during fallback

The loop prop of <Video> is handled differently depending on the environment:

During preview, the fallback uses <Html5Video>, which natively supports the loop prop. Looping works as expected.

During rendering, <OffthreadVideo> does not natively support looping. To work around this, @remotion/media attempts to determine the duration of the video and automatically wraps <OffthreadVideo> in a <Loop> component.

  • In most cases, the duration can be extracted from the media container even if the codec is not supported.
  • If the duration cannot be determined (e.g. due to CORS issues or a broken container), the render will fail with an error.

To ensure looping works reliably during rendering, make sure:

  • The video file is valid and not corrupted
  • There are no CORS issues preventing the file from being read

Fallback is not possible in client-side rendering

When using @remotion/web-renderer for client-side rendering, fallback to <OffthreadVideo> or <Html5Audio> is not possible.

This is because these fallback components require server-side capabilities that are not available in the browser.

If a media file cannot be rendered using @remotion/media during client-side rendering, the render will fail with an error message describing the issue.