Search Docs
Loading...
Skip to content

To MP4

Export video compositions as MP4 files on the server with H.264 encoding, progress tracking, and configurable quality settings using the native Node.js bindings.

The native Node.js bindings (@cesdk/node-native) export video entirely in-process — no browser and no separate rendering service required. Video encoding is hardware-accelerated through Apple VideoToolbox on macOS; on Linux and Windows, H.264 is encoded in software.

Export to MP4#

Use engine.block.exportVideo() to export a page of a video scene. The method returns a Blob with the encoded MP4 data. The engine drives its update loop automatically during the export.

import fs from 'fs/promises';
import CreativeEngine from '@cesdk/node-native';
const engine = await CreativeEngine.init({ license: 'YOUR_CESDK_LICENSE_KEY' });
try {
// Create a small video scene programmatically
const scene = engine.scene.createVideo();
const page = engine.block.create('page');
engine.block.appendChild(scene, page);
engine.block.setWidth(page, 1280);
engine.block.setHeight(page, 720);
engine.block.setDuration(page, 5);
const block = engine.block.create('graphic');
engine.block.setShape(block, engine.block.createShape('rect'));
const fill = engine.block.createFill('color');
engine.block.setColor(fill, 'fill/color/value', { r: 0.9, g: 0.3, b: 0.1, a: 1 });
engine.block.setFill(block, fill);
engine.block.setPosition(block, 240, 160);
engine.block.setWidth(block, 800);
engine.block.setHeight(block, 400);
engine.block.appendChild(page, block);
// Export the page as an MP4 video
const blob = await engine.block.exportVideo(page, {
mimeType: 'video/mp4',
onProgress: (renderedFrames, encodedFrames, totalFrames) => {
console.log(`Rendered ${renderedFrames}/${totalFrames} frames`);
},
});
await fs.writeFile('./output.mp4', Buffer.from(await blob.arrayBuffer()));
console.log('Export completed: output.mp4');
} finally {
engine.dispose();
}

Loading an existing video scene works the same way — load it with engine.scene.load() or engine.scene.loadFromURL(), find the page, and export it.

Set a Video Cover#

By default, MP4 exports include a cover from the page playback position when export starts. Omit coverTimeOffset or pass null to use this position. For a partial export, playback stays relative to the page timeline. A position outside the exported segment uses its first or last frame.

Set coverTimeOffset to override the default in seconds from the beginning of the exported video. It must be finite, at least 0, and less than the export duration; invalid values fail the export. For a partial export, this offset is relative to the exported segment, rather than the page timeline.

The engine embeds the exported frame containing that time as a PNG in the MP4 covr metadata. Within the exported range, a time between frame boundaries selects the earlier frame, matching playback rather than advancing to the next frame. The cover preserves the exported aspect ratio, fits within 512 × 512 pixels, and is never upscaled. Transparent areas use black, matching video playback. Displaying that cover depends on the player or file browser.

Cancel an Export#

Pass an abortSignal to stop an export whose result nobody waits for any more, for example when a job reaches its deadline. The engine stops the export at once and releases its encoders. The promise rejects, and no file is produced.

const controller = new AbortController();
const deadline = setTimeout(() => controller.abort(), 60_000);
try {
const blob = await engine.block.exportVideo(page, {
mimeType: 'video/mp4',
abortSignal: controller.signal,
});
await fs.writeFile('./output.mp4', Buffer.from(await blob.arrayBuffer()));
} catch (error) {
if (!controller.signal.aborted) {
throw error;
}
console.log('The export did not finish within one minute');
} finally {
clearTimeout(deadline);
}

Check aborted on the signal to tell a cancel from a failed export, and throw every other error again. An AbortController signals only once, so create a new one for each export.

Export Options#

Resolution and Framerate#

Use targetWidth, targetHeight, and framerate to control output dimensions and smoothness:

const blob = await engine.block.exportVideo(page, {
mimeType: 'video/mp4',
targetWidth: 1920,
targetHeight: 1080,
framerate: 30,
});

H.264 Profile and Quality#

The h264Profile option controls encoding quality and device compatibility, and videoBitrate controls file size:

const blob = await engine.block.exportVideo(page, {
mimeType: 'video/mp4',
h264Profile: 100, // High profile
videoBitrate: 8_000_000, // 8 Mbit/s
});

Choose the video codec#

The engine encodes H.264 by default. Set videoCodec to choose another codec. HEVC gives a smaller file at the same quality, but it needs a platform encoder.

Ask the engine before you set the option. Where the platform has no HEVC encoder, the export fails with an error. It does not fall back to H.264 without a word.

import { VideoCodec } from '@cesdk/node-native';
const options = { mimeType: 'video/mp4' as const, framerate: 30 };
const blob = engine.editor.getCapabilityState('hevcEncode') === 'supported'
? await engine.block.exportVideo(page, { ...options, videoCodec: VideoCodec.HEVC })
: await engine.block.exportVideo(page, options);

h264Profile and h264Level apply to H.264 only.

All MP4 Export Options#

Option Description
mimeType Output container. 'video/mp4' is the supported video export format.
targetWidth Target output width. If only one dimension is set, the other keeps the aspect ratio.
targetHeight Target output height.
framerate Target framerate in Hz, greater than 0 and at most 240. Defaults to the scene’s scene/frameRate.
h264Profile H.264 profile: 66 (Baseline), 77 (Main), 100 (High). Defaults to 77.
h264Level H.264 level. Defaults to 52.
videoCodec VideoCodec.H264 (default) or VideoCodec.HEVC.
enableHEVC Deprecated. Use videoCodec. true selects HEVC.
videoBitrate Video bitrate in bits/second, or a named automatic mode ('System', 'Auto').
audioBitrate Audio bitrate in bits/second. 0 lets the encoder choose.
timeOffset Start time in seconds for partial export. Defaults to 0.
duration Export duration in seconds. Defaults to the exported block’s duration.
onProgress Callback receiving (renderedFrames, encodedFrames, totalFrames).
abortSignal Signal that cancels the export. The engine stops it at once.

API Reference#

Method Purpose
engine.block.exportVideo() Export a page as MP4 video (returns Blob)
engine.block.exportAudio() Export the audio of a scene (WAV by default)
engine.scene.createVideo() Create a new scene in video mode
engine.block.setDuration() Set how long a block is visible on the video timeline

Next Steps#