<OffthreadVideo>
Available from Remotion 3.0.11
This component imports and displays a video, similar to <Video/>
, but during rendering, extracts the exact frame from the video and displays it in a <Img>
tag. This extraction process happens outside the browser using FFMPEG.
This component was designed to combat limitations of the default <Video>
element. See: <Video>
vs <OffthreadVideo>
.
Example
tsx
import {AbsoluteFill ,OffthreadVideo ,staticFile } from "remotion";export constMyVideo = () => {return (<AbsoluteFill ><OffthreadVideo src ={staticFile ("video.webm")} /></AbsoluteFill >);};
tsx
import {AbsoluteFill ,OffthreadVideo ,staticFile } from "remotion";export constMyVideo = () => {return (<AbsoluteFill ><OffthreadVideo src ={staticFile ("video.webm")} /></AbsoluteFill >);};
You can load a video from an URL as well:
tsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo src ="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" /></AbsoluteFill >);};
tsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo src ="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" /></AbsoluteFill >);};
Props
startFrom
Will remove a portion of the video at the beginning.
In the following example, we assume that the fps
of the composition is 30
.
By passing startFrom={60}
, the playback starts immediately, but with the first 2 seconds of the video trimmed away.
By passing endAt={120}
, any video after the 4 second mark in the file will be trimmed away.
The video will play the range from 00:02:00
to 00:04:00
, meaning the video will play for 2 seconds.
tsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo src ={staticFile ("video.webm")}startFrom ={60}endAt ={120}/></AbsoluteFill >);};
tsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo src ={staticFile ("video.webm")}startFrom ={60}endAt ={120}/></AbsoluteFill >);};
endAt
Removes a portion of the video at the end. See startAt
for an explanation.
transparent
v4.0.0
optional, boolean
If set to true
, frames will be extracted as PNG, enabling transparency but also slowing down your render.
If set to false
(default), frames will be extracted as bitmap (BMP), which is faster.
volume
Allows you to control the volume for the whole track or change it on a per-frame basis. Refer to the using audio guide to learn how to use it.
Example using static volumetsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo volume ={0.5}src ={staticFile ("video.webm")} /></AbsoluteFill >);};
Example using static volumetsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo volume ={0.5}src ={staticFile ("video.webm")} /></AbsoluteFill >);};
style
You can pass any style you can pass to a native HTML element. Keep in mind that during rendering, <OffthreadVideo>
renders an <Img>
tag, but a <video>
tag is used during preview.
tsx
export constMyComposition = () => {return (<AbsoluteFill ><Img src ={staticFile ("video.webm")}style ={{height : 720,width : 1280 }}/></AbsoluteFill >);};
tsx
export constMyComposition = () => {return (<AbsoluteFill ><Img src ={staticFile ("video.webm")}style ={{height : 720,width : 1280 }}/></AbsoluteFill >);};
allowAmplificationDuringRender
v3.3.17
Make values for volume
greater than 1
result in amplification during renders.
During Preview, the volume will be limited to 1
, since the browser cannot amplify audio.
toneFrequency
v4.0.47
Adjust the pitch of the audio - will only be applied during rendering.
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%.
onError
Handle an error playing the video. From v3.3.89, if you pass an onError
callback, then no exception will be thrown. Previously, the error could not be caught.
playbackRate
v2.2.0
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.
While Remotion doesn't limit the range of possible playback speeds, in development mode the HTMLMediaElement.playbackRate
API is used which throws errors on extreme values. At the time of writing, Google Chrome throws an exception if the playback rate is below 0.0625
or above 16
.
Example of a video playing twice as fasttsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo playbackRate ={2}src ={staticFile ("video.webm")} /></AbsoluteFill >);};
Example of a video playing twice as fasttsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo playbackRate ={2}src ={staticFile ("video.webm")} /></AbsoluteFill >);};
muted
You can drop the audio of the video by adding a muted
prop:
Example of a muted videotsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo muted src ="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"/></AbsoluteFill >);};
Example of a muted videotsx
export constMyComposition = () => {return (<AbsoluteFill ><OffthreadVideo muted src ="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"/></AbsoluteFill >);};
acceptableTimeShiftInSeconds
v3.2.42
In the Studio or in the Remotion Player, Remotion will seek the video if it gets too much out of sync with Remotion's internal time - be it due to the video loading or the page being too slow to keep up in real-time. By default, a seek is triggered if 0.45
seconds of time shift is encountered. Using this prop, you can customize the threshold.
allowAmplificationDuringRender
v3.3.17
Make values for volume
greater than 1
result in amplification during renders.
During Preview, the volume will be limited to 1
, since the browser cannot amplify audio.
toneFrequency
v4.0.47
Adjust the pitch of the audio - will only be applied during rendering.
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%.
imageFormat
v3.0.22
imageFormat
v3.0.22removed in v4.0.0
Either jpeg
or png
. Default jpeg
.
With png
, transparent videos (VP8, VP9, ProRes) can be displayed, however it is around 40% slower, with VP8 videos being much slower.
Other props
The props onError
, className
and style
are supported and get passed to the underlying HTML element. Remember that during render, this is a <img>
element, and during Preview, this is a <video>
element.
Performance tips
Only set transparent
to true
if you need transparency. It is slower than non-transparent frame extraction.
Looping a video
Unlike <Video>
, OffthreadVideo
does not currently implement the loop
property. You can use the following snippet that uses @remotion/media-utils
to loop a video.
LoopedOffthreadVideo.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";importReact , {useEffect ,useState } from "react";import {cancelRender ,continueRender ,delayRender ,Loop ,OffthreadVideo ,staticFile ,useVideoConfig ,} from "remotion";constsrc =staticFile ("myvideo.mp4");export constLoopedOffthreadVideo :React .FC = () => {const [duration ,setDuration ] =useState <null | number>(null);const [handle ] =useState (() =>delayRender ());const {fps } =useVideoConfig ();useEffect (() => {getVideoMetadata (src ).then (({durationInSeconds }) => {setDuration (durationInSeconds );continueRender (handle );}).catch ((err ) => {cancelRender (handle );console .log (err );});}, [handle ]);if (duration === null) {return null;}return (<Loop durationInFrames ={Math .floor (fps *duration )}><OffthreadVideo src ={src } /></Loop >);};
LoopedOffthreadVideo.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";importReact , {useEffect ,useState } from "react";import {cancelRender ,continueRender ,delayRender ,Loop ,OffthreadVideo ,staticFile ,useVideoConfig ,} from "remotion";constsrc =staticFile ("myvideo.mp4");export constLoopedOffthreadVideo :React .FC = () => {const [duration ,setDuration ] =useState <null | number>(null);const [handle ] =useState (() =>delayRender ());const {fps } =useVideoConfig ();useEffect (() => {getVideoMetadata (src ).then (({durationInSeconds }) => {setDuration (durationInSeconds );continueRender (handle );}).catch ((err ) => {cancelRender (handle );console .log (err );});}, [handle ]);if (duration === null) {return null;}return (<Loop durationInFrames ={Math .floor (fps *duration )}><OffthreadVideo src ={src } /></Loop >);};
Supported codecs by <OffthreadVideo>
The following codecs can be read by <OffthreadVideo>
:
- H.264 ("MP4")
- H.265 ("HEVC")
- VP8 and VP9 ("WebM")
- AV1 (from v4.0.6)
- ProRes