<MuxVideo muxId="t00Mj7y1CLLGjaMvQyoBqcjdy4PIzVrFaT4317fKbzx00" style={{
width: '100%'
}} controls />
You can now also style a sequence if you did not pass layout="none".
A ref can be attached to <Sequence> and <AbsoluteFill>
Video and Audio support loop prop  
The <Video><Audio>loop
Preview  
New CLI output  
When starting the Remotion Preview, it now shows on which URL the preview is running. The Webpack output is now also cleaner.
Pinch to Zoom  
If your device supports multitouch, you can now pinch to zoom the composition. Alternatively, you can hold Ctrl /Cmd  and use your scrollwheel to zoom.
Using two fingers, you can move the canvas around and pressing 0  will reset the canvas. For the latter, there is also a button in the top-right corner that you can click.
<MuxVideo muxId="5I01hwK6hs7w0200Ho1KNho7rfU700UVKYDnd7FItANR32U" style={{
width: '100%'
}} controls />
Search the docs from the Remotion Preview  
Pressing ?  to reveal the keyboard shortcuts now has a secondary function: You can type in any term to search the Remotion documentation!
Shorter commands  
Previously, a Remotion CLI command looked like this:
bash
npx remotion render src/index.tsx my-comp output.mp4 
Copy bash
npx remotion render src/index.tsx my-comp output.mp4 
Copy We now allow you to skip the output name, in this case the render would land in out/my-comp.mp4 by default:
bash
npx remotion render src/index.tsx my-comp 
Copy bash
npx remotion render src/index.tsx my-comp 
Copy You can also omit the composition name and Remotion will ask which composition to render:
bash
npx remotion render src/index.tsx 
Copy bash
npx remotion render src/index.tsx 
Copy Experimental: We might change the behavior to rendering all compositions in the future.
Finally, you can also omit the entry point and Remotion will take an educated guess!
bash
Copy bash
Copy If you deviate from the defaults of our templates, you can set an entry point  in your config file and leave it out from Remotion commands.
Auto-reload environment variables  
If you change values in your .env file, the Remotion Preview will reload and pick them up without having to restart.
Signal that Remotion Preview disconnected  
When quitting the Remotion Preview using Ctrl+C, for example to render a video, A new popup will signalize that Fast Refresh will not work anymore.
<img src="/img/disconnected.png" style={{borderRadius: 5}}/>
Rendering  
--muted render This new flag can be passed to a render to ignore the audio. If you know that your video has no audio, this can make your render faster.
--enforce-audio-track When no audio was detected in your video, the audio will now be dropped (except on Lambda). With this new flag, you can enforce that a silent audio track is added.
--audio-bitrate and --video-bitrate These flags allow you to set a target bitrate for audio or video. Those flags are not recommended though, use --crf instead.
--height and --width flags Using these flags, you can ignore the width and height you have defined for your output, and override it. The difference to --scale is that the viewport and therefore the layout may actually change.
Obtain slowest frames  
If you add --log=verbose, the slowest frames are shown in order, so you can optimize them. Slowest frames are also available for renderMedia()onSlowestFrames
Negative numbers when rendering a still  
When rendering a still, you may now pass a negative frame number to refer to frames from the back of the video. -1 is the last frame of a video, -2 the second last, and so on.
Override FFmpeg command  
The FFmpeg command that Remotion executes under the hood can now be overriden reducer-style .
Server-side rendering  
Resuming renders if they crash  
If a render crashes due to being resource-intensive (see: Target closed ), Remotion will now retry each failed frame once, to prevent long renders from failing on low-resource machines.
Previously, the progress for rendering and encoding was reported individually. There is a new field, simply named progress, in the onProgress
Easier function signature for bundle()  
Previously, bundle()entryPoint, onProgress and options.
Old bundle() signature
ts
import  { bundle  }  from   "@remotion/bundler" ; 
 
bundle ( "./src/index.ts" , ( progress )  =>  console . log (progress ), { 
  publicDir : process . cwd ()  +   "/public" , 
}); 
Copy Old bundle() signature
ts
import  { bundle  }  from   "@remotion/bundler" ; 
 
bundle ( "./src/index.ts" , ( progress )  =>  console . log (progress ), { 
  publicDir : process . cwd ()  +   "/public" , 
}); 
Copy Since getting the progress was less important than some of the options, bundle() now accepts an object with options, progress callback and entryPoint altogether:
New bundle() signature
ts
import  { bundle  }  from   "@remotion/bundler" ; 
 
bundle ({ 
  entryPoint :  "./src/index.ts" , 
   onProgress : ( progress )  =>  console . log (progress ), 
  publicDir : process . cwd ()  +   "/public" , 
}); 
Copy New bundle() signature
ts
import  { bundle  }  from   "@remotion/bundler" ; 
 
bundle ({ 
  entryPoint :  "./src/index.ts" , 
   onProgress : ( progress )  =>  console . log (progress ), 
  publicDir : process . cwd ()  +   "/public" , 
}); 
Copy The previous signature is still supported.
Player  
<Thumbnail> component The new <Thumbnail><Player>
tsx
import  { Thumbnail  }  from   "@remotion/player" ; 
 
const   MyApp :   React . FC   =  ()  =>  { 
   return  ( 
    < Thumbnail 
       component = {MyComp } 
       compositionWidth = { 1920 } 
       compositionHeight = { 1080 } 
       frameToDisplay = { 30 } 
       durationInFrames = { 120 } 
       fps = { 30 } 
       style = {{ 
        width :  200 , 
      }} 
    /> 
  ); 
}; 
Copy tsx
import  { Thumbnail  }  from   "@remotion/player" ; 
 
