Video Clip
This guide provides a comprehensive overview of manipulating videos and exporting the final product.
Adding and Manipulating Video
Loading a Video Source
To add a video, you need a VideoClip and a VideoSource. You can create a VideoSource from a file or an external URL. Here, we will use a URL:
import { VideoSource } from '@diffusionstudio/core';
const source = await VideoSource.from('https://diffusion-studio-public.s3.eu-central-1.amazonaws.com/videos/big_buck_bunny_1080p_30fps.mp4');A VideoSource is a reusable reference that can be shared across multiple clips, optimizing memory usage.
Creating a Video Clip
Now, create a VideoClip from the VideoSource:
import { VideoClip } from '@diffusionstudio/core';
const video = new VideoClip(source, { // also accepts new File(...)
position: 'center', // ensures the clip is centered
height: '100%', // stretches the clip to the full height
width: '100%', // stretches the clip to the full width
}); Performing Video Manipulations
You can perform various manipulations on the VideoClip:
video
.offsetBy(-30) // time offset in frames (relative to current offset)
.subclip(0, 180); // trims the clip from start to end framesThis sets the video’s start time to -30 frames at 30 FPS, resulting in a 5-second visible clip (180 - 30 = 150 frames). The video is centered and scaled to fill the entire composition. Specifying either height or width maintains the aspect ratio, while setting both does not.
Adding the Clip to the Composition
Add the clip to the composition:
await composition.add(video);Alternatively, if adding multiple clips to the same track, use:
const track = composition.createTrack('video');
await track.add(video);The add method is asynchronous, ensuring the clip is fully loaded before proceeding.
Using Realtime Playback
The composition provides various realtime playback options:
composition.play(); // start playback
composition.pause(); // pause playback
composition.seek(120); // seek to a specific frame
composition.time(); // get human-readable time (e.g., 00:04 / 00:05)
composition.on('currentframe', console.log); // log frame eventsExporting the Composition
To export the composition, use the Encoder:
import { Encoder } from '@diffusionstudio/core';
const encoder = new Encoder(composition);You can customize the render settings with the second argument of the Encoder constructor. For example, to render at 4K resolution and 25 FPS:
const encoder = new Encoder(composition, { resolution: 2, fps: 25 });Export the video with the render method:
encoder.render(); // downloads the video with a default name
encoder.render('myVideo.mp4'); // specifies a filename
encoder.render('https://my-s3.com'); // uploads to a URLUsing the showSaveFilePicker API
The recommended method for client-side export is using showSaveFilePicker:
const fileHandle = await window.showSaveFilePicker({
suggestedName: 'untitled_video.mp4',
types: [
{
description: 'Video File',
accept: { 'video/mp4': ['.mp4'] },
},
],
});
await encoder.render(fileHandle);This writes the MP4 chunks directly to disk, allowing the export of large files while consuming minimal RAM.
Browser Compatibility Fallback
If showSaveFilePicker is unavailable, use this fallback snippet:
if (!('showSaveFilePicker' in window)) {
Object.assign(window, { showSaveFilePicker: async () => undefined });
}Full Example
Here is a complete example putting everything together:
import { Composition, VideoSource, VideoClip, Encoder } from '@diffusionstudio/core';
const composition = new Composition();
const player = document.getElementById('player') as HTMLDivElement;
composition.attachPlayer(player);
const source = await VideoSource.from('https://diffusion-studio-public.s3.eu-central-1.amazonaws.com/videos/big_buck_bunny_1080p_30fps.mp4');
const video = new VideoClip(source, {
position: 'center',
height: '100%',
width: '100%',
})
.offsetBy(-30)
.subclip(0, 180);
await composition.add(video);
const encoder = new Encoder(composition, { resolution: 2, fps: 25 });
await encoder.render();