Skip to content
Apexify.jsDocs
Apexify.js version v5.4.5

Node / Video Ffmpeg · guide

Frame extraction & previews

Current Apexify.js 6.0.0 documentation for Frame extraction & previews.

apexify.jsRuntime: nodeCURRENTSince 6.0.0

Same jobs without createVideo: Imperative video helpers (getVideoInfo, extractFrameAtTime, extractFrameByNumber, …).


extractFrame

What it does: Decodes one image from the video at a chosen time or frame index, optionally scales it.

Options explained

FieldEffect
timeSeek to this second before grabbing (most intuitive). If set, it drives extraction; frame is ignored for positioning.
frameIndex (0 = start). Converted to time with frame / fps when time is omitted (fps from probe or assumed 30).
width, heightResize on a canvas after decode. Omit = native resolution.
outputFormatjpg or png for the intermediate FFmpeg output.
qualityJPEG -q:v (lower = better quality, typical 2–5). PNG path ignores quality in practice.

Return value: createVideo wraps the bitmap in a PNG buffer plus canvas: { width, height } (VideoCreator), even if you asked jpg internally.

Example — poster at 10s

SOURCEtypescript
typescript
Studio
import fs from 'fs'; const poster = await painter.createVideo({  source: './film.mp4',  extractFrame: {    time: 10,    width: 1920,    height: 1080,    outputFormat: 'jpg',    quality: 3,  },}); fs.writeFileSync('poster.png', poster.buffer);

extractFrames — mode A: times

What it does: Calls extractVideoFrame once per timestamp → Buffer[] in order.

FieldEffect
timesArray of seconds.
outputFormat, qualitySame semantics as extractFrame.
SOURCEtypescript
typescript
Studio
import fs from 'fs'; const stills = await painter.createVideo({  source: './clip.mp4',  extractFrames: {    times: [0, 2.5, 5.0, 7.5],    outputFormat: 'png',    quality: 2,  },}); stills.forEach((buf, i) => fs.writeFileSync(`grab-${i}.png`, buf));

extractFrames — mode B: interval

What it does: Runs ApexPainter.extractFrames — FFmpeg -vf fps= derived from interval in milliseconds (fps = 1000 / interval).

FieldEffect
intervalMs between samples (must be > 0). Smaller = more frames, larger disk use.
frameSelection.start, endFrame indices within the extracted sequence (trim the list).
outputFormat, qualityJPEG/PNG quality flags.
outputDirectoryTyped on VideoCreationOptions but not used by current extractFrames implementation — files land under .temp-frames/frames-<id>/.
SOURCEtypescript
typescript
Studio
const paths = await painter.createVideo({  source: './motion.mp4',  extractFrames: {    interval: 250, // ~4 fps sampling    outputFormat: 'jpg',    frameSelection: { start: 0, end: 48 },  },});console.log(paths.map((p) => p.source));

extractAllFrames

What it does: Dumps every frame in [startTime, endTime] to disk (large outputs).

FieldDefaultEffect
outputDirectory./extracted-framesWhere prefix-%06d.ext files go.
outputFormatpngjpg smaller but lossy.
quality2JPEG -q:v.
prefixframeFilename prefix.
startTime, endTime0 … durationTime window in seconds.

Returns { source, frameNumber, time }[] with time stepped by 1/fps (approximate).

SOURCEtypescript
typescript
Studio
const frames = await painter.createVideo({  source: './short.mp4',  extractAllFrames: {    outputDirectory: './all-frames',    outputFormat: 'png',    prefix: 'cell',    startTime: 0,    endTime: 1,  },});

generateThumbnail

What it does: Builds one PNG sheet: count thumbnails evenly spaced in time, arranged in grid.

FieldDefaultEffect
count9How many stills.
grid3×3cols × rows must fit count sensibly.
width, height320×180Per-cell size (total canvas = cell × grid).
outputFormat, qualityPassed through frame extraction.
SOURCEtypescript
typescript
Studio
const sheet = await painter.createVideo({  source: './tutorial.mp4',  generateThumbnail: {    count: 12,    grid: { cols: 4, rows: 3 },    width: 320,    height: 180,  },});fs.writeFileSync('sheet.png', sheet.buffer);

generatePreview

What it does: Writes count images to outputDirectory (like a storyboard dump, not one montage).

FieldDefault
count10
outputDirectory./video-preview
outputFormatpng
quality2
SOURCEtypescript
typescript
Studio
const previews = await painter.createVideo({  source: './draft.mp4',  generatePreview: {    count: 15,    outputDirectory: './storyboard',    outputFormat: 'jpg',  },});

detectScenes

What it does: Runs FFmpeg scene-detection filter and parses timestamps (shell pipeline — most reliable on Unix/Git Bash/WSL).

FieldDefaultEffect
threshold0.3Higher → fewer cuts detected.
outputPath—Optional JSON file [{ time, scene }].
SOURCEtypescript
typescript
Studio
const cuts = await painter.createVideo({  source: './interview.mp4',  detectScenes: {    threshold: 0.4,    outputPath: './cuts.json',  },});

Next steps