const   MyApp :   React . FC   =  ()  =>  { 
   return  ( 
    < Thumbnail 
       component = {MyComp } 
       compositionWidth = { 1920 } 
       compositionHeight = { 1080 } 
       frameToDisplay = { 30 } 
       durationInFrames = { 120 } 
       fps = { 30 } 
       style = {{ 
        width :  200 , 
      }} 
    /> 
  ); 
}; 
Copy Player frameupdate event  
In addition to timeupdate, you can subscribe to frameupdate
Player volume slider is responsive  
If the Player is displayed in a narrow container, the volume control now goes upwards instead of to the right, in order to save some space.
Get the scale of the Player  
Using the imperative getScale()
Controls are initially shown  
On YouTube, the video always starts with controls shown and then they fade out after a few seconds. We have made this the default behavior in Remotion as well, because users would often not realize that the Player is interactive otherwise. You can control the behavior using initiallyShowControls
<video src="/img/controlsinitiallyshown.mov" style={{maxWidth: 400, width: "100%"}} autoPlay loop muted playsInline/>
Play a section of a video  
Using the inFrameoutFrame
Using renderPlayPauseButtonrenderFullscreenButton
Start player from an offset  
You can define the initialFrameinFrame prop.
New prefetch() API  
In addition to the Preload APIsprefetch()
Prefetching API
tsx
import  { prefetch  }  from   "remotion" ; 
 
const  {  free ,  waitUntilDone  }  =   prefetch ( "https://example.com/video.mp4" ); 
 
waitUntilDone (). then (()  =>  { 
  console . log ( "Video has finished loading" ); 
   free ();  // Free up memory 
}); 
Copy Prefetching API
tsx
import  { prefetch  }  from   "remotion" ; 
 
const  {  free ,  waitUntilDone  }  =   prefetch ( "https://example.com/video.mp4" ); 
 
waitUntilDone (). then (()  =>  { 
  console . log ( "Video has finished loading" ); 
   free ();  // Free up memory 
}); 
Copy Video and audio tags will automatically use the prefetched asset if it is available. See @remotion/preload vs. prefetch()
Remix template  
The Remix template is our first SaaS template! It includes the Remotion Preview, the Player and Remotion Lambda out of the box to jumpstart you with everything you need to create your app that offers customized video generation.
<Tabs
defaultValue="npm"
values={[
{ label: 'npm', value: 'npm', },
{ label: 'yarn', value: 'yarn', },
{ label: 'pnpm', value: 'pnpm', },
]
}>
bash
Copy bash
Copy 
bash
yarn create video --remix 
Copy bash
yarn create video --remix 
Copy  
  
bash
pnpm create video --remix 
Copy bash
pnpm create video --remix 
Copy  
Lambda improvements  
Webhook support  
You can now send and receive a webhook  when a Lambda render is done or has failed. Examples for Next.js and Express apps have been added and our documentation page features a way to send a test webhook.
Payload limit lifted  
Previously, the input props passed to a Lambda render could not be bigger than 256KB when serialized. Now, this limit is lifted, since if the payload is big, it will be stored to S3 instead being passed directly to the Lambda function.
Lambda artifact can be saved to another cloud  
The output videos generated by Lambda can now be saved to other S3-compatible protocols  such as DigitalOcean Spaces or Cloudflare R2.
Deleting a render from Lambda  
The new deleteRender()
The following options are now optional:
Benchmark command  
The new npx remotion benchmark
<img src="/img/benchmark.png" style={{borderRadius: 5, maxWidth: 600, width: "100%"}}/>
New guides  
We have added new guides that document interesting workflows for Remotion:
We try to avoid jargon, but we have also created a Remotion Terminology  page to define some commonly used terms. When using these terms, we will from now link to the terminology page for you to read about it.
Better structure and naming in templates  
The file that was previously called src/Video.tsx in templates is now called src/Root.tsx, because it did not contain a video, but a list of compositions. That component was also renamed from RemotionVideo to RemotionRoot. The new naming makes more sense, because that component is passed into registerRoot()
Notable improvements  
Get the duration of a GIF  
The new function getGifDurationInSeconds()
Lottie animation direction  
Using the new direction
Lottie embedded images  
Should a Lottie animation contain an embedded image, it will now be properly awaited.
Temporary directory Cleanup  
The temporary directory that Remotion creates is now completely cleaned up after every render.
Parallel encoding turned off if memory is low  
Parallel encoding  will not be used when a machine has little free RAM. You can also force-disable it using disallowParallelEncoding
Thank you  
Thank you to these contributors that implemented these awesome features:
ayatko  for implementing the @remotion/google-fonts packageAntoine Caron  for implementing the <Thumbnail> component, for reloading the page when the environment variables change and implementing negative frame indicesApoorv Kansal  for implementing the documentation search in the Quick Switcher, the benchmark command and the option to customize Play button and fullscreen button in the PlayerAkshit Tyagi  for implementing the --height and --width CLI flagsIlija Boshkov , Marcus Stenbeck  and UmungoBongo  for implementing the Motion Blur packageRavi Jain  for removing the need to pass the entry point to the CLIDhroov Makwana  for writing a tutorial on how to import assets from SplineStefan Uzunov  for implementing a composition selector if no composition is passedFlorent Pergoud  for implementing the Remix templateDerryk Boyd  for implementing the loop prop for Video and AudioPaul Kuhle  for implementing Lambda WebhooksDan Manastireau  for implementing a warning when using an Intel version of Node.JS under RosettaPompette  for making the volume slider responsiveLogan Arnett  for making the composition ID optional in the render commandPatric Salvisberg  for making the FFmpeg auto-install featureArthur Denner  for implementing the direction property for the Lottie component 
Many of these contributions came during Hacktoberfest where we put bounties on GitHub issues. We also want to thank CodeChem  for sponsoring a part of those bounties!