Diffusion Studio
Rendering

Client-Side

Rendering videos on the client side is made highly efficient by utilizing WebCodecs, a modern browser API that supports hardware-accelerated encoding. This allows for fast and optimized video processing directly in the browser.

Setup

To begin, you'll need a Composition to render. Below is an example of setting up an empty Composition for demonstration purposes:

import { Composition } from '@diffusionstudio/core';
 
const composition = new Composition();

Next, create an encoder using the Composition:

import { Encoder } from '@diffusionstudio/core';
 
const encoder = new Encoder(composition);

Configuring the Encoder

The encoder can be customized via its second argument, which allows you to configure various output settings. The default configuration is as follows:

{
  resolution: 1,        // Scales the dimensions of the output.
  sampleRate: 48000,    // Defines the audio sample rate; higher values improve audio quality.
  numberOfChannels: 2,  // Specifies the number of audio channels.
  videoBitrate: 10e6,   // Sets the video bitrate; higher values yield better quality.
  gpuBatchSize: 5,      // Defines the workload for the GPU.
  fps: 30,              // Sets the output frame rate.
  debug: false,         // Enables logging of rendering performance.
}

For example, to produce a 4K video at 60 FPS from a default 1080p Composition, you can configure the encoder like this:

const encoder = new Encoder(composition, {
  fps: 60,
  resolution: 2,
});

Rendering the Video

To start exporting the video, use the render method, which accepts a render target as an argument. The recommended approach is to use the showSaveFilePicker API:

const fileHandle = await window.showSaveFilePicker({
  suggestedName: 'untitled_video.mp4',
  types: [
    {
      description: 'Video File',
      accept: { 'video/mp4': ['.mp4'] },
    },
  ],
});
 
await encoder.render(fileHandle);

This approach writes the MP4 chunks directly to disk as they are generated, allowing you to render videos that exceed your available RAM. However, note that browser support for showSaveFilePicker is currently limited. In such cases, other export targets can be used:

await encoder.render();                         // Downloads the result with a default name.
await encoder.render('myVideo.mp4');            // Downloads the result with a specified name.
await encoder.render('https://my.s3.com/path'); // Uploads the result to the specified URL.

To ensure compatibility across browsers, you can provide a fallback for showSaveFilePicker:

if (!('showSaveFilePicker' in window)) {
  Object.assign(window, { showSaveFilePicker: async () => undefined });
}

This fallback ensures that the export process continues seamlessly even if showSaveFilePicker is not available.

Aborting the export

This feature was implemented utilizing the AbortController Web API. You can simply pass in the abort signal as the second argument of the render method:

const controller = new AbortController();
 
encoder.render(fileHandle, controller.signal);
 
controller.abort();

On this page