Skip to content

Video Nodes

Transcode, resize, trim, and extract metadata from videos.

PluginPackageOperationsRequirements
videoPlugin@uploadista/flow-videos-av-nodeTranscode, resize, trim, thumbnail, metadataNone (FFmpeg bundled)
npm install @uploadista/flow-videos-nodes @uploadista/flow-videos-av-node
import { createUploadistaServer } from "@uploadista/server";
import { videoPlugin } from "@uploadista/flow-videos-av-node";
const uploadista = await createUploadistaServer({
// ...
plugins: [
videoPlugin(),
],
});
import { createUploadistaServer } from "@uploadista/server";
import { videoPluginWithCheck } from "@uploadista/flow-videos-av-node";
const uploadista = await createUploadistaServer({
// ...
plugins: [
videoPluginWithCheck(), // Logs: "✓ node-av 4.x detected" or warning
],
});
  • No System Dependencies - FFmpeg binaries bundled with node-av
  • Cross-Platform - Works on Windows, macOS, and Linux
  • TypeScript Native - Full type safety
  • Memory Efficient - Automatic resource management

Input: MP4, WebM, MOV, AVI, MKV, FLV

Output: MP4 (H.264/AAC), WebM (VP9/Opus), MOV (H.264/AAC), AVI

Video Codecs: H.264, H.265/HEVC, VP9, AV1

Audio Codecs: AAC, Opus, MP3, Vorbis


Convert video to different formats and codecs.

Package: @uploadista/flow-videos-nodes

import { createTranscodeVideoNode } from "@uploadista/flow-videos-nodes";
// Convert to WebM with VP9 codec
const transcodeNode = yield* createTranscodeVideoNode("transcode-1", {
format: "webm",
codec: "vp9",
videoBitrate: "1000k",
});
// Convert to MP4 with H.264 for compatibility
const mp4Node = yield* createTranscodeVideoNode("transcode-2", {
format: "mp4",
codec: "h264",
videoBitrate: "2M",
audioBitrate: "128k",
audioCodec: "aac",
});
// With streaming mode for large files
const streamingNode = yield* createTranscodeVideoNode("transcode-3", {
format: "mp4",
codec: "h264",
}, {
mode: "streaming",
naming: { mode: "auto" },
});
ParameterTypeRequiredDescription
format"mp4" | "webm" | "mov" | "avi"YesOutput container format
codec"h264" | "h265" | "vp9" | "av1"NoVideo codec
videoBitratestringNoVideo bitrate (e.g., “1000k”, “2M”)
audioBitratestringNoAudio bitrate (e.g., “128k”, “192k”)
audioCodec"aac" | "mp3" | "opus" | "vorbis"NoAudio codec
OptionTypeDefaultDescription
mode"auto" | "buffered" | "streaming""auto"Processing mode
keepOutputbooleanfalseKeep output in flow results
namingFileNamingConfig-File naming configuration
streamingConfig.fileSizeThresholdnumber10000000Threshold for auto streaming (10MB)

Change video resolution.

Package: @uploadista/flow-videos-nodes

import { createVideoResizeNode } from "@uploadista/flow-videos-nodes";
// Resize to 720p
const resizeNode = yield* createVideoResizeNode("resize-1", {
width: 1280,
height: 720,
aspectRatio: "keep",
scaling: "bicubic",
});
// Resize to 1080p width, auto height
const widthOnlyNode = yield* createVideoResizeNode("resize-2", {
width: 1920,
aspectRatio: "keep",
});
// With streaming mode
const streamingNode = yield* createVideoResizeNode("resize-3", {
width: 1280,
height: 720,
}, {
mode: "streaming",
naming: { mode: "auto" },
});
ParameterTypeRequiredDescription
widthnumberNo*Target width in pixels
heightnumberNo*Target height in pixels
aspectRatio"keep" | "ignore"NoAspect ratio handling mode
scaling"bicubic" | "bilinear" | "lanczos"NoScaling algorithm quality

*At least one of width or height must be specified.


Extract a segment from a video.

Package: @uploadista/flow-videos-nodes

import { createTrimVideoNode } from "@uploadista/flow-videos-nodes";
// Extract segment using endTime
const trimNode = yield* createTrimVideoNode("trim-1", {
startTime: 10,
endTime: 30,
});
// Extract segment using duration
const durationNode = yield* createTrimVideoNode("trim-2", {
startTime: 10,
duration: 20,
});
// With streaming mode for large files
const streamingNode = yield* createTrimVideoNode("trim-3", {
startTime: 5,
endTime: 25,
}, {
mode: "streaming",
naming: { mode: "auto" },
});
ParameterTypeRequiredDescription
startTimenumberYesStart time in seconds
endTimenumberNoEnd time in seconds
durationnumberNoDuration in seconds (alternative to endTime)

Note: Cannot specify both endTime and duration.


Generate a preview image from the video.

Package: @uploadista/flow-videos-nodes

import { createVideoThumbnailNode } from "@uploadista/flow-videos-nodes";
// Extract frame at 15 seconds as JPEG
const thumbnailNode = yield* createVideoThumbnailNode("thumbnail-1", {
timestamp: 15,
format: "jpeg",
quality: 85,
});
// Extract frame as PNG
const pngThumbNode = yield* createVideoThumbnailNode("thumbnail-2", {
timestamp: 5,
format: "png",
});
// With auto naming
const namedThumb = yield* createVideoThumbnailNode("thumbnail-3", {
timestamp: 10,
format: "jpeg",
quality: 90,
}, {
naming: { mode: "auto" },
});
ParameterTypeRequiredDefaultDescription
timestampnumberYes-Time position in seconds
format"jpeg" | "png"No"jpeg"Output image format
qualitynumber (1-100)No-JPEG quality (only for jpeg format)

Extract comprehensive video metadata.

Package: @uploadista/flow-videos-nodes

import { createDescribeVideoNode } from "@uploadista/flow-videos-nodes";
// Extract video metadata
const describeNode = yield* createDescribeVideoNode("describe-1");
// With keepOutput option
const keepOutputNode = yield* createDescribeVideoNode("describe-2", {
keepOutput: true,
});
ParameterTypeRequiredDefaultDescription
keepOutputbooleanNofalseKeep output in flow results

Output Metadata:

{
"width": 1920,
"height": 1080,
"duration": 120.5,
"frameRate": 30,
"codec": "h264",
"bitrate": 5000000,
"audioCodec": "aac",
"audioChannels": 2
}

All video transform nodes support three processing modes:

ModeDescriptionWhen to Use
autoAutomatically selects streaming for files > 10MBDefault, recommended
bufferedLoads entire file into memorySmall files, predictable memory
streamingProcesses file as chunksLarge files, memory-constrained

Video processing is computationally intensive. Approximate times on modern CPU:

Operation1 min video5 min video
Transcode H.264 → WebM~30s~2.5m
Resize 1080p → 720p~15s~1.5m
Thumbnail extraction~2s~2s
Metadata extraction~1s~1s
Trim (with re-encode)~10s~50s

Times vary based on video complexity, codec settings, and hardware.


The plugin uses typed error codes:

Error CodeDescription
VIDEO_PROCESSING_FAILEDGeneric processing error
INVALID_VIDEO_FORMATUnsupported format
CODEC_NOT_SUPPORTEDCodec unavailable
VIDEO_METADATA_EXTRACTION_FAILEDCannot read metadata
import { Effect } from "effect";
import { UploadistaError } from "@uploadista/core/errors";
const program = Effect.gen(function* () {
const videoPlugin = yield* VideoPlugin;
const result = yield* videoPlugin.transcode(videoBytes, {
format: "webm",
codec: "vp9",
});
return result;
}).pipe(
Effect.catchTag("UploadistaError", (error) => {
if (error.code === "VIDEO_PROCESSING_FAILED") {
console.error("Video processing failed:", error.message);
}
return Effect.fail(error);
})
